about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig2
-rw-r--r--.git-blame-ignore-revs2
-rw-r--r--Cargo.lock39
-rw-r--r--Cargo.toml1
-rw-r--r--compiler/rustc_abi/src/lib.rs11
-rw-r--r--compiler/rustc_ast/src/ast.rs2
-rw-r--r--compiler/rustc_ast/src/expand/autodiff_attrs.rs24
-rw-r--r--compiler/rustc_ast_lowering/Cargo.toml1
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs21
-rw-r--r--compiler/rustc_ast_lowering/src/format.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs59
-rw-r--r--compiler/rustc_ast_passes/Cargo.toml1
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs7
-rw-r--r--compiler/rustc_attr_parsing/src/session_diagnostics.rs36
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs37
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs32
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs8
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs15
-rw-r--r--compiler/rustc_borrowck/src/lib.rs10
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs25
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs26
-rw-r--r--compiler/rustc_borrowck/src/type_check/opaque_types.rs12
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs25
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs22
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs11
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs40
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs32
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs157
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock60
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.toml26
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/prepare.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/example/std_example.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch4
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch4
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh22
-rw-r--r--compiler/rustc_codegen_cranelift/src/cast.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/compiler_builtins.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/object.rs21
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/jit.rs26
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs14
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs24
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/src/main_shim.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/trap.rs14
-rw-r--r--compiler/rustc_codegen_gcc/src/abi.rs3
-rw-r--r--compiler/rustc_codegen_gcc/src/base.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs21
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs22
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs466
-rw-r--r--compiler/rustc_codegen_gcc/src/mono_item.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs45
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs25
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs41
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/builder/autodiff.rs72
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs55
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs23
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs21
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs471
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/type_.rs4
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker/tests.rs35
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs143
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs43
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/naked_asm.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/consts.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/type_.rs4
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs14
-rw-r--r--compiler/rustc_const_eval/src/errors.rs11
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs22
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs25
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/tests.rs65
-rw-r--r--compiler/rustc_data_structures/src/graph/implementation/tests.rs11
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/tests.rs83
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/tests.rs8
-rw-r--r--compiler/rustc_data_structures/src/vec_cache/tests.rs13
-rw-r--r--compiler/rustc_errors/src/json/tests.rs160
-rw-r--r--compiler/rustc_expand/src/build.rs13
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs47
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs36
-rw-r--r--compiler/rustc_graphviz/src/tests.rs16
-rw-r--r--compiler/rustc_hir/src/hir.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs110
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs27
-rw-r--r--compiler/rustc_hir_analysis/src/delegation.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs11
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs34
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs44
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs38
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs16
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs49
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs9
-rw-r--r--compiler/rustc_index/src/bit_set/tests.rs70
-rw-r--r--compiler/rustc_index/src/vec/tests.rs18
-rw-r--r--compiler/rustc_infer/src/infer/outlives/for_liveness.rs10
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs30
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs8
-rw-r--r--compiler/rustc_infer/src/infer/relate/higher_ranked.rs24
-rw-r--r--compiler/rustc_infer/src/traits/engine.rs15
-rw-r--r--compiler/rustc_infer/src/traits/project.rs8
-rw-r--r--compiler/rustc_interface/Cargo.toml1
-rw-r--r--compiler/rustc_interface/src/passes.rs4
-rw-r--r--compiler/rustc_interface/src/tests.rs15
-rw-r--r--compiler/rustc_lexer/src/tests.rs35
-rw-r--r--compiler/rustc_lexer/src/unescape/tests.rs15
-rw-r--r--compiler/rustc_lint/src/builtin.rs213
-rw-r--r--compiler/rustc_lint/src/context.rs26
-rw-r--r--compiler/rustc_lint/src/deref_into_dyn_supertrait.rs21
-rw-r--r--compiler/rustc_lint/src/drop_forget_useless.rs52
-rw-r--r--compiler/rustc_lint/src/early.rs8
-rw-r--r--compiler/rustc_lint/src/enum_intrinsics_non_enums.rs9
-rw-r--r--compiler/rustc_lint/src/for_loops_over_fallibles.rs13
-rw-r--r--compiler/rustc_lint/src/hidden_unicode_codepoints.rs12
-rw-r--r--compiler/rustc_lint/src/if_let_rescope.rs33
-rw-r--r--compiler/rustc_lint/src/impl_trait_overcaptures.rs10
-rw-r--r--compiler/rustc_lint/src/internal.rs50
-rw-r--r--compiler/rustc_lint/src/let_underscore.rs9
-rw-r--r--compiler/rustc_lint/src/lib.rs29
-rw-r--r--compiler/rustc_lint/src/map_unit_fn.rs42
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs53
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs12
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs26
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs20
-rw-r--r--compiler/rustc_lint/src/noop_method_call.rs18
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs11
-rw-r--r--compiler/rustc_lint/src/pass_by_value.rs9
-rw-r--r--compiler/rustc_lint/src/passes.rs2
-rw-r--r--compiler/rustc_lint/src/redundant_semicolon.rs9
-rw-r--r--compiler/rustc_lint/src/shadowed_into_iter.rs11
-rw-r--r--compiler/rustc_lint/src/static_mut_refs.rs10
-rw-r--r--compiler/rustc_lint/src/traits.rs10
-rw-r--r--compiler/rustc_lint/src/types.rs46
-rw-r--r--compiler/rustc_lint/src/types/literal.rs101
-rw-r--r--compiler/rustc_lint/src/unit_bindings.rs8
-rw-r--r--compiler/rustc_lint/src/unused.rs98
-rw-r--r--compiler/rustc_llvm/Cargo.toml2
-rw-r--r--compiler/rustc_llvm/build.rs4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp22
-rw-r--r--compiler/rustc_macros/src/serialize.rs34
-rw-r--r--compiler/rustc_macros/src/symbols/tests.rs8
-rw-r--r--compiler/rustc_metadata/src/creader.rs32
-rw-r--r--compiler/rustc_middle/Cargo.toml1
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs2
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs139
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs11
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs8
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs2
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs6
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs2
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs9
-rw-r--r--compiler/rustc_middle/src/query/mod.rs13
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs21
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs7
-rw-r--r--compiler/rustc_middle/src/ty/context.rs37
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs33
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs9
-rw-r--r--compiler/rustc_middle/src/ty/util.rs32
-rw-r--r--compiler/rustc_mir_build/src/builder/cfg.rs8
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_place.rs46
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs69
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/into.rs109
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/stmt.rs10
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/match_pair.rs11
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/mod.rs111
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/test.rs71
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/util.rs9
-rw-r--r--compiler/rustc_mir_build/src/builder/misc.rs15
-rw-r--r--compiler/rustc_mir_build/src/builder/scope.rs120
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs19
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs30
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs9
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/tests.rs42
-rw-r--r--compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs15
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs22
-rw-r--r--compiler/rustc_mir_transform/src/check_alignment.rs2
-rw-r--r--compiler/rustc_mir_transform/src/check_call_recursion.rs10
-rw-r--r--compiler/rustc_mir_transform/src/check_null.rs69
-rw-r--r--compiler/rustc_mir_transform/src/check_pointers.rs14
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs112
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs8
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs103
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs25
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs34
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs10
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mappings.rs61
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs112
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs167
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs3
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs21
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs8
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs13
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs9
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs20
-rw-r--r--compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs28
-rw-r--r--compiler/rustc_mir_transform/src/simplify_comparison_integral.rs11
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs9
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/abi_check.rs4
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/move_check.rs9
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs10
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs29
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs9
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs9
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs62
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs33
-rw-r--r--compiler/rustc_parse/src/errors.rs76
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs8
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs58
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs36
-rw-r--r--compiler/rustc_parse/src/parser/item.rs8
-rw-r--r--compiler/rustc_parse/src/parser/path.rs24
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs22
-rw-r--r--compiler/rustc_parse_format/src/lib.rs101
-rw-r--r--compiler/rustc_parse_format/src/tests.rs640
-rw-r--r--compiler/rustc_passes/src/abi_test.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs44
-rw-r--r--compiler/rustc_passes/src/errors.rs14
-rw-r--r--compiler/rustc_passes/src/input_stats.rs431
-rw-r--r--compiler/rustc_query_impl/Cargo.toml1
-rw-r--r--compiler/rustc_query_impl/src/lib.rs17
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs4
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs11
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs13
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs12
-rw-r--r--compiler/rustc_resolve/src/ident.rs57
-rw-r--r--compiler/rustc_resolve/src/imports.rs19
-rw-r--r--compiler/rustc_resolve/src/late.rs64
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs36
-rw-r--r--compiler/rustc_resolve/src/lib.rs29
-rw-r--r--compiler/rustc_resolve/src/macros.rs15
-rw-r--r--compiler/rustc_session/messages.ftl3
-rw-r--r--compiler/rustc_session/src/config/native_libs/tests.rs40
-rw-r--r--compiler/rustc_session/src/errors.rs1
-rw-r--r--compiler/rustc_session/src/search_paths.rs8
-rw-r--r--compiler/rustc_session/src/session.rs3
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs10
-rw-r--r--compiler/rustc_target/src/callconv/aarch64.rs2
-rw-r--r--compiler/rustc_target/src/callconv/amdgpu.rs2
-rw-r--r--compiler/rustc_target/src/callconv/arm.rs2
-rw-r--r--compiler/rustc_target/src/callconv/avr.rs2
-rw-r--r--compiler/rustc_target/src/callconv/bpf.rs2
-rw-r--r--compiler/rustc_target/src/callconv/csky.rs2
-rw-r--r--compiler/rustc_target/src/callconv/hexagon.rs2
-rw-r--r--compiler/rustc_target/src/callconv/m68k.rs2
-rw-r--r--compiler/rustc_target/src/callconv/mips.rs2
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs5
-rw-r--r--compiler/rustc_target/src/callconv/msp430.rs2
-rw-r--r--compiler/rustc_target/src/callconv/nvptx64.rs2
-rw-r--r--compiler/rustc_target/src/callconv/powerpc.rs2
-rw-r--r--compiler/rustc_target/src/callconv/powerpc64.rs2
-rw-r--r--compiler/rustc_target/src/callconv/riscv.rs2
-rw-r--r--compiler/rustc_target/src/callconv/s390x.rs2
-rw-r--r--compiler/rustc_target/src/callconv/sparc.rs2
-rw-r--r--compiler/rustc_target/src/callconv/sparc64.rs2
-rw-r--r--compiler/rustc_target/src/callconv/wasm.rs2
-rw-r--r--compiler/rustc_target/src/callconv/x86.rs2
-rw-r--r--compiler/rustc_target/src/callconv/x86_64.rs2
-rw-r--r--compiler/rustc_target/src/callconv/x86_win64.rs2
-rw-r--r--compiler/rustc_target/src/callconv/xtensa.rs2
-rw-r--r--compiler/rustc_target/src/json.rs2
-rw-r--r--compiler/rustc_target/src/lib.rs6
-rw-r--r--compiler/rustc_target/src/spec/base/apple/tests.rs13
-rw-r--r--compiler/rustc_target/src/spec/base/avr_gnu.rs7
-rw-r--r--compiler/rustc_target/src/spec/base/fuchsia.rs29
-rw-r--r--compiler/rustc_target/src/spec/base/illumos.rs41
-rw-r--r--compiler/rustc_target/src/spec/base/nto_qnx.rs8
-rw-r--r--compiler/rustc_target/src/spec/base/uefi_msvc.rs35
-rw-r--r--compiler/rustc_target/src/spec/base/windows_gnu.rs33
-rw-r--r--compiler/rustc_target/src/spec/base/windows_gnullvm.rs19
-rw-r--r--compiler/rustc_target/src/spec/json.rs8
-rw-r--r--compiler/rustc_target/src/spec/mod.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs7
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs7
-rw-r--r--compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs51
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs10
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs11
-rw-r--r--compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs21
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs21
-rw-r--r--compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs8
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs10
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs11
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs10
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs28
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs24
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32v1_none.rs28
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs30
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs65
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs3
-rw-r--r--compiler/rustc_target/src/target_features.rs16
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs9
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs27
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs17
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs31
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs53
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs34
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs96
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs85
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs8
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs8
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs55
-rw-r--r--compiler/rustc_type_ir/src/interner.rs6
-rw-r--r--compiler/rustc_type_ir/src/outlives.rs18
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs63
-rw-r--r--compiler/rustc_type_ir/src/relate.rs28
-rw-r--r--compiler/rustc_type_ir/src/ty_kind/closure.rs21
-rw-r--r--compiler/rustc_type_ir_macros/src/lib.rs61
-rw-r--r--compiler/stable_mir/src/mir/body.rs2
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs2
-rw-r--r--config.example.toml2
-rw-r--r--library/Cargo.lock4
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/alloc/src/alloc.rs6
-rw-r--r--library/alloc/src/collections/btree/merge_iter.rs2
-rw-r--r--library/alloc/src/collections/btree/set/tests.rs16
-rw-r--r--library/alloc/src/collections/linked_list/tests.rs28
-rw-r--r--library/alloc/src/collections/vec_deque/tests.rs7
-rw-r--r--library/alloc/src/ffi/c_str.rs7
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/rc.rs19
-rw-r--r--library/alloc/src/sync.rs13
-rw-r--r--library/alloc/src/vec/mod.rs4
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/str.rs165
-rw-r--r--library/alloc/tests/string.rs35
-rw-r--r--library/core/src/cell.rs17
-rw-r--r--library/core/src/ffi/c_str.rs2
-rw-r--r--library/core/src/ffi/mod.rs2
-rw-r--r--library/core/src/intrinsics/mod.rs2
-rw-r--r--library/core/src/iter/sources/once_with.rs14
-rw-r--r--library/core/src/iter/traits/iterator.rs7
-rw-r--r--library/core/src/ops/async_function.rs3
-rw-r--r--library/core/src/panicking.rs6
-rw-r--r--library/core/src/ptr/metadata.rs2
-rw-r--r--library/coretests/tests/iter/adapters/map_windows.rs9
-rw-r--r--library/coretests/tests/mem.rs2
-rw-r--r--library/coretests/tests/num/flt2dec/mod.rs2
-rw-r--r--library/coretests/tests/ptr.rs6
-rw-r--r--library/panic_abort/src/lib.rs4
-rw-r--r--library/panic_abort/src/zkvm.rs2
-rw-r--r--library/panic_unwind/src/emcc.rs17
-rw-r--r--library/panic_unwind/src/hermit.rs4
-rw-r--r--library/panic_unwind/src/lib.rs2
-rw-r--r--library/panic_unwind/src/miri.rs2
-rw-r--r--library/panic_unwind/src/seh.rs6
-rw-r--r--library/portable-simd/.github/workflows/ci.yml125
-rw-r--r--library/portable-simd/.github/workflows/doc.yml2
-rw-r--r--library/portable-simd/.gitignore1
-rw-r--r--library/portable-simd/Cargo.toml6
-rw-r--r--library/portable-simd/Cross.toml2
-rw-r--r--library/portable-simd/crates/core_simd/Cargo.toml3
-rw-r--r--library/portable-simd/crates/core_simd/src/lane_count.rs8
-rw-r--r--library/portable-simd/crates/core_simd/src/lib.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/masks.rs42
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/bitmask.rs17
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/full_masks.rs58
-rw-r--r--library/portable-simd/crates/core_simd/src/ops.rs25
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/num/float.rs30
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/num/int.rs43
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/num/uint.rs42
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs21
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs21
-rw-r--r--library/portable-simd/crates/core_simd/src/swizzle.rs257
-rw-r--r--library/portable-simd/crates/core_simd/src/swizzle_dyn.rs59
-rw-r--r--library/portable-simd/crates/core_simd/src/vector.rs43
-rw-r--r--library/portable-simd/crates/core_simd/src/vendor.rs3
-rw-r--r--library/portable-simd/crates/core_simd/src/vendor/loongarch64.rs31
-rw-r--r--library/portable-simd/crates/core_simd/tests/layout.rs35
-rw-r--r--library/portable-simd/crates/core_simd/tests/masks.rs43
-rw-r--r--library/portable-simd/crates/core_simd/tests/ops_macros.rs38
-rw-r--r--library/portable-simd/crates/core_simd/tests/swizzle.rs18
-rw-r--r--library/portable-simd/crates/test_helpers/Cargo.toml3
-rw-r--r--library/portable-simd/crates/test_helpers/src/lib.rs216
-rw-r--r--library/portable-simd/rust-toolchain.toml3
-rwxr-xr-xlibrary/portable-simd/subtree-sync.sh52
-rw-r--r--library/rtstartup/rsbegin.rs8
-rw-r--r--library/rtstartup/rsend.rs2
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/alloc.rs2
-rw-r--r--library/std/src/collections/hash/map.rs12
-rw-r--r--library/std/src/collections/hash/set.rs4
-rw-r--r--library/std/src/fs.rs4
-rw-r--r--library/std/src/fs/tests.rs4
-rw-r--r--library/std/src/io/error.rs2
-rw-r--r--library/std/src/io/mod.rs2
-rw-r--r--library/std/src/io/stdio/tests.rs7
-rw-r--r--library/std/src/lib.rs25
-rw-r--r--library/std/src/net/test.rs33
-rw-r--r--library/std/src/os/unix/fs/tests.rs4
-rw-r--r--library/std/src/os/unix/net/tests.rs2
-rw-r--r--library/std/src/os/windows/process.rs8
-rw-r--r--library/std/src/os/xous/ffi/definitions.rs66
-rw-r--r--library/std/src/panicking.rs4
-rw-r--r--library/std/src/path.rs2
-rw-r--r--library/std/src/process/tests.rs152
-rw-r--r--library/std/src/sync/mpmc/mod.rs6
-rw-r--r--library/std/src/sys/alloc/xous.rs2
-rw-r--r--library/std/src/sys/cmath.rs2
-rw-r--r--library/std/src/sys/io/io_slice/iovec.rs (renamed from library/std/src/sys/pal/hermit/io.rs)14
-rw-r--r--library/std/src/sys/io/io_slice/unsupported.rs (renamed from library/std/src/sys/pal/unsupported/io.rs)4
-rw-r--r--library/std/src/sys/io/io_slice/wasi.rs (renamed from library/std/src/sys/pal/wasi/io.rs)8
-rw-r--r--library/std/src/sys/io/io_slice/windows.rs (renamed from library/std/src/sys/pal/solid/io.rs)38
-rw-r--r--library/std/src/sys/io/is_terminal/hermit.rs6
-rw-r--r--library/std/src/sys/io/is_terminal/isatty.rs6
-rw-r--r--library/std/src/sys/io/is_terminal/unsupported.rs3
-rw-r--r--library/std/src/sys/io/is_terminal/windows.rs (renamed from library/std/src/sys/pal/windows/io.rs)84
-rw-r--r--library/std/src/sys/io/mod.rs44
-rw-r--r--library/std/src/sys/mod.rs1
-rw-r--r--library/std/src/sys/net/connection/uefi/mod.rs369
-rw-r--r--library/std/src/sys/net/connection/xous/dns.rs2
-rw-r--r--library/std/src/sys/net/connection/xous/tcplistener.rs32
-rw-r--r--library/std/src/sys/net/connection/xous/tcpstream.rs42
-rw-r--r--library/std/src/sys/net/connection/xous/udp.rs51
-rw-r--r--library/std/src/sys/net/mod.rs5
-rw-r--r--library/std/src/sys/pal/hermit/fs.rs8
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs3
-rw-r--r--library/std/src/sys/pal/itron/abi.rs2
-rw-r--r--library/std/src/sys/pal/itron/time/tests.rs30
-rw-r--r--library/std/src/sys/pal/sgx/abi/mem.rs2
-rw-r--r--library/std/src/sys/pal/sgx/abi/mod.rs2
-rw-r--r--library/std/src/sys/pal/sgx/abi/panic.rs2
-rw-r--r--library/std/src/sys/pal/sgx/abi/reloc.rs2
-rw-r--r--library/std/src/sys/pal/sgx/abi/thread.rs2
-rw-r--r--library/std/src/sys/pal/sgx/abi/tls/mod.rs2
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/raw.rs2
-rw-r--r--library/std/src/sys/pal/sgx/mod.rs2
-rw-r--r--library/std/src/sys/pal/sgx/stdio.rs2
-rw-r--r--library/std/src/sys/pal/solid/abi/fs.rs2
-rw-r--r--library/std/src/sys/pal/solid/abi/mod.rs10
-rw-r--r--library/std/src/sys/pal/solid/abi/sockets.rs2
-rw-r--r--library/std/src/sys/pal/solid/fs.rs2
-rw-r--r--library/std/src/sys/pal/solid/mod.rs1
-rw-r--r--library/std/src/sys/pal/solid/os.rs2
-rw-r--r--library/std/src/sys/pal/teeos/mod.rs4
-rw-r--r--library/std/src/sys/pal/teeos/os.rs4
-rw-r--r--library/std/src/sys/pal/teeos/thread.rs2
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs2
-rw-r--r--library/std/src/sys/pal/uefi/mod.rs4
-rw-r--r--library/std/src/sys/pal/uefi/stdio.rs2
-rw-r--r--library/std/src/sys/pal/unix/args.rs4
-rw-r--r--library/std/src/sys/pal/unix/fs.rs25
-rw-r--r--library/std/src/sys/pal/unix/futex.rs4
-rw-r--r--library/std/src/sys/pal/unix/io.rs87
-rw-r--r--library/std/src/sys/pal/unix/kernel_copy/tests.rs2
-rw-r--r--library/std/src/sys/pal/unix/mod.rs21
-rw-r--r--library/std/src/sys/pal/unix/os.rs22
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs4
-rw-r--r--library/std/src/sys/pal/unix/process/zircon.rs4
-rw-r--r--library/std/src/sys/pal/unix/stdio.rs2
-rw-r--r--library/std/src/sys/pal/unix/thread.rs6
-rw-r--r--library/std/src/sys/pal/unix/thread_parking.rs2
-rw-r--r--library/std/src/sys/pal/unix/weak.rs2
-rw-r--r--library/std/src/sys/pal/unsupported/mod.rs1
-rw-r--r--library/std/src/sys/pal/wasi/fs.rs7
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs1
-rw-r--r--library/std/src/sys/pal/wasi/os.rs4
-rw-r--r--library/std/src/sys/pal/wasi/stdio.rs2
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs2
-rw-r--r--library/std/src/sys/pal/wasip2/mod.rs2
-rw-r--r--library/std/src/sys/pal/wasm/mod.rs2
-rw-r--r--library/std/src/sys/pal/windows/args/tests.rs8
-rw-r--r--library/std/src/sys/pal/windows/c.rs4
-rw-r--r--library/std/src/sys/pal/windows/compat.rs2
-rw-r--r--library/std/src/sys/pal/windows/fs.rs46
-rw-r--r--library/std/src/sys/pal/windows/mod.rs1
-rw-r--r--library/std/src/sys/pal/windows/process.rs4
-rw-r--r--library/std/src/sys/pal/windows/process/tests.rs4
-rw-r--r--library/std/src/sys/pal/xous/mod.rs2
-rw-r--r--library/std/src/sys/pal/xous/os.rs2
-rw-r--r--library/std/src/sys/pal/zkvm/abi.rs2
-rw-r--r--library/std/src/sys/pal/zkvm/mod.rs2
-rw-r--r--library/std/src/sys/pal/zkvm/stdio.rs2
-rw-r--r--library/std/src/sys/personality/gcc.rs2
-rw-r--r--library/std/src/sys/random/arc4random.rs2
-rw-r--r--library/std/src/sys/random/espidf.rs2
-rw-r--r--library/std/src/sys/random/fuchsia.rs2
-rw-r--r--library/std/src/sys/random/teeos.rs2
-rw-r--r--library/std/src/sys/sync/thread_parking/darwin.rs2
-rw-r--r--library/std/src/sys/thread_local/destructors/linux_like.rs2
-rw-r--r--library/std/src/sys/thread_local/guard/apple.rs2
-rw-r--r--library/std/src/sys/thread_local/guard/windows.rs2
-rw-r--r--library/std/src/sys/thread_local/key/unix.rs2
-rw-r--r--library/std/src/sys/thread_local/key/xous.rs2
-rw-r--r--library/std/src/sys_common/io.rs49
-rw-r--r--library/std/src/sys_common/mod.rs1
-rw-r--r--library/std/src/sys_common/wtf8/tests.rs111
-rw-r--r--library/std/src/test_helpers.rs65
-rw-r--r--library/std/tests/common/mod.rs2
-rw-r--r--library/std/tests/switch-stdout.rs4
-rw-r--r--library/std/tests/win_delete_self.rs9
-rw-r--r--library/test/src/console.rs5
-rw-r--r--library/test/src/formatters/junit.rs6
-rw-r--r--library/test/src/lib.rs9
-rw-r--r--library/test/src/term/terminfo/mod.rs2
-rw-r--r--library/test/src/term/terminfo/parser/compiled.rs2
-rw-r--r--library/test/src/term/win.rs2
-rw-r--r--library/unwind/src/lib.rs46
-rw-r--r--library/unwind/src/libunwind.rs16
-rw-r--r--library/windows_targets/src/lib.rs2
-rw-r--r--src/bootstrap/download-ci-llvm-stamp2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs63
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs54
-rw-r--r--src/bootstrap/src/core/build_steps/perf.rs220
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs29
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/toolstate.rs14
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs26
-rw-r--r--src/bootstrap/src/core/builder/mod.rs49
-rw-r--r--src/bootstrap/src/core/builder/tests.rs640
-rw-r--r--src/bootstrap/src/core/config/config.rs13
-rw-r--r--src/bootstrap/src/core/config/flags.rs8
-rw-r--r--src/bootstrap/src/lib.rs32
-rw-r--r--src/bootstrap/src/utils/cc_detect.rs6
-rw-r--r--src/bootstrap/src/utils/exec.rs5
-rw-r--r--src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile4
-rw-r--r--src/ci/docker/scripts/crosstool-ng-git.sh17
-rw-r--r--src/ci/docker/scripts/crosstool-ng.sh2
-rw-r--r--src/ci/github-actions/jobs.yml16
-rwxr-xr-xsrc/ci/scripts/free-disk-space.sh3
-rw-r--r--src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md4
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md6
-rw-r--r--src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md111
-rw-r--r--src/etc/completions/x.fish250
-rw-r--r--src/etc/completions/x.ps1219
-rw-r--r--src/etc/completions/x.py.fish250
-rw-r--r--src/etc/completions/x.py.ps1219
-rw-r--r--src/etc/completions/x.py.sh1010
-rw-r--r--src/etc/completions/x.py.zsh273
-rw-r--r--src/etc/completions/x.sh1010
-rw-r--r--src/etc/completions/x.zsh273
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/clean/cfg/tests.rs29
-rw-r--r--src/librustdoc/clean/mod.rs70
-rw-r--r--src/librustdoc/clean/types.rs11
-rw-r--r--src/librustdoc/html/highlight.rs42
-rw-r--r--src/librustdoc/html/markdown/tests.rs16
-rw-r--r--src/librustdoc/html/render/search_index.rs9
-rw-r--r--src/librustdoc/json/mod.rs28
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs9
-rw-r--r--src/stage0924
-rw-r--r--src/tools/build-manifest/src/main.rs14
-rw-r--r--src/tools/bump-stage0/src/main.rs2
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs345
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs81
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_line_after.rs492
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_bools.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_to_string.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_futures.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/types/type_complexity.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs2
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs16
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr14
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed9
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed9
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs10
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr51
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr30
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.fixed1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.rs1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.stderr18
-rw-r--r--src/tools/compiletest/src/common.rs4
-rw-r--r--src/tools/compiletest/src/header/cfg.rs2
-rw-r--r--src/tools/compiletest/src/header/tests.rs17
-rw-r--r--src/tools/compiletest/src/lib.rs10
-rw-r--r--src/tools/compiletest/src/runtest/run_make.rs32
-rw-r--r--src/tools/coverage-dump/src/covfun.rs11
m---------src/tools/enzyme0
-rw-r--r--src/tools/generate-copyright/src/cargo_metadata.rs15
-rw-r--r--src/tools/generate-copyright/src/main.rs10
-rw-r--r--src/tools/jsondoclint/src/validator/tests.rs327
-rw-r--r--src/tools/lint-docs/src/lib.rs42
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/tests/pass/intrinsics/portable-simd.rs21
-rw-r--r--src/tools/rust-analyzer/.git-blame-ignore-revs1
-rw-r--r--src/tools/rust-analyzer/.github/workflows/autopublish.yaml1
-rw-r--r--src/tools/rust-analyzer/.github/workflows/publish-libs.yaml1
-rw-r--r--src/tools/rust-analyzer/.github/workflows/release.yaml11
-rw-r--r--src/tools/rust-analyzer/.gitignore7
-rw-r--r--src/tools/rust-analyzer/Cargo.lock33
-rw-r--r--src/tools/rust-analyzer/Cargo.toml10
-rw-r--r--src/tools/rust-analyzer/PRIVACY.md2
-rw-r--r--src/tools/rust-analyzer/README.md9
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/input.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/db.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs (renamed from src/tools/rust-analyzer/crates/hir-def/src/body.rs)349
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs175
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs (renamed from src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs)408
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs (renamed from src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs)2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs (renamed from src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs)44
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs (renamed from src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs)54
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs (renamed from src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs)1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs (renamed from src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs)0
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/generics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/import_map.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs37
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/name.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs134
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/generics.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs23
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs129
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs13
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs79
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs47
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs78
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/variance.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/diagnostics.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/from_id.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs99
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/term_search.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs102
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs41
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs50
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/defs.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs123
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs35
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs88
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/annotations.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/extend_selection.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/file_structure.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/highlight_related.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs102
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs33
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/interpret.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/join_lines.rs14
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/matching_brace.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/moniker.rs22
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/move_item.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/parent_module.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/references.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/rename.rs32
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/runnables.rs17
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/signature_help.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs38
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/status.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs190
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs45
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/typing.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs24
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_hir.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_mir.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs107
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs18
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs5
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs12
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast59
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast70
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rast28
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rast47
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_initializer_with_defaults.rast39
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_initializer_with_defaults.rs3
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs10
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs39
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/project_json.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/tests.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs83
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs25
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs5
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs18
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs21
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs82
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs5
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs28
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/cli.rs156
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/testdir.rs9
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs21
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs6
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/tokens.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs117
-rw-r--r--src/tools/rust-analyzer/crates/test-fixture/src/lib.rs10
-rw-r--r--src/tools/rust-analyzer/docs/book/README.md29
-rw-r--r--src/tools/rust-analyzer/docs/book/book.toml41
-rw-r--r--src/tools/rust-analyzer/docs/book/src/README.md21
-rw-r--r--src/tools/rust-analyzer/docs/book/src/SUMMARY.md13
-rw-r--r--src/tools/rust-analyzer/docs/book/src/assists.md8
-rw-r--r--src/tools/rust-analyzer/docs/book/src/configuration.md51
-rw-r--r--src/tools/rust-analyzer/docs/book/src/configuration_generated.md1206
-rw-r--r--src/tools/rust-analyzer/docs/book/src/diagnostics.md16
-rw-r--r--src/tools/rust-analyzer/docs/book/src/editor_features.md204
-rw-r--r--src/tools/rust-analyzer/docs/book/src/features.md3
-rw-r--r--src/tools/rust-analyzer/docs/book/src/installation.md644
-rw-r--r--src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md246
-rw-r--r--src/tools/rust-analyzer/docs/book/src/privacy.md15
-rw-r--r--src/tools/rust-analyzer/docs/book/src/security.md19
-rw-r--r--src/tools/rust-analyzer/docs/book/src/troubleshooting.md50
-rw-r--r--src/tools/rust-analyzer/docs/dev/style.md4
-rw-r--r--src/tools/rust-analyzer/docs/user/.gitignore1
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc1197
-rw-r--r--src/tools/rust-analyzer/docs/user/manual.adoc1121
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json14
-rw-r--r--src/tools/rust-analyzer/editors/code/src/commands.ts14
-rw-r--r--src/tools/rust-analyzer/editors/code/src/ctx.ts4
-rw-r--r--src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts140
-rw-r--r--src/tools/rust-analyzer/lib/line-index/src/lib.rs12
-rw-r--r--src/tools/rust-analyzer/rust-version2
-rw-r--r--src/tools/rust-analyzer/xtask/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen.rs13
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/assists_doc_tests.rs10
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/diagnostics_docs.rs6
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/feature_docs.rs16
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/grammar.rs3
-rw-r--r--src/tools/rust-analyzer/xtask/src/publish/notes.rs6
-rw-r--r--src/tools/rust-analyzer/xtask/src/release.rs21
-rw-r--r--src/tools/rust-analyzer/xtask/test_data/expected.md8
-rw-r--r--src/tools/rust-installer/src/compression.rs19
-rw-r--r--src/tools/rustc-perf-wrapper/Cargo.toml7
-rw-r--r--src/tools/rustc-perf-wrapper/README.md3
-rw-r--r--src/tools/rustc-perf-wrapper/src/config.rs45
-rw-r--r--src/tools/rustc-perf-wrapper/src/main.rs178
-rw-r--r--src/tools/tidy/src/deps.rs4
-rw-r--r--src/tools/tidy/src/ext_tool_checks.rs33
-rw-r--r--src/tools/tidy/src/known_bug.rs11
-rw-r--r--src/tools/unicode-table-generator/src/raw_emitter.rs48
-rw-r--r--tests/assembly/targets/targets-amdgpu.rs21
-rw-r--r--tests/codegen/autodiff.rs33
-rw-r--r--tests/codegen/debug-fndef-size.rs8
-rw-r--r--tests/codegen/terminating-catchpad.rs37
-rw-r--r--tests/coverage/assert_not.cov-map8
-rw-r--r--tests/coverage/bad_counter_ids.cov-map24
-rw-r--r--tests/coverage/fn_sig_into_try.cov-map24
-rw-r--r--tests/coverage/inline-dead.cov-map9
-rw-r--r--tests/coverage/issue-84561.cov-map29
-rw-r--r--tests/coverage/loops_branches.cov-map95
-rw-r--r--tests/coverage/no_spans_if_not.cov-map8
-rw-r--r--tests/coverage/tight_inf_loop.cov-map8
-rw-r--r--tests/crashes/135470.rs40
-rw-r--r--tests/crashes/135528.rs18
-rw-r--r--tests/crashes/135570.rs12
-rw-r--r--tests/crashes/135617.rs13
-rw-r--r--tests/crashes/135646.rs5
-rw-r--r--tests/crashes/135668.rs38
-rw-r--r--tests/crashes/135718.rs50
-rw-r--r--tests/crashes/135720.rs4
-rw-r--r--tests/crashes/135845.rs6
-rw-r--r--tests/crashes/135863.rs10
-rw-r--r--tests/crashes/136063.rs6
-rw-r--r--tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff26
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff4
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff18
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.rs8
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff18
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff18
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.rs4
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/run-make/apple-deployment-target/rmake.rs23
-rw-r--r--tests/run-make/libs-through-symlinks/rmake.rs1
-rw-r--r--tests/run-make/wasm-export-all-symbols/rmake.rs17
-rw-r--r--tests/ui/amdgpu-require-explicit-cpu.nocpu.stderr4
-rw-r--r--tests/ui/amdgpu-require-explicit-cpu.rs17
-rw-r--r--tests/ui/argument-suggestions/extern-fn-arg-names.stderr2
-rw-r--r--tests/ui/c-variadic/variadic-ffi-1.stderr4
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr2
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.feature.stderr2
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.full.stderr2
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr8
-rw-r--r--tests/ui/debuginfo/dwarf-versions.one.stderr6
-rw-r--r--tests/ui/debuginfo/dwarf-versions.rs38
-rw-r--r--tests/ui/debuginfo/dwarf-versions.six.stderr6
-rw-r--r--tests/ui/debuginfo/dwarf-versions.zero.stderr6
-rw-r--r--tests/ui/error-codes/E0060.stderr2
-rw-r--r--tests/ui/fn/param-mismatch-foreign.rs11
-rw-r--r--tests/ui/fn/param-mismatch-foreign.stderr19
-rw-r--r--tests/ui/impl-trait/precise-capturing/rpitit-outlives-2.rs19
-rw-r--r--tests/ui/impl-trait/precise-capturing/rpitit-outlives.rs18
-rw-r--r--tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs3
-rw-r--r--tests/ui/lint/lint-overflowing-int-136675.rs4
-rw-r--r--tests/ui/lint/lint-overflowing-int-136675.stderr21
-rw-r--r--tests/ui/mir/null/borrowed_mut_null.rs2
-rw-r--r--tests/ui/mir/null/borrowed_null.rs2
-rw-r--r--tests/ui/mir/null/borrowed_null_zst.rs8
-rw-r--r--tests/ui/mir/null/null_lhs.rs2
-rw-r--r--tests/ui/mir/null/null_rhs.rs2
-rw-r--r--tests/ui/mir/null/place_without_read.rs1
-rw-r--r--tests/ui/mir/null/place_without_read_zst.rs11
-rw-r--r--tests/ui/mir/null/two_pointers.rs2
-rw-r--r--tests/ui/mismatched_types/issue-26480.stderr2
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr6
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs2
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr4
-rw-r--r--tests/ui/process/win-creation-flags.rs51
-rw-r--r--tests/ui/process/win-proc-thread-attributes.rs118
-rw-r--r--tests/ui/self/arbitrary_self_types_dispatch_to_vtable.rs33
-rw-r--r--tests/ui/suggestions/suggest-null-ptr.stderr8
-rw-r--r--tests/ui/wait-forked-but-failed-child.rs11
-rw-r--r--triagebot.toml2
992 files changed, 20309 insertions, 12307 deletions
diff --git a/.editorconfig b/.editorconfig
index eadd72e4993..ef8ed24c52a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -9,6 +9,8 @@ end_of_line = lf
 charset = utf-8
 trim_trailing_whitespace = true
 insert_final_newline = true
+
+[!src/llvm-project]
 indent_style = space
 indent_size = 4
 
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 8612a40923a..d2a017bd2a0 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -29,3 +29,5 @@ ec2cc761bc7067712ecc7734502f703fe3b024c8
 99cb0c6bc399fb94a0ddde7e9b38e9c00d523bad
 # reformat with rustfmt edition 2024
 c682aa162b0d41e21cc6748f4fecfe01efb69d1f
+# reformat with updated edition 2024
+1fcae03369abb4c2cc180cd5a49e1f4440a81300
diff --git a/Cargo.lock b/Cargo.lock
index 89eb514917d..2ee2c52b32a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -420,9 +420,9 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.2.7"
+version = "1.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7"
+checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda"
 dependencies = [
  "shlex",
 ]
@@ -1210,16 +1210,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "field-offset"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
-dependencies = [
- "memoffset",
- "rustc_version",
-]
-
-[[package]]
 name = "filetime"
 version = "0.2.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2296,15 +2286,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "memoffset"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
 name = "mime"
 version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2322,9 +2303,9 @@ dependencies = [
 
 [[package]]
 name = "minifier"
-version = "0.3.2"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd559bbf5d350ac7f2c1cf92ed71a869b847a92bce0c1318b47932a5b5f65cdd"
+checksum = "1cf47565b1430f5fe6c81d3afcb4b835271348d7eb35294a4d592e38dd09ea22"
 
 [[package]]
 name = "minimal-lexical"
@@ -3288,13 +3269,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "rustc-perf-wrapper"
-version = "0.1.0"
-dependencies = [
- "clap",
-]
-
-[[package]]
 name = "rustc-rayon"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3400,6 +3374,7 @@ dependencies = [
 name = "rustc_ast_lowering"
 version = "0.0.0"
 dependencies = [
+ "rustc_abi",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
@@ -3422,6 +3397,7 @@ name = "rustc_ast_passes"
 version = "0.0.0"
 dependencies = [
  "itertools",
+ "rustc_abi",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_attr_parsing",
@@ -4015,6 +3991,7 @@ version = "0.0.0"
 dependencies = [
  "rustc-rayon",
  "rustc-rayon-core",
+ "rustc_abi",
  "rustc_ast",
  "rustc_ast_lowering",
  "rustc_ast_passes",
@@ -4177,7 +4154,6 @@ version = "0.0.0"
 dependencies = [
  "bitflags",
  "either",
- "field-offset",
  "gsgdt",
  "polonius-engine",
  "rustc-rayon-core",
@@ -4425,7 +4401,6 @@ dependencies = [
 name = "rustc_query_impl"
 version = "0.0.0"
 dependencies = [
- "field-offset",
  "measureme",
  "rustc_data_structures",
  "rustc_errors",
diff --git a/Cargo.toml b/Cargo.toml
index 68d142ebe92..97e782d0df0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -45,7 +45,6 @@ members = [
   "src/tools/rustdoc-gui-test",
   "src/tools/opt-dist",
   "src/tools/coverage-dump",
-  "src/tools/rustc-perf-wrapper",
   "src/tools/wasm-component-ld",
   "src/tools/features-status-dump",
 ]
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 8ad33749f34..fc34b288933 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1184,10 +1184,13 @@ impl Scalar {
     #[inline]
     pub fn is_bool(&self) -> bool {
         use Integer::*;
-        matches!(self, Scalar::Initialized {
-            value: Primitive::Int(I8, false),
-            valid_range: WrappingRange { start: 0, end: 1 }
-        })
+        matches!(
+            self,
+            Scalar::Initialized {
+                value: Primitive::Int(I8, false),
+                valid_range: WrappingRange { start: 0, end: 1 }
+            }
+        )
     }
 
     /// Get the primitive representation of this type, ignoring the valid range and whether the
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index e75334b19c8..deee3a597ae 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -3225,7 +3225,7 @@ pub enum Extern {
     ///
     /// E.g. `extern fn foo() {}`.
     ///
-    /// This is just `extern "C"` (see `rustc_target::spec::abi::Abi::FALLBACK`).
+    /// This is just `extern "C"` (see `rustc_abi::ExternAbi::FALLBACK`).
     Implicit(Span),
     /// An explicit extern keyword was used with an explicit ABI.
     ///
diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
index ecc522ec39d..70222f4acab 100644
--- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs
+++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
@@ -30,14 +30,6 @@ pub enum DiffMode {
     Forward,
     /// The target function, to be created using reverse mode AD.
     Reverse,
-    /// The target function, to be created using forward mode AD.
-    /// This target function will also be used as a source for higher order derivatives,
-    /// so compute it before all Forward/Reverse targets and optimize it through llvm.
-    ForwardFirst,
-    /// The target function, to be created using reverse mode AD.
-    /// This target function will also be used as a source for higher order derivatives,
-    /// so compute it before all Forward/Reverse targets and optimize it through llvm.
-    ReverseFirst,
 }
 
 /// Dual and Duplicated (and their Only variants) are getting lowered to the same Enzyme Activity.
@@ -92,10 +84,10 @@ pub struct AutoDiffAttrs {
 
 impl DiffMode {
     pub fn is_rev(&self) -> bool {
-        matches!(self, DiffMode::Reverse | DiffMode::ReverseFirst)
+        matches!(self, DiffMode::Reverse)
     }
     pub fn is_fwd(&self) -> bool {
-        matches!(self, DiffMode::Forward | DiffMode::ForwardFirst)
+        matches!(self, DiffMode::Forward)
     }
 }
 
@@ -106,8 +98,6 @@ impl Display for DiffMode {
             DiffMode::Source => write!(f, "Source"),
             DiffMode::Forward => write!(f, "Forward"),
             DiffMode::Reverse => write!(f, "Reverse"),
-            DiffMode::ForwardFirst => write!(f, "ForwardFirst"),
-            DiffMode::ReverseFirst => write!(f, "ReverseFirst"),
         }
     }
 }
@@ -125,12 +115,12 @@ pub fn valid_ret_activity(mode: DiffMode, activity: DiffActivity) -> bool {
     match mode {
         DiffMode::Error => false,
         DiffMode::Source => false,
-        DiffMode::Forward | DiffMode::ForwardFirst => {
+        DiffMode::Forward => {
             activity == DiffActivity::Dual
                 || activity == DiffActivity::DualOnly
                 || activity == DiffActivity::Const
         }
-        DiffMode::Reverse | DiffMode::ReverseFirst => {
+        DiffMode::Reverse => {
             activity == DiffActivity::Const
                 || activity == DiffActivity::Active
                 || activity == DiffActivity::ActiveOnly
@@ -166,10 +156,10 @@ pub fn valid_input_activity(mode: DiffMode, activity: DiffActivity) -> bool {
     return match mode {
         DiffMode::Error => false,
         DiffMode::Source => false,
-        DiffMode::Forward | DiffMode::ForwardFirst => {
+        DiffMode::Forward => {
             matches!(activity, Dual | DualOnly | Const)
         }
-        DiffMode::Reverse | DiffMode::ReverseFirst => {
+        DiffMode::Reverse => {
             matches!(activity, Active | ActiveOnly | Duplicated | DuplicatedOnly | Const)
         }
     };
@@ -200,8 +190,6 @@ impl FromStr for DiffMode {
             "Source" => Ok(DiffMode::Source),
             "Forward" => Ok(DiffMode::Forward),
             "Reverse" => Ok(DiffMode::Reverse),
-            "ForwardFirst" => Ok(DiffMode::ForwardFirst),
-            "ReverseFirst" => Ok(DiffMode::ReverseFirst),
             _ => Err(()),
         }
     }
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
index 8cc4521e0a7..754f3c1a6e9 100644
--- a/compiler/rustc_ast_lowering/Cargo.toml
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -8,6 +8,7 @@ doctest = false
 
 [dependencies]
 # tidy-alphabetical-start
+rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index dded18fce0a..923fd65dcca 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -828,15 +828,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 span,
                 Some(Arc::clone(&self.allow_gen_future)),
             );
-            self.lower_attrs(inner_hir_id, &[Attribute {
-                kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
-                    sym::track_caller,
-                    span,
-                )))),
-                id: self.tcx.sess.psess.attr_id_generator.mk_attr_id(),
-                style: AttrStyle::Outer,
-                span: unstable_span,
-            }]);
+            self.lower_attrs(
+                inner_hir_id,
+                &[Attribute {
+                    kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
+                        sym::track_caller,
+                        span,
+                    )))),
+                    id: self.tcx.sess.psess.attr_id_generator.mk_attr_id(),
+                    style: AttrStyle::Outer,
+                    span: unstable_span,
+                }],
+            );
         }
     }
 
diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index 22aa1e6fc20..07b94dbc2ae 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -362,13 +362,16 @@ fn make_format_spec<'hir>(
         debug_hex,
     } = &placeholder.format_options;
     let fill = ctx.expr_char(sp, fill.unwrap_or(' '));
-    let align =
-        ctx.expr_lang_item_type_relative(sp, hir::LangItem::FormatAlignment, match alignment {
+    let align = ctx.expr_lang_item_type_relative(
+        sp,
+        hir::LangItem::FormatAlignment,
+        match alignment {
             Some(FormatAlignment::Left) => sym::Left,
             Some(FormatAlignment::Right) => sym::Right,
             Some(FormatAlignment::Center) => sym::Center,
             None => sym::Unknown,
-        });
+        },
+    );
     // This needs to match `Flag` in library/core/src/fmt/rt.rs.
     let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32)
         | ((sign == Some(FormatSign::Minus)) as u32) << 1
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index c96110fee61..7379a3d2cde 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1,3 +1,4 @@
+use rustc_abi::ExternAbi;
 use rustc_ast::ptr::P;
 use rustc_ast::visit::AssocCtxt;
 use rustc_ast::*;
@@ -11,7 +12,6 @@ use rustc_middle::span_bug;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::{DesugaringKind, Ident, Span, Symbol, kw, sym};
-use rustc_target::spec::abi;
 use smallvec::{SmallVec, smallvec};
 use thin_vec::ThinVec;
 use tracing::instrument;
@@ -275,7 +275,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
             },
             ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
-                abi: fm.abi.map_or(abi::Abi::FALLBACK, |abi| self.lower_abi(abi)),
+                abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
                 items: self
                     .arena
                     .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
@@ -304,12 +304,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             );
                             this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
                         }
-                        Some(ty) => this.lower_ty(ty, ImplTraitContext::OpaqueTy {
-                            origin: hir::OpaqueTyOrigin::TyAlias {
-                                parent: this.local_def_id(id),
-                                in_assoc_ty: false,
+                        Some(ty) => this.lower_ty(
+                            ty,
+                            ImplTraitContext::OpaqueTy {
+                                origin: hir::OpaqueTyOrigin::TyAlias {
+                                    parent: this.local_def_id(id),
+                                    in_assoc_ty: false,
+                                },
                             },
-                        }),
+                        ),
                     },
                 );
                 hir::ItemKind::TyAlias(ty, generics)
@@ -966,12 +969,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             hir::ImplItemKind::Type(ty)
                         }
                         Some(ty) => {
-                            let ty = this.lower_ty(ty, ImplTraitContext::OpaqueTy {
-                                origin: hir::OpaqueTyOrigin::TyAlias {
-                                    parent: this.local_def_id(i.id),
-                                    in_assoc_ty: true,
+                            let ty = this.lower_ty(
+                                ty,
+                                ImplTraitContext::OpaqueTy {
+                                    origin: hir::OpaqueTyOrigin::TyAlias {
+                                        parent: this.local_def_id(i.id),
+                                        in_assoc_ty: true,
+                                    },
                                 },
-                            });
+                            );
                             hir::ImplItemKind::Type(ty)
                         }
                     },
@@ -1152,10 +1158,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
         self.lower_body(|this| {
-            (&[], match expr {
-                Some(expr) => this.lower_expr_mut(expr),
-                None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
-            })
+            (
+                &[],
+                match expr {
+                    Some(expr) => this.lower_expr_mut(expr),
+                    None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
+                },
+            )
         })
     }
 
@@ -1470,23 +1479,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
-        abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|err| {
+    pub(super) fn lower_abi(&mut self, abi: StrLit) -> ExternAbi {
+        rustc_abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|err| {
             self.error_on_invalid_abi(abi, err);
-            abi::Abi::Rust
+            ExternAbi::Rust
         })
     }
 
-    pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
+    pub(super) fn lower_extern(&mut self, ext: Extern) -> ExternAbi {
         match ext {
-            Extern::None => abi::Abi::Rust,
-            Extern::Implicit(_) => abi::Abi::FALLBACK,
+            Extern::None => ExternAbi::Rust,
+            Extern::Implicit(_) => ExternAbi::FALLBACK,
             Extern::Explicit(abi, _) => self.lower_abi(abi),
         }
     }
 
-    fn error_on_invalid_abi(&self, abi: StrLit, err: abi::AbiUnsupported) {
-        let abi_names = abi::enabled_names(self.tcx.features(), abi.span)
+    fn error_on_invalid_abi(&self, abi: StrLit, err: rustc_abi::AbiUnsupported) {
+        let abi_names = rustc_abi::enabled_names(self.tcx.features(), abi.span)
             .iter()
             .map(|s| Symbol::intern(s))
             .collect::<Vec<_>>();
@@ -1495,7 +1504,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             abi: abi.symbol_unescaped,
             span: abi.span,
             explain: match err {
-                abi::AbiUnsupported::Reason { explain } => Some(InvalidAbiReason(explain)),
+                rustc_abi::AbiUnsupported::Reason { explain } => Some(InvalidAbiReason(explain)),
                 _ => None,
             },
             suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml
index 8046765647e..19c379c8599 100644
--- a/compiler/rustc_ast_passes/Cargo.toml
+++ b/compiler/rustc_ast_passes/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2021"
 [dependencies]
 # tidy-alphabetical-start
 itertools = "0.12"
+rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_attr_parsing = { path = "../rustc_attr_parsing" }
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 62e451fa876..13294efdaf6 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -6,7 +6,6 @@ use rustc_session::Session;
 use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
 use rustc_span::source_map::Spanned;
 use rustc_span::{Span, Symbol, sym};
-use rustc_target::spec::abi;
 use thin_vec::ThinVec;
 
 use crate::errors;
@@ -77,12 +76,12 @@ impl<'a> PostExpansionVisitor<'a> {
     fn check_abi(&self, abi: ast::StrLit) {
         let ast::StrLit { symbol_unescaped, span, .. } = abi;
 
-        match abi::is_enabled(self.features, span, symbol_unescaped.as_str()) {
+        match rustc_abi::is_enabled(self.features, span, symbol_unescaped.as_str()) {
             Ok(()) => (),
-            Err(abi::AbiDisabled::Unstable { feature, explain }) => {
+            Err(rustc_abi::AbiDisabled::Unstable { feature, explain }) => {
                 feature_err_issue(&self.sess, feature, span, GateIssue::Language, explain).emit();
             }
-            Err(abi::AbiDisabled::Unrecognized) => {
+            Err(rustc_abi::AbiDisabled::Unrecognized) => {
                 if self.sess.opts.pretty.is_none_or(|ppm| ppm.needs_hir()) {
                     self.sess.dcx().span_delayed_bug(
                         span,
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
index b1d8ec49774..92bc2a8aeb0 100644
--- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs
+++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -204,21 +204,27 @@ pub(crate) struct UnsupportedLiteral {
 
 impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral {
     fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
-        let mut diag = Diag::new(dcx, level, match self.reason {
-            UnsupportedLiteralReason::Generic => fluent::attr_parsing_unsupported_literal_generic,
-            UnsupportedLiteralReason::CfgString => {
-                fluent::attr_parsing_unsupported_literal_cfg_string
-            }
-            UnsupportedLiteralReason::CfgBoolean => {
-                fluent::attr_parsing_unsupported_literal_cfg_boolean
-            }
-            UnsupportedLiteralReason::DeprecatedString => {
-                fluent::attr_parsing_unsupported_literal_deprecated_string
-            }
-            UnsupportedLiteralReason::DeprecatedKvPair => {
-                fluent::attr_parsing_unsupported_literal_deprecated_kv_pair
-            }
-        });
+        let mut diag = Diag::new(
+            dcx,
+            level,
+            match self.reason {
+                UnsupportedLiteralReason::Generic => {
+                    fluent::attr_parsing_unsupported_literal_generic
+                }
+                UnsupportedLiteralReason::CfgString => {
+                    fluent::attr_parsing_unsupported_literal_cfg_string
+                }
+                UnsupportedLiteralReason::CfgBoolean => {
+                    fluent::attr_parsing_unsupported_literal_cfg_boolean
+                }
+                UnsupportedLiteralReason::DeprecatedString => {
+                    fluent::attr_parsing_unsupported_literal_deprecated_string
+                }
+                UnsupportedLiteralReason::DeprecatedKvPair => {
+                    fluent::attr_parsing_unsupported_literal_deprecated_kv_pair
+                }
+            },
+        );
         diag.span(self.span);
         diag.code(E0565);
         if self.is_bytestr {
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 475897d8f3e..30b0a358580 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -156,24 +156,25 @@ pub(crate) trait TypeOpInfo<'tcx> {
             return;
         };
 
-        let placeholder_region = ty::Region::new_placeholder(tcx, ty::Placeholder {
-            universe: adjusted_universe.into(),
-            bound: placeholder.bound,
-        });
-
-        let error_region =
-            if let RegionElement::PlaceholderRegion(error_placeholder) = error_element {
-                let adjusted_universe =
-                    error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
-                adjusted_universe.map(|adjusted| {
-                    ty::Region::new_placeholder(tcx, ty::Placeholder {
-                        universe: adjusted.into(),
-                        bound: error_placeholder.bound,
-                    })
-                })
-            } else {
-                None
-            };
+        let placeholder_region = ty::Region::new_placeholder(
+            tcx,
+            ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
+        );
+
+        let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) =
+            error_element
+        {
+            let adjusted_universe =
+                error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
+            adjusted_universe.map(|adjusted| {
+                ty::Region::new_placeholder(
+                    tcx,
+                    ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound },
+                )
+            })
+        } else {
+            None
+        };
 
         debug!(?placeholder_region);
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index b3fb2cd938b..6269728e67f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -147,10 +147,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 span,
                 desired_action.as_noun(),
                 partially_str,
-                self.describe_place_with_options(moved_place, DescribePlaceOpt {
-                    including_downcast: true,
-                    including_tuple_field: true,
-                }),
+                self.describe_place_with_options(
+                    moved_place,
+                    DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
+                ),
             );
 
             let reinit_spans = maybe_reinitialized_locations
@@ -280,10 +280,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 self.suggest_adding_bounds(&mut err, ty, copy_did, span);
             }
 
-            let opt_name = self.describe_place_with_options(place.as_ref(), DescribePlaceOpt {
-                including_downcast: true,
-                including_tuple_field: true,
-            });
+            let opt_name = self.describe_place_with_options(
+                place.as_ref(),
+                DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
+            );
             let note_msg = match opt_name {
                 Some(name) => format!("`{name}`"),
                 None => "value".to_owned(),
@@ -765,17 +765,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         }
         let spans: Vec<_> = spans_set.into_iter().collect();
 
-        let (name, desc) = match self.describe_place_with_options(moved_place, DescribePlaceOpt {
-            including_downcast: true,
-            including_tuple_field: true,
-        }) {
+        let (name, desc) = match self.describe_place_with_options(
+            moved_place,
+            DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
+        ) {
             Some(name) => (format!("`{name}`"), format!("`{name}` ")),
             None => ("the variable".to_string(), String::new()),
         };
-        let path = match self.describe_place_with_options(used_place, DescribePlaceOpt {
-            including_downcast: true,
-            including_tuple_field: true,
-        }) {
+        let path = match self.describe_place_with_options(
+            used_place,
+            DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
+        ) {
             Some(name) => format!("`{name}`"),
             None => "value".to_string(),
         };
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 01ed0464c8a..860c7c267ea 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -304,10 +304,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
     /// End-user visible description of `place` if one can be found.
     /// If the place is a temporary for instance, `None` will be returned.
     pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option<String> {
-        self.describe_place_with_options(place_ref, DescribePlaceOpt {
-            including_downcast: false,
-            including_tuple_field: true,
-        })
+        self.describe_place_with_options(
+            place_ref,
+            DescribePlaceOpt { including_downcast: false, including_tuple_field: true },
+        )
     }
 
     /// End-user visible description of `place` if one can be found. If the place is a temporary
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 3c4e4c29197..b809b40a399 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -1100,12 +1100,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         let closure_ty = Ty::new_closure(
             tcx,
             closure_def_id.to_def_id(),
-            ty::ClosureArgs::new(tcx, ty::ClosureArgsParts {
-                parent_args: args.parent_args(),
-                closure_kind_ty: args.kind_ty(),
-                tupled_upvars_ty: args.tupled_upvars_ty(),
-                closure_sig_as_fn_ptr_ty,
-            })
+            ty::ClosureArgs::new(
+                tcx,
+                ty::ClosureArgsParts {
+                    parent_args: args.parent_args(),
+                    closure_kind_ty: args.kind_ty(),
+                    tupled_upvars_ty: args.tupled_upvars_ty(),
+                    closure_sig_as_fn_ptr_ty,
+                },
+            )
             .args,
         );
 
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 8ddc8add675..53cf4f34ae7 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1668,9 +1668,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
             match elem {
                 ProjectionElem::Deref => match place_ty.ty.kind() {
                     ty::Ref(..) | ty::RawPtr(..) => {
-                        self.move_errors.push(MoveError::new(place, location, BorrowedContent {
-                            target_place: place_ref.project_deeper(&[elem], tcx),
-                        }));
+                        self.move_errors.push(MoveError::new(
+                            place,
+                            location,
+                            BorrowedContent {
+                                target_place: place_ref.project_deeper(&[elem], tcx),
+                            },
+                        ));
                         return;
                     }
                     ty::Adt(adt, _) => {
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 5440d451ec8..9c19f8b3ad8 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -166,10 +166,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
                 prev.span = prev.span.substitute_dummy(concrete_type.span);
             } else {
-                result.insert(opaque_type_key.def_id, OpaqueHiddenType {
-                    ty,
-                    span: concrete_type.span,
-                });
+                result.insert(
+                    opaque_type_key.def_id,
+                    OpaqueHiddenType { ty, span: concrete_type.span },
+                );
             }
 
             // Check that all opaque types have the same region parameters if they have the same
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index 1f2ec168f03..f70b17e3362 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -75,17 +75,20 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             let output_ty = Ty::new_coroutine(
                 self.tcx(),
                 self.tcx().coroutine_for_closure(mir_def_id),
-                ty::CoroutineArgs::new(self.tcx(), ty::CoroutineArgsParts {
-                    parent_args: args.parent_args(),
-                    kind_ty: Ty::from_coroutine_closure_kind(self.tcx(), args.kind()),
-                    return_ty: user_provided_sig.output(),
-                    tupled_upvars_ty,
-                    // For async closures, none of these can be annotated, so just fill
-                    // them with fresh ty vars.
-                    resume_ty: next_ty_var(),
-                    yield_ty: next_ty_var(),
-                    witness: next_ty_var(),
-                })
+                ty::CoroutineArgs::new(
+                    self.tcx(),
+                    ty::CoroutineArgsParts {
+                        parent_args: args.parent_args(),
+                        kind_ty: Ty::from_coroutine_closure_kind(self.tcx(), args.kind()),
+                        return_ty: user_provided_sig.output(),
+                        tupled_upvars_ty,
+                        // For async closures, none of these can be annotated, so just fill
+                        // them with fresh ty vars.
+                        resume_ty: next_ty_var(),
+                        yield_ty: next_ty_var(),
+                        witness: next_ty_var(),
+                    },
+                )
                 .args,
             );
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 002f6e36cd8..26a5d438edb 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -411,10 +411,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                 } else {
                     self.typeck.ascribe_user_type(
                         constant.const_.ty(),
-                        ty::UserType::new(ty::UserTypeKind::TypeOf(uv.def, UserArgs {
-                            args: uv.args,
-                            user_self_ty: None,
-                        })),
+                        ty::UserType::new(ty::UserTypeKind::TypeOf(
+                            uv.def,
+                            UserArgs { args: uv.args, user_self_ty: None },
+                        )),
                         locations.span(self.typeck.body),
                     );
                 }
@@ -1642,10 +1642,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             }
 
             &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
-                let trait_ref =
-                    ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, Some(span)), [
-                        ty,
-                    ]);
+                let trait_ref = ty::TraitRef::new(
+                    tcx,
+                    tcx.require_lang_item(LangItem::Sized, Some(span)),
+                    [ty],
+                );
 
                 self.prove_trait_ref(
                     trait_ref,
@@ -1659,10 +1660,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             Rvalue::ShallowInitBox(operand, ty) => {
                 self.check_operand(operand, location);
 
-                let trait_ref =
-                    ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, Some(span)), [
-                        *ty,
-                    ]);
+                let trait_ref = ty::TraitRef::new(
+                    tcx,
+                    tcx.require_lang_item(LangItem::Sized, Some(span)),
+                    [*ty],
+                );
 
                 self.prove_trait_ref(
                     trait_ref,
diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
index ad4e006c21a..17482cc0cbd 100644
--- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
@@ -284,7 +284,7 @@ where
             return;
         }
 
-        match ty.kind() {
+        match *ty.kind() {
             ty::Closure(_, args) => {
                 // Skip lifetime parameters of the enclosing item(s)
 
@@ -316,10 +316,12 @@ where
                 args.as_coroutine().resume_ty().visit_with(self);
             }
 
-            ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
-                // Skip lifetime parameters that are not captures.
-                let variances = self.tcx.variances_of(*def_id);
-
+            ty::Alias(kind, ty::AliasTy { def_id, args, .. })
+                if let Some(variances) = self.tcx.opt_alias_variances(kind, def_id) =>
+            {
+                // Skip lifetime parameters that are not captured, since they do
+                // not need member constraints registered for them; we'll erase
+                // them (and hopefully in the future replace them with placeholders).
                 for (v, s) in std::iter::zip(variances, args.iter()) {
                     if *v != ty::Bivariant {
                         s.visit_with(self);
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 26af86c0cdd..eb0079a3883 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -620,10 +620,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                     let ty = tcx
                         .typeck(self.mir_def)
                         .node_type(tcx.local_def_id_to_hir_id(self.mir_def));
-                    let args = InlineConstArgs::new(tcx, InlineConstArgsParts {
-                        parent_args: identity_args,
-                        ty,
-                    })
+                    let args = InlineConstArgs::new(
+                        tcx,
+                        InlineConstArgsParts { parent_args: identity_args, ty },
+                    )
                     .args;
                     let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args);
                     DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index cffc4978601..78bf2195975 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -67,10 +67,11 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
 
     let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
     let layout_new = cx.expr_path(cx.path(span, layout_new));
-    let layout = cx.expr_call(span, layout_new, thin_vec![
-        cx.expr_ident(span, size),
-        cx.expr_ident(span, align)
-    ]);
+    let layout = cx.expr_call(
+        span,
+        layout_new,
+        thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)],
+    );
 
     let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]);
 
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 8960cf6ab59..24c54edd705 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -406,19 +406,21 @@ mod llvm_enzyme {
         let unsf_expr = ecx.expr_block(P(unsf_block));
         let blackbox_call_expr = ecx.expr_path(ecx.path(span, blackbox_path));
         let primal_call = gen_primal_call(ecx, span, primal, idents);
-        let black_box_primal_call =
-            ecx.expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![
-                primal_call.clone()
-            ]);
+        let black_box_primal_call = ecx.expr_call(
+            new_decl_span,
+            blackbox_call_expr.clone(),
+            thin_vec![primal_call.clone()],
+        );
         let tup_args = new_names
             .iter()
             .map(|arg| ecx.expr_path(ecx.path_ident(span, Ident::from_str(arg))))
             .collect();
 
-        let black_box_remaining_args =
-            ecx.expr_call(sig_span, blackbox_call_expr.clone(), thin_vec![
-                ecx.expr_tuple(sig_span, tup_args)
-            ]);
+        let black_box_remaining_args = ecx.expr_call(
+            sig_span,
+            blackbox_call_expr.clone(),
+            thin_vec![ecx.expr_tuple(sig_span, tup_args)],
+        );
 
         let mut body = ecx.block(span, ThinVec::new());
         body.stmts.push(ecx.stmt_semi(unsf_expr));
@@ -532,8 +534,11 @@ mod llvm_enzyme {
                 return body;
             }
             [arg] => {
-                ret = ecx
-                    .expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![arg.clone()]);
+                ret = ecx.expr_call(
+                    new_decl_span,
+                    blackbox_call_expr.clone(),
+                    thin_vec![arg.clone()],
+                );
             }
             args => {
                 let ret_tuple: P<ast::Expr> = ecx.expr_tuple(span, args.into());
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index 78f50ba8d29..c3656e8244f 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -114,10 +114,13 @@ fn cs_clone_simple(
                 // type parameters.
             } else {
                 // let _: AssertParamIsClone<FieldTy>;
-                super::assert_ty_bounds(cx, &mut stmts, field.ty.clone(), field.span, &[
-                    sym::clone,
-                    sym::AssertParamIsClone,
-                ]);
+                super::assert_ty_bounds(
+                    cx,
+                    &mut stmts,
+                    field.ty.clone(),
+                    field.span,
+                    &[sym::clone, sym::AssertParamIsClone],
+                );
             }
         }
     };
@@ -126,10 +129,13 @@ fn cs_clone_simple(
         // Just a single assertion for unions, that the union impls `Copy`.
         // let _: AssertParamIsCopy<Self>;
         let self_ty = cx.ty_path(cx.path_ident(trait_span, Ident::with_dummy_span(kw::SelfUpper)));
-        super::assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, &[
-            sym::clone,
-            sym::AssertParamIsCopy,
-        ]);
+        super::assert_ty_bounds(
+            cx,
+            &mut stmts,
+            self_ty,
+            trait_span,
+            &[sym::clone, sym::AssertParamIsCopy],
+        );
     } else {
         match *substr.fields {
             StaticStruct(vdata, ..) => {
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 5790350203a..eca79e4dc48 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -65,10 +65,13 @@ fn cs_total_eq_assert(
                 // Already produced an assertion for this type.
             } else {
                 // let _: AssertParamIsEq<FieldTy>;
-                super::assert_ty_bounds(cx, &mut stmts, field.ty.clone(), field.span, &[
-                    sym::cmp,
-                    sym::AssertParamIsEq,
-                ]);
+                super::assert_ty_bounds(
+                    cx,
+                    &mut stmts,
+                    field.ty.clone(),
+                    field.span,
+                    &[sym::cmp, sym::AssertParamIsEq],
+                );
             }
         }
     };
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 2388b7dd648..1fe567e23f4 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -108,30 +108,38 @@ fn default_enum_substructure(
         Ok(default_variant) => {
             // We now know there is exactly one unit variant with exactly one `#[default]` attribute.
             match &default_variant.data {
-                VariantData::Unit(_) => cx.expr_path(cx.path(default_variant.span, vec![
-                    Ident::new(kw::SelfUpper, default_variant.span),
-                    default_variant.ident,
-                ])),
+                VariantData::Unit(_) => cx.expr_path(cx.path(
+                    default_variant.span,
+                    vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident],
+                )),
                 VariantData::Struct { fields, .. } => {
                     // This only happens if `#![feature(default_field_values)]`. We have validated
                     // all fields have default values in the definition.
                     let default_fields = fields
                         .iter()
                         .map(|field| {
-                            cx.field_imm(field.span, field.ident.unwrap(), match &field.default {
-                                // We use `Default::default()`.
-                                None => default_call(cx, field.span),
-                                // We use the field default const expression.
-                                Some(val) => {
-                                    cx.expr(val.value.span, ast::ExprKind::ConstBlock(val.clone()))
-                                }
-                            })
+                            cx.field_imm(
+                                field.span,
+                                field.ident.unwrap(),
+                                match &field.default {
+                                    // We use `Default::default()`.
+                                    None => default_call(cx, field.span),
+                                    // We use the field default const expression.
+                                    Some(val) => cx.expr(
+                                        val.value.span,
+                                        ast::ExprKind::ConstBlock(val.clone()),
+                                    ),
+                                },
+                            )
                         })
                         .collect();
-                    let path = cx.path(default_variant.span, vec![
-                        Ident::new(kw::SelfUpper, default_variant.span),
-                        default_variant.ident,
-                    ]);
+                    let path = cx.path(
+                        default_variant.span,
+                        vec![
+                            Ident::new(kw::SelfUpper, default_variant.span),
+                            default_variant.ident,
+                        ],
+                    );
                     cx.expr_struct(default_variant.span, path, default_fields)
                 }
                 // Logic error in `extract_default_variant`.
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 0631c5a80fc..234ec858216 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -1220,10 +1220,12 @@ impl<'a> MethodDef<'a> {
 
             let discr_let_stmts: ThinVec<_> = iter::zip(&discr_idents, &selflike_args)
                 .map(|(&ident, selflike_arg)| {
-                    let variant_value =
-                        deriving::call_intrinsic(cx, span, sym::discriminant_value, thin_vec![
-                            selflike_arg.clone()
-                        ]);
+                    let variant_value = deriving::call_intrinsic(
+                        cx,
+                        span,
+                        sym::discriminant_value,
+                        thin_vec![selflike_arg.clone()],
+                    );
                     cx.stmt_let(span, false, ident, variant_value)
                 })
                 .collect();
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 8831261759c..0913dc91a53 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -77,11 +77,11 @@ pub(crate) fn expand_option_env<'cx>(
             let guar = cx.dcx().emit_err(errors::EnvNotUnicode { span: sp, var: *symbol });
             return ExpandResult::Ready(DummyResult::any(sp, guar));
         }
-        Ok(value) => {
-            cx.expr_call_global(sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), thin_vec![
-                cx.expr_str(sp, value)
-            ])
-        }
+        Ok(value) => cx.expr_call_global(
+            sp,
+            cx.std_path(&[sym::option, sym::Option, sym::Some]),
+            thin_vec![cx.expr_str(sp, value)],
+        ),
     };
     ExpandResult::Ready(MacEager::expr(e))
 }
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index 71320e6d5ad..866ec72f116 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -183,10 +183,14 @@ pub(crate) mod printf {
             s.push('{');
 
             if let Some(arg) = self.parameter {
-                match write!(s, "{}", match arg.checked_sub(1) {
-                    Some(a) => a,
-                    None => return Err(None),
-                }) {
+                match write!(
+                    s,
+                    "{}",
+                    match arg.checked_sub(1) {
+                        Some(a) => a,
+                        None => return Err(None),
+                    }
+                ) {
                     Err(_) => return Err(None),
                     _ => {}
                 }
diff --git a/compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs b/compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs
index 8fe06df48e5..1fd54e170b9 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs
@@ -99,12 +99,10 @@ fn test_parse() {
 fn test_iter() {
     let s = "The %d'th word %% is: `%.*s` %!\n";
     let subs: Vec<_> = iter_subs(s, 0).map(|sub| sub.translate().ok()).collect();
-    assert_eq!(subs.iter().map(Option::as_deref).collect::<Vec<_>>(), vec![
-        Some("{}"),
-        None,
-        Some("{:.*}"),
-        None
-    ]);
+    assert_eq!(
+        subs.iter().map(Option::as_deref).collect::<Vec<_>>(),
+        vec![Some("{}"), None, Some("{:.*}"), None]
+    );
 }
 
 /// Checks that the translations are what we expect.
diff --git a/compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs b/compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs
index dd2ee2b6ca9..145e3e529b0 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs
@@ -38,11 +38,10 @@ fn test_iter() {
     use super::iter_subs;
     let s = "The $0'th word $$ is: `$WORD` $!\n";
     let subs: Vec<_> = iter_subs(s, 0).map(|sub| sub.translate().ok()).collect();
-    assert_eq!(subs.iter().map(Option::as_deref).collect::<Vec<_>>(), vec![
-        Some("{0}"),
-        None,
-        Some("{WORD}")
-    ]);
+    assert_eq!(
+        subs.iter().map(Option::as_deref).collect::<Vec<_>>(),
+        vec![Some("{0}"), None, Some("{WORD}")]
+    );
 }
 
 #[test]
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index dee185ff0c9..ee6475c8b8e 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -301,13 +301,10 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
             };
             let local_path = |cx: &ExtCtxt<'_>, name| cx.expr_path(cx.path(span, vec![name]));
             let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| {
-                cx.expr_path(cx.path(span.with_ctxt(harness_span.ctxt()), vec![
-                    proc_macro,
-                    bridge,
-                    client,
-                    proc_macro_ty,
-                    method,
-                ]))
+                cx.expr_path(cx.path(
+                    span.with_ctxt(harness_span.ctxt()),
+                    vec![proc_macro, bridge, client, proc_macro_ty, method],
+                ))
             };
             match m {
                 ProcMacro::Derive(cd) => {
@@ -340,10 +337,14 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
 
                     // The call needs to use `harness_span` so that the const stability checker
                     // accepts it.
-                    cx.expr_call(harness_span, proc_macro_ty_method_path(cx, ident), thin_vec![
-                        cx.expr_str(span, ca.function_name.name),
-                        local_path(cx, ca.function_name),
-                    ])
+                    cx.expr_call(
+                        harness_span,
+                        proc_macro_ty_method_path(cx, ident),
+                        thin_vec![
+                            cx.expr_str(span, ca.function_name.name),
+                            local_path(cx, ca.function_name),
+                        ],
+                    )
                 }
             }
         })
@@ -357,12 +358,9 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
                 span,
                 cx.ty(
                     span,
-                    ast::TyKind::Slice(cx.ty_path(cx.path(span, vec![
-                        proc_macro,
-                        bridge,
-                        client,
-                        proc_macro_ty,
-                    ]))),
+                    ast::TyKind::Slice(
+                        cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty])),
+                    ),
                 ),
                 None,
                 ast::Mutability::Not,
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 3f73ddbdd29..a05fff2dcd1 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -169,20 +169,26 @@ pub(crate) fn expand_test_or_bench(
 
     // creates test::ShouldPanic::$name
     let should_panic_path = |name| {
-        cx.path(sp, vec![
-            test_id,
-            Ident::from_str_and_span("ShouldPanic", sp),
-            Ident::from_str_and_span(name, sp),
-        ])
+        cx.path(
+            sp,
+            vec![
+                test_id,
+                Ident::from_str_and_span("ShouldPanic", sp),
+                Ident::from_str_and_span(name, sp),
+            ],
+        )
     };
 
     // creates test::TestType::$name
     let test_type_path = |name| {
-        cx.path(sp, vec![
-            test_id,
-            Ident::from_str_and_span("TestType", sp),
-            Ident::from_str_and_span(name, sp),
-        ])
+        cx.path(
+            sp,
+            vec![
+                test_id,
+                Ident::from_str_and_span("TestType", sp),
+                Ident::from_str_and_span(name, sp),
+            ],
+        )
     };
 
     // creates $name: $expr
@@ -202,39 +208,55 @@ pub(crate) fn expand_test_or_bench(
         // A simple ident for a lambda
         let b = Ident::from_str_and_span("b", attr_sp);
 
-        cx.expr_call(sp, cx.expr_path(test_path("StaticBenchFn")), thin_vec![
-            // #[coverage(off)]
-            // |b| self::test::assert_test_result(
-            coverage_off(cx.lambda1(
-                sp,
-                cx.expr_call(sp, cx.expr_path(test_path("assert_test_result")), thin_vec![
-                    // super::$test_fn(b)
+        cx.expr_call(
+            sp,
+            cx.expr_path(test_path("StaticBenchFn")),
+            thin_vec![
+                // #[coverage(off)]
+                // |b| self::test::assert_test_result(
+                coverage_off(cx.lambda1(
+                    sp,
                     cx.expr_call(
-                        ret_ty_sp,
-                        cx.expr_path(cx.path(sp, vec![item.ident])),
-                        thin_vec![cx.expr_ident(sp, b)],
+                        sp,
+                        cx.expr_path(test_path("assert_test_result")),
+                        thin_vec![
+                            // super::$test_fn(b)
+                            cx.expr_call(
+                                ret_ty_sp,
+                                cx.expr_path(cx.path(sp, vec![item.ident])),
+                                thin_vec![cx.expr_ident(sp, b)],
+                            ),
+                        ],
                     ),
-                ],),
-                b,
-            )), // )
-        ])
+                    b,
+                )), // )
+            ],
+        )
     } else {
-        cx.expr_call(sp, cx.expr_path(test_path("StaticTestFn")), thin_vec![
-            // #[coverage(off)]
-            // || {
-            coverage_off(cx.lambda0(
-                sp,
-                // test::assert_test_result(
-                cx.expr_call(sp, cx.expr_path(test_path("assert_test_result")), thin_vec![
-                    // $test_fn()
+        cx.expr_call(
+            sp,
+            cx.expr_path(test_path("StaticTestFn")),
+            thin_vec![
+                // #[coverage(off)]
+                // || {
+                coverage_off(cx.lambda0(
+                    sp,
+                    // test::assert_test_result(
                     cx.expr_call(
-                        ret_ty_sp,
-                        cx.expr_path(cx.path(sp, vec![item.ident])),
-                        ThinVec::new(),
-                    ), // )
-                ],), // }
-            )), // )
-        ])
+                        sp,
+                        cx.expr_path(test_path("assert_test_result")),
+                        thin_vec![
+                            // $test_fn()
+                            cx.expr_call(
+                                ret_ty_sp,
+                                cx.expr_path(cx.path(sp, vec![item.ident])),
+                                ThinVec::new(),
+                            ), // )
+                        ],
+                    ), // }
+                )), // )
+            ],
+        )
     };
 
     let test_path_symbol = Symbol::intern(&item_path(
@@ -245,26 +267,30 @@ pub(crate) fn expand_test_or_bench(
 
     let location_info = get_location_info(cx, &item);
 
-    let mut test_const = cx.item(
-        sp,
-        Ident::new(item.ident.name, sp),
-        thin_vec![
-            // #[cfg(test)]
-            cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
-            // #[rustc_test_marker = "test_case_sort_key"]
-            cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
-            // #[doc(hidden)]
-            cx.attr_nested_word(sym::doc, sym::hidden, attr_sp),
-        ],
-        // const $ident: test::TestDescAndFn =
-        ast::ItemKind::Const(
-            ast::ConstItem {
-                defaultness: ast::Defaultness::Final,
-                generics: ast::Generics::default(),
-                ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
-                // test::TestDescAndFn {
-                expr: Some(
-                    cx.expr_struct(sp, test_path("TestDescAndFn"), thin_vec![
+    let mut test_const =
+        cx.item(
+            sp,
+            Ident::new(item.ident.name, sp),
+            thin_vec![
+                // #[cfg(test)]
+                cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
+                // #[rustc_test_marker = "test_case_sort_key"]
+                cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
+                // #[doc(hidden)]
+                cx.attr_nested_word(sym::doc, sym::hidden, attr_sp),
+            ],
+            // const $ident: test::TestDescAndFn =
+            ast::ItemKind::Const(
+                ast::ConstItem {
+                    defaultness: ast::Defaultness::Final,
+                    generics: ast::Generics::default(),
+                    ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
+                    // test::TestDescAndFn {
+                    expr: Some(
+                        cx.expr_struct(
+                            sp,
+                            test_path("TestDescAndFn"),
+                            thin_vec![
                         // desc: test::TestDesc {
                         field(
                             "desc",
@@ -340,12 +366,13 @@ pub(crate) fn expand_test_or_bench(
                         ),
                         // testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
                         field("testfn", test_fn), // }
-                    ]), // }
-                ),
-            }
-            .into(),
-        ),
-    );
+                    ],
+                        ), // }
+                    ),
+                }
+                .into(),
+            ),
+        );
     test_const = test_const.map(|mut tc| {
         tc.vis.kind = ast::VisibilityKind::Public;
         tc
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index b5aba86079f..ca66ec5c6e9 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -43,24 +43,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac89549be94911dd0e839b4a7db99e9ed29c17517e1c026f61066884c168aa3c"
+checksum = "e15d04a0ce86cb36ead88ad68cf693ffd6cda47052b9e0ac114bc47fd9cd23c4"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-bitset"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9bd49369f76c77e34e641af85d0956869237832c118964d08bf5f51f210875a"
+checksum = "7c6e3969a7ce267259ce244b7867c5d3bc9e65b0a87e81039588dfdeaede9f34"
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd96ce9cf8efebd7f5ab8ced5a0ce44250280bbae9f593d74a6d7effc3582a35"
+checksum = "2c22032c4cb42558371cf516bb47f26cdad1819d3475c133e93c49f50ebf304e"
 dependencies = [
  "bumpalo",
  "cranelift-bforest",
@@ -82,42 +82,42 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a68e358827afe4bfb6239fcbf6fbd5ac56206ece8a99c8f5f9bbd518773281a"
+checksum = "c904bc71c61b27fc57827f4a1379f29de64fe95653b620a3db77d59655eee0b8"
 dependencies = [
  "cranelift-codegen-shared",
 ]
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e184c9767afbe73d50c55ec29abcf4c32f9baf0d9d22b86d58c4d55e06dee181"
+checksum = "40180f5497572f644ce88c255480981ae2ec1d7bb4d8e0c0136a13b87a2f2ceb"
 
 [[package]]
 name = "cranelift-control"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc7664f2a66f053e33f149e952bb5971d138e3af637f5097727ed6dc0ed95dd"
+checksum = "26d132c6d0bd8a489563472afc171759da0707804a65ece7ceb15a8c6d7dd5ef"
 dependencies = [
  "arbitrary",
 ]
 
 [[package]]
 name = "cranelift-entity"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "118597e3a9cf86c3556fa579a7a23b955fa18231651a52a77a2475d305a9cf84"
+checksum = "4b2d0d9618275474fbf679dd018ac6e009acbd6ae6850f6a67be33fb3b00b323"
 dependencies = [
  "cranelift-bitset",
 ]
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7638ea1efb069a0aa18d8ee67401b6b0d19f6bfe5de5e9ede348bfc80bb0d8c7"
+checksum = "4fac41e16729107393174b0c9e3730fb072866100e1e64e80a1a963b2e484d57"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -127,15 +127,15 @@ dependencies = [
 
 [[package]]
 name = "cranelift-isle"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15c53e1152a0b01c4ed2b1e0535602b8e86458777dd9d18b28732b16325c7dc0"
+checksum = "1ca20d576e5070044d0a72a9effc2deacf4d6aa650403189d8ea50126483944d"
 
 [[package]]
 name = "cranelift-jit"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36972cab12ff246afe8d45b6a427669cf814bd393c661e5e8a8dedc26a81c73f"
+checksum = "5e65c42755a719b09662b00c700daaf76cc35d5ace1f5c002ad404b591ff1978"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -153,9 +153,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-module"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11841b3f54ac480db1e8e8d5678ba901a13b387012d315e3f8fba3e7b7a80447"
+checksum = "4d55612bebcf16ff7306c8a6f5bdb6d45662b8aa1ee058ecce8807ad87db719b"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -164,9 +164,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-native"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b7d8f895444fa52dd7bdd0bed11bf007a7fb43af65a6deac8fcc4094c6372f7"
+checksum = "b8dee82f3f1f2c4cba9177f1cc5e350fe98764379bcd29340caa7b01f85076c7"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -175,9 +175,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-object"
-version = "0.115.0"
+version = "0.116.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e235ddfd19f100855ad03358c7ae0a13070c38a000701054cab46458cca6e81"
+checksum = "aad5a6d3e379493c3f8b35dc61c93d0bf5f27003bbe20614e0200b0ec372ef52"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -413,9 +413,9 @@ dependencies = [
 
 [[package]]
 name = "target-lexicon"
-version = "0.12.16"
+version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
+checksum = "dc12939a1c9b9d391e0b7135f72fd30508b73450753e28341fed159317582a77"
 
 [[package]]
 name = "unicode-ident"
@@ -425,9 +425,9 @@ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
 
 [[package]]
 name = "wasmtime-jit-icache-coherence"
-version = "28.0.0"
+version = "29.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d40d7722b9e1fbeae135715710a8a2570b1e6cf72b74dd653962d89831c6c70d"
+checksum = "ec5e8552e01692e6c2e5293171704fed8abdec79d1a6995a0870ab190e5747d1"
 dependencies = [
  "anyhow",
  "cfg-if",
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml
index bfdbc3e768a..670d6f4eef5 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.toml
+++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -8,13 +8,13 @@ crate-type = ["dylib"]
 
 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.115.0", default-features = false, features = ["std", "unwind", "all-native-arch"] }
-cranelift-frontend = { version = "0.115.0" }
-cranelift-module = { version = "0.115.0" }
-cranelift-native = { version = "0.115.0" }
-cranelift-jit = { version = "0.115.0", optional = true }
-cranelift-object = { version = "0.115.0" }
-target-lexicon = "0.12.0"
+cranelift-codegen = { version = "0.116.0", default-features = false, features = ["std", "unwind", "all-native-arch"] }
+cranelift-frontend = { version = "0.116.0" }
+cranelift-module = { version = "0.116.0" }
+cranelift-native = { version = "0.116.0" }
+cranelift-jit = { version = "0.116.0", optional = true }
+cranelift-object = { version = "0.116.0" }
+target-lexicon = "0.13"
 gimli = { version = "0.31", default-features = false, features = ["write"] }
 object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
 
@@ -24,12 +24,12 @@ smallvec = "1.8.1"
 
 [patch.crates-io]
 # Uncomment to use an unreleased version of cranelift
-#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-28.0.0", version = "0.115.0" }
-#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-28.0.0", version = "0.115.0" }
-#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-28.0.0", version = "0.115.0" }
-#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-28.0.0", version = "0.115.0" }
-#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-28.0.0", version = "0.115.0" }
-#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-28.0.0", version = "0.115.0" }
+#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
+#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
+#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
+#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
+#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
+#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
 
 # Uncomment to use local checkout of cranelift
 #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
index a4e9cb5f5c8..11f73bdb61f 100644
--- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
@@ -186,7 +186,7 @@ fn init_git_repo(repo_dir: &Path) {
     spawn_and_wait(git_add_cmd);
 
     let mut git_commit_cmd = git_command(repo_dir, "commit");
-    git_commit_cmd.arg("-m").arg("Initial commit").arg("-q");
+    git_commit_cmd.arg("-m").arg("Initial commit").arg("-q").arg("--no-verify");
     spawn_and_wait(git_commit_cmd);
 }
 
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index bcb2b4881eb..ea7e94c345a 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -330,14 +330,6 @@ impl<'a> TestRunner<'a> {
         target_compiler.rustflags.extend(rustflags_from_env("RUSTFLAGS"));
         target_compiler.rustdocflags.extend(rustflags_from_env("RUSTDOCFLAGS"));
 
-        // FIXME fix `#[linkage = "extern_weak"]` without this
-        if target_compiler.triple.contains("darwin") {
-            target_compiler.rustflags.extend([
-                "-Clink-arg=-undefined".to_owned(),
-                "-Clink-arg=dynamic_lookup".to_owned(),
-            ]);
-        }
-
         let jit_supported = use_unstable_features
             && is_native
             && target_compiler.triple.contains("x86_64")
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
index e47431e0f87..09d5b73fd3d 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -274,7 +274,7 @@ fn main() {
 
     assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42);
 
-    #[cfg(not(any(jit, windows)))]
+    #[cfg(not(any(jit, target_vendor = "apple", windows)))]
     {
         extern "C" {
             #[linkage = "extern_weak"]
diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs
index 0b1d83c5630..ffdc6a7d484 100644
--- a/compiler/rustc_codegen_cranelift/example/std_example.rs
+++ b/compiler/rustc_codegen_cranelift/example/std_example.rs
@@ -241,9 +241,10 @@ unsafe fn test_simd() {
     let (zero0, zero1) = std::mem::transmute::<_, (u64, u64)>(x);
     assert_eq!((zero0, zero1), (0, 0));
     assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]);
-    assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_eq), [
-        0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
-    ]);
+    assert_eq!(
+        std::mem::transmute::<_, [u16; 8]>(cmp_eq),
+        [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff]
+    );
     assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]);
 
     test_mm_slli_si128();
diff --git a/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch b/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch
index 5a38dffa24f..f5ae66c0eb1 100644
--- a/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch
@@ -36,8 +36,8 @@ index 8402833..84592e0 100644
  #[cfg(not(miri))] // unused in Miri
  macro_rules! empty_max_mut {
 @@ -2485,6 +2486,7 @@ take_tests! {
-     (take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
-     (take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
+     (split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
+     (split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
  }
 +*/
  
diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
index bac411d1eb0..e3a9512dda9 100644
--- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
@@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644
  
  [dependencies]
  core = { path = "../core" }
--compiler_builtins = { version = "=0.1.145", features = ['rustc-dep-of-std'] }
-+compiler_builtins = { version = "=0.1.145", features = ['rustc-dep-of-std', 'no-f16-f128'] }
+-compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] }
++compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std', 'no-f16-f128'] }
  
  [dev-dependencies]
  rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index 9c6aad3490d..8d423319fa9 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2025-01-20"
+channel = "nightly-2025-02-07"
 components = ["rust-src", "rustc-dev", "llvm-tools"]
 profile = "minimal"
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
index 41aa011e805..55230a0b598 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -83,7 +83,6 @@ rm tests/ui/match/match-float.rs
 # ==================
 rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations
 rm tests/ui/codegen/init-large-type.rs # same
-rm tests/ui/issues/issue-40883.rs # same
 rm -r tests/run-make/fmt-write-bloat/ # tests an optimization
 rm tests/ui/statics/const_generics.rs # same
 
@@ -91,13 +90,11 @@ rm tests/ui/statics/const_generics.rs # same
 # ======================
 rm tests/incremental/thinlto/cgu_invalidated_when_import_{added,removed}.rs # requires LLVM
 rm -r tests/run-make/cross-lang-lto # same
-rm -r tests/run-make/sepcomp-inlining # same
-rm -r tests/run-make/sepcomp-separate # same
-rm -r tests/run-make/sepcomp-cci-copies # same
 rm -r tests/run-make/volatile-intrinsics # same
 rm -r tests/run-make/llvm-ident # same
 rm -r tests/run-make/no-builtins-attribute # same
 rm -r tests/run-make/pgo-gen-no-imp-symbols # same
+rm -r tests/run-make/llvm-location-discriminator-limit-dummy-span # same
 rm tests/ui/abi/stack-protector.rs # requires stack protector support
 rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes
 rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific
@@ -130,6 +127,7 @@ rm tests/ui/abi/large-byval-align.rs # exceeds implementation limit of Cranelift
 rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
 rm -r tests/run-make/strip # same
 rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source
+rm -r tests/run-make/translation # same
 rm -r tests/run-make/missing-unstable-trait-bound # This disables support for unstable features, but running cg_clif needs some unstable features
 rm -r tests/run-make/const-trait-stable-toolchain # same
 rm -r tests/run-make/incr-add-rust-src-component
@@ -156,8 +154,6 @@ cp $(../dist/rustc-clif --print target-libdir)/libstd-*.so ../dist/lib/
 
 # prevent $(RUSTDOC) from picking up the sysroot built by x.py. It conflicts with the one used by
 # rustdoc-clif
-# FIXME remove the bootstrap changes once it is no longer necessary to revert rust-lang/rust#130642
-# to avoid building rustc when testing stage0 run-make.
 cat <<EOF | git apply -
 diff --git a/tests/run-make/tools.mk b/tests/run-make/tools.mk
 index ea06b620c4c..b969d0009c6 100644
@@ -196,6 +192,20 @@ index e7ae773ffa1d3..04bc2d7787da7 100644
              // Provide necessary library search paths for rustc.
              .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap());
 
+diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs
+index 30387af428c..f7895b12961 100644
+--- a/tests/run-make/linker-warning/rmake.rs
++++ b/tests/run-make/linker-warning/rmake.rs
+@@ -57,7 +57,8 @@ fn main() {
+             .actual_text("(linker error)", out.stderr())
+-            .normalize(r#"/rustc[^/]*/"#, "/rustc/")
++            .normalize(r#"/tmp/rustc[^/]*/"#, "/tmp/rustc/")
++            .normalize("libpanic_abort", "libpanic_unwind")
+             .normalize(
+                 regex::escape(run_make_support::build_root().to_str().unwrap()),
+                 "/build-root",
+             )
+             .run();
 EOF
 
 echo "[TEST] rustc test suite"
diff --git a/compiler/rustc_codegen_cranelift/src/cast.rs b/compiler/rustc_codegen_cranelift/src/cast.rs
index 4463631c524..e2346324232 100644
--- a/compiler/rustc_codegen_cranelift/src/cast.rs
+++ b/compiler/rustc_codegen_cranelift/src/cast.rs
@@ -96,9 +96,12 @@ pub(crate) fn clif_int_or_float_cast(
                 },
             );
 
-            fx.lib_call(&name, vec![AbiParam::new(from_ty)], vec![AbiParam::new(types::I128)], &[
-                from,
-            ])[0]
+            fx.lib_call(
+                &name,
+                vec![AbiParam::new(from_ty)],
+                vec![AbiParam::new(types::I128)],
+                &[from],
+            )[0]
         } else if to_ty == types::I8 || to_ty == types::I16 {
             // FIXME implement fcvt_to_*int_sat.i8/i16
             let val = if to_signed {
diff --git a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs
index 2484c10848e..bf16e81a06f 100644
--- a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs
+++ b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs
@@ -44,6 +44,7 @@ builtin_functions! {
     fn __umodti3(n: u128, d: u128) -> u128;
     fn __modti3(n: i128, d: i128) -> i128;
     fn __rust_u128_mulo(a: u128, b: u128, oflow: &mut i32) -> u128;
+    fn __rust_i128_mulo(a: i128, b: i128, oflow: &mut i32) -> i128;
 
     // floats
     fn __floattisf(i: i128) -> f32;
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/object.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/object.rs
index 048a388731f..1c6e471cc87 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/object.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/object.rs
@@ -73,16 +73,19 @@ impl WriteDebugInfo for ObjectProduct {
             }
         };
         self.object
-            .add_relocation(from.0, Relocation {
-                offset: u64::from(reloc.offset),
-                symbol,
-                flags: RelocationFlags::Generic {
-                    kind: reloc.kind,
-                    encoding: RelocationEncoding::Generic,
-                    size: reloc.size * 8,
+            .add_relocation(
+                from.0,
+                Relocation {
+                    offset: u64::from(reloc.offset),
+                    symbol,
+                    flags: RelocationFlags::Generic {
+                        kind: reloc.kind,
+                        encoding: RelocationEncoding::Generic,
+                        size: reloc.size * 8,
+                    },
+                    addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
                 },
-                addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
-            })
+            )
             .unwrap();
     }
 }
diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
index 9ca930e14da..2e713171ae0 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
@@ -46,7 +46,7 @@ unsafe impl Send for UnsafeMessage {}
 
 impl UnsafeMessage {
     /// Send the message.
-    fn send(self) -> Result<(), mpsc::SendError<UnsafeMessage>> {
+    fn send(self) {
         thread_local! {
             /// The Sender owned by the local thread
             static LOCAL_MESSAGE_SENDER: mpsc::Sender<UnsafeMessage> =
@@ -55,7 +55,9 @@ impl UnsafeMessage {
                     .lock().unwrap()
                     .clone();
         }
-        LOCAL_MESSAGE_SENDER.with(|sender| sender.send(self))
+        LOCAL_MESSAGE_SENDER.with(|sender| {
+            sender.send(self).expect("rustc thread hung up before lazy JIT request was sent")
+        })
     }
 }
 
@@ -90,7 +92,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode, jit_args: Vec<
         create_jit_module(tcx, matches!(codegen_mode, CodegenMode::JitLazy));
     let mut cached_context = Context::new();
 
-    let (_, cgus) = tcx.collect_and_partition_mono_items(());
+    let cgus = tcx.collect_and_partition_mono_items(()).codegen_units;
     let mono_items = cgus
         .iter()
         .map(|cgu| cgu.items_in_deterministic_order(tcx).into_iter())
@@ -231,9 +233,7 @@ extern "C" fn clif_jit_fn(
 ) -> *const u8 {
     // send the JIT request to the rustc thread, with a channel for the response
     let (tx, rx) = mpsc::channel();
-    UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx }
-        .send()
-        .expect("rustc thread hung up before lazy JIT request was sent");
+    UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx }.send();
 
     // block on JIT compilation result
     rx.recv().expect("rustc thread hung up before responding to sent lazy JIT request")
@@ -342,11 +342,15 @@ fn codegen_shim<'tcx>(
     let instance_ptr = Box::into_raw(Box::new(inst));
 
     let jit_fn = module
-        .declare_function("__clif_jit_fn", Linkage::Import, &Signature {
-            call_conv: module.target_config().default_call_conv,
-            params: vec![AbiParam::new(pointer_type), AbiParam::new(pointer_type)],
-            returns: vec![AbiParam::new(pointer_type)],
-        })
+        .declare_function(
+            "__clif_jit_fn",
+            Linkage::Import,
+            &Signature {
+                call_conv: module.target_config().default_call_conv,
+                params: vec![AbiParam::new(pointer_type), AbiParam::new(pointer_type)],
+                returns: vec![AbiParam::new(pointer_type)],
+            },
+        )
         .unwrap();
 
     let context = cached_context;
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 6ff75f75d3b..f2b0ec977c6 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -875,11 +875,15 @@ fn call_inline_asm<'tcx>(
 
     let inline_asm_func = fx
         .module
-        .declare_function(asm_name, Linkage::Import, &Signature {
-            call_conv: CallConv::SystemV,
-            params: vec![AbiParam::new(fx.pointer_type)],
-            returns: vec![],
-        })
+        .declare_function(
+            asm_name,
+            Linkage::Import,
+            &Signature {
+                call_conv: CallConv::SystemV,
+                params: vec![AbiParam::new(fx.pointer_type)],
+                returns: vec![],
+            },
+        )
         .unwrap();
     let inline_asm_func = fx.module.declare_func_in_func(inline_asm_func, fx.bcx.func);
     if fx.clif_comments.enabled() {
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
index 39f6763d9f2..4c59c81296b 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
@@ -17,6 +17,14 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
             fx.bcx.ins().fence();
         }
 
+        "llvm.aarch64.neon.ld1x4.v16i8.p0i8" => {
+            intrinsic_args!(fx, args => (ptr); intrinsic);
+
+            let ptr = ptr.load_scalar(fx);
+            let val = CPlace::for_ptr(Pointer::new(ptr), ret.layout()).to_cvalue(fx);
+            ret.write_cvalue(fx, val);
+        }
+
         _ if intrinsic.starts_with("llvm.aarch64.neon.abs.v") => {
             intrinsic_args!(fx, args => (a); intrinsic);
 
@@ -115,6 +123,22 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
             );
         }
 
+        "llvm.aarch64.neon.uaddlv.i32.v16i8" => {
+            intrinsic_args!(fx, args => (v); intrinsic);
+
+            let mut res_val = fx.bcx.ins().iconst(types::I16, 0);
+            for lane_idx in 0..16 {
+                let lane = v.value_lane(fx, lane_idx).load_scalar(fx);
+                let lane = fx.bcx.ins().uextend(types::I16, lane);
+                res_val = fx.bcx.ins().iadd(res_val, lane);
+            }
+            let res = CValue::by_val(
+                fx.bcx.ins().uextend(types::I32, res_val),
+                fx.layout_of(fx.tcx.types.u32),
+            );
+            ret.write_cvalue(fx, res);
+        }
+
         _ if intrinsic.starts_with("llvm.aarch64.neon.faddv.f32.v") => {
             intrinsic_args!(fx, args => (v); intrinsic);
 
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index d682efd19aa..fcccda62355 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -558,9 +558,12 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                     (sym::simd_round, types::F64) => "round",
                     _ => unreachable!("{:?}", intrinsic),
                 };
-                fx.lib_call(name, vec![AbiParam::new(lane_ty)], vec![AbiParam::new(lane_ty)], &[
-                    lane,
-                ])[0]
+                fx.lib_call(
+                    name,
+                    vec![AbiParam::new(lane_ty)],
+                    vec![AbiParam::new(lane_ty)],
+                    &[lane],
+                )[0]
             });
         }
 
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index dc5d80e7a34..b0153419903 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -183,8 +183,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
     ) -> Vec<rustc_span::Symbol> {
         // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)]
         if sess.target.arch == "x86_64" && sess.target.os != "none" {
-            // x86_64 mandates SSE2 support
-            vec![sym::fsxr, sym::sse, sym::sse2]
+            // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled
+            vec![sym::fsxr, sym::sse, sym::sse2, Symbol::intern("x87")]
         } else if sess.target.arch == "aarch64" {
             match &*sess.target.os {
                 "none" => vec![],
@@ -209,7 +209,6 @@ impl CodegenBackend for CraneliftCodegenBackend {
         metadata: EncodedMetadata,
         need_metadata_module: bool,
     ) -> Box<dyn Any> {
-        tcx.dcx().abort_if_errors();
         info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE));
         let config = self.config.clone().unwrap_or_else(|| {
             BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs
index f6843496895..6d5df2b0043 100644
--- a/compiler/rustc_codegen_cranelift/src/main_shim.rs
+++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs
@@ -15,9 +15,12 @@ pub(crate) fn maybe_create_entry_wrapper(
     is_primary_cgu: bool,
 ) {
     let (main_def_id, sigpipe) = match tcx.entry_fn(()) {
-        Some((def_id, entry_ty)) => (def_id, match entry_ty {
-            EntryFnType::Main { sigpipe } => sigpipe,
-        }),
+        Some((def_id, entry_ty)) => (
+            def_id,
+            match entry_ty {
+                EntryFnType::Main { sigpipe } => sigpipe,
+            },
+        ),
         None => return,
     };
 
diff --git a/compiler/rustc_codegen_cranelift/src/trap.rs b/compiler/rustc_codegen_cranelift/src/trap.rs
index 9ef1a523d6d..ac3f58ee1ee 100644
--- a/compiler/rustc_codegen_cranelift/src/trap.rs
+++ b/compiler/rustc_codegen_cranelift/src/trap.rs
@@ -5,11 +5,15 @@ use crate::prelude::*;
 fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) {
     let puts = fx
         .module
-        .declare_function("puts", Linkage::Import, &Signature {
-            call_conv: fx.target_config.default_call_conv,
-            params: vec![AbiParam::new(fx.pointer_type)],
-            returns: vec![AbiParam::new(types::I32)],
-        })
+        .declare_function(
+            "puts",
+            Linkage::Import,
+            &Signature {
+                call_conv: fx.target_config.default_call_conv,
+                params: vec![AbiParam::new(fx.pointer_type)],
+                returns: vec![AbiParam::new(types::I32)],
+            },
+        )
         .unwrap();
     let puts = fx.module.declare_func_in_func(puts, &mut fx.bcx.func);
     if fx.clif_comments.enabled() {
diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs
index d94fc552528..717baebcd8c 100644
--- a/compiler/rustc_codegen_gcc/src/abi.rs
+++ b/compiler/rustc_codegen_gcc/src/abi.rs
@@ -1,6 +1,7 @@
 #[cfg(feature = "master")]
 use gccjit::FnAttribute;
 use gccjit::{ToLValue, ToRValue, Type};
+use rustc_abi::{Reg, RegKind};
 use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeCodegenMethods};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::bug;
@@ -8,7 +9,7 @@ use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf;
 #[cfg(feature = "master")]
 use rustc_session::config;
-use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind};
+use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode};
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs
index c9701fb9885..962f4b161d7 100644
--- a/compiler/rustc_codegen_gcc/src/base.rs
+++ b/compiler/rustc_codegen_gcc/src/base.rs
@@ -49,9 +49,7 @@ pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind {
         Linkage::LinkOnceODR => unimplemented!(),
         Linkage::WeakAny => unimplemented!(),
         Linkage::WeakODR => unimplemented!(),
-        Linkage::Appending => unimplemented!(),
         Linkage::Internal => GlobalKind::Internal,
-        Linkage::Private => GlobalKind::Internal,
         Linkage::ExternalWeak => GlobalKind::Imported, // TODO(antoyo): should be weak linkage.
         Linkage::Common => unimplemented!(),
     }
@@ -66,9 +64,7 @@ pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType {
         Linkage::LinkOnceODR => unimplemented!(),
         Linkage::WeakAny => FunctionType::Exported, // FIXME(antoyo): should be similar to linkonce.
         Linkage::WeakODR => unimplemented!(),
-        Linkage::Appending => unimplemented!(),
         Linkage::Internal => FunctionType::Internal,
-        Linkage::Private => FunctionType::Internal,
         Linkage::ExternalWeak => unimplemented!(),
         Linkage::Common => unimplemented!(),
     }
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index bba19d06258..1c3d6cc899a 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -155,14 +155,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         // NOTE: not sure why, but we have the wrong type here.
         let int_type = compare_exchange.get_param(2).to_rvalue().get_type();
         let src = self.context.new_bitcast(self.location, src, int_type);
-        self.context.new_call(self.location, compare_exchange, &[
-            dst,
-            expected,
-            src,
-            weak,
-            order,
-            failure_order,
-        ])
+        self.context.new_call(
+            self.location,
+            compare_exchange,
+            &[dst, expected, src, weak, order, failure_order],
+        )
     }
 
     pub fn assign(&self, lvalue: LValue<'gcc>, value: RValue<'gcc>) {
@@ -1076,9 +1073,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         let align = dest.val.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
         cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align));
 
-        let next = self.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[
-            self.const_usize(1),
-        ]);
+        let next = self.inbounds_gep(
+            self.backend_type(cg_elem.layout),
+            current.to_rvalue(),
+            &[self.const_usize(1)],
+        );
         self.llbb().add_assignment(self.location, current, next);
         self.br(header_bb);
 
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
index 231307def29..2d731f88d7d 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
@@ -687,11 +687,12 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
                 let field2 = builder.context.new_field(None, args[1].get_type(), "carryResult");
                 let struct_type =
                     builder.context.new_struct_type(None, "addcarryResult", &[field1, field2]);
-                return_value =
-                    builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[
-                        return_value,
-                        last_arg.dereference(None).to_rvalue(),
-                    ]);
+                return_value = builder.context.new_struct_constructor(
+                    None,
+                    struct_type.as_type(),
+                    None,
+                    &[return_value, last_arg.dereference(None).to_rvalue()],
+                );
             }
         }
         "__builtin_ia32_stmxcsr" => {
@@ -716,11 +717,12 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
             let field2 = builder.context.new_field(None, return_value.get_type(), "success");
             let struct_type =
                 builder.context.new_struct_type(None, "rdrand_result", &[field1, field2]);
-            return_value =
-                builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[
-                    random_number,
-                    success_variable.to_rvalue(),
-                ]);
+            return_value = builder.context.new_struct_constructor(
+                None,
+                struct_type.as_type(),
+                None,
+                &[random_number, success_variable.to_rvalue()],
+            );
         }
         "fma" => {
             let f16_type = builder.context.new_c_type(CType::Float16);
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 12a7dab155b..84cd5b002fb 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -62,11 +62,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     let arg_tys = sig.inputs();
 
     if name == sym::simd_select_bitmask {
-        require_simd!(arg_tys[1], InvalidMonomorphization::SimdArgument {
-            span,
-            name,
-            ty: arg_tys[1]
-        });
+        require_simd!(
+            arg_tys[1],
+            InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
+        );
         let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
 
         let expected_int_bits = (len.max(8) - 1).next_power_of_two();
@@ -140,14 +139,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
 
         let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
         require!(
             bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
             InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty }
@@ -269,23 +271,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         let lo_nibble =
             bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &lo_nibble_elements);
 
-        let mask = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &vec![
-            bx.context
-                .new_rvalue_from_int(
-                    bx.u8_type, 0x0f
-                );
-            byte_vector_type_size
-                as _
-        ]);
-
-        let four_vec = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &vec![
-                bx.context
-                    .new_rvalue_from_int(
-                        bx.u8_type, 4
-                    );
-                byte_vector_type_size
-                    as _
-            ]);
+        let mask = bx.context.new_rvalue_from_vector(
+            None,
+            long_byte_vector_type,
+            &vec![bx.context.new_rvalue_from_int(bx.u8_type, 0x0f); byte_vector_type_size as _],
+        );
+
+        let four_vec = bx.context.new_rvalue_from_vector(
+            None,
+            long_byte_vector_type,
+            &vec![bx.context.new_rvalue_from_int(bx.u8_type, 4); byte_vector_type_size as _],
+        );
 
         // Step 2: Byte-swap the input.
         let swapped = simd_bswap(bx, args[0].immediate());
@@ -388,21 +384,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
 
         let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
-        require!(out_len == n, InvalidMonomorphization::ReturnLength {
-            span,
-            name,
-            in_len: n,
-            ret_ty,
-            out_len
-        });
-        require!(in_elem == out_ty, InvalidMonomorphization::ReturnElement {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            ret_ty,
-            out_ty
-        });
+        require!(
+            out_len == n,
+            InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
+        );
+        require!(
+            in_elem == out_ty,
+            InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
+        );
 
         let vector = args[2].immediate();
 
@@ -411,13 +400,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
     #[cfg(feature = "master")]
     if name == sym::simd_insert {
-        require!(in_elem == arg_tys[2], InvalidMonomorphization::InsertedType {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            out_ty: arg_tys[2]
-        });
+        require!(
+            in_elem == arg_tys[2],
+            InvalidMonomorphization::InsertedType {
+                span,
+                name,
+                in_elem,
+                in_ty,
+                out_ty: arg_tys[2]
+            }
+        );
         let vector = args[0].immediate();
         let index = args[1].immediate();
         let value = args[2].immediate();
@@ -431,13 +423,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
     #[cfg(feature = "master")]
     if name == sym::simd_extract {
-        require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            ret_ty
-        });
+        require!(
+            ret_ty == in_elem,
+            InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+        );
         let vector = args[0].immediate();
         return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue());
     }
@@ -445,18 +434,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     if name == sym::simd_select {
         let m_elem_ty = in_elem;
         let m_len = in_len;
-        require_simd!(arg_tys[1], InvalidMonomorphization::SimdArgument {
-            span,
-            name,
-            ty: arg_tys[1]
-        });
+        require_simd!(
+            arg_tys[1],
+            InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
+        );
         let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
-        require!(m_len == v_len, InvalidMonomorphization::MismatchedLengths {
-            span,
-            name,
-            m_len,
-            v_len
-        });
+        require!(
+            m_len == v_len,
+            InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
+        );
         match *m_elem_ty.kind() {
             ty::Int(_) => {}
             _ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }),
@@ -468,25 +454,27 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
 
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match *in_elem.kind() {
             ty::RawPtr(p_ty, _) => {
                 let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
                     bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
                 });
-                require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
-                    span,
-                    name,
-                    ty: in_elem
-                });
+                require!(
+                    metadata.is_unit(),
+                    InvalidMonomorphization::CastWidePointer { span, name, ty: in_elem }
+                );
             }
             _ => {
                 return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
@@ -497,11 +485,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
                 let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
                     bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
                 });
-                require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
-                    span,
-                    name,
-                    ty: out_elem
-                });
+                require!(
+                    metadata.is_unit(),
+                    InvalidMonomorphization::CastWidePointer { span, name, ty: out_elem }
+                );
             }
             _ => {
                 return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
@@ -524,14 +511,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
 
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match *in_elem.kind() {
             ty::RawPtr(_, _) => {}
@@ -560,14 +550,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
 
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match *in_elem.kind() {
             ty::Uint(ty::UintTy::Usize) => {}
@@ -596,14 +589,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     if name == sym::simd_cast || name == sym::simd_as {
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
         // casting cares about nominal type, not just structural type
         if in_elem == out_elem {
             return Ok(args[0].immediate());
@@ -629,14 +625,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
         match (in_style, out_style) {
             (Style::Unsupported, Style::Unsupported) => {
-                require!(false, InvalidMonomorphization::UnsupportedCast {
-                    span,
-                    name,
-                    in_ty,
-                    in_elem,
-                    ret_ty,
-                    out_elem
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::UnsupportedCast {
+                        span,
+                        name,
+                        in_ty,
+                        in_elem,
+                        ret_ty,
+                        out_elem
+                    }
+                );
             }
             _ => return Ok(bx.context.convert_vector(None, args[0].immediate(), llret_ty)),
         }
@@ -914,45 +913,47 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
         // All types must be simd vector types
         require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
-        require_simd!(arg_tys[1], InvalidMonomorphization::SimdSecond {
-            span,
-            name,
-            ty: arg_tys[1]
-        });
-        require_simd!(arg_tys[2], InvalidMonomorphization::SimdThird {
-            span,
-            name,
-            ty: arg_tys[2]
-        });
+        require_simd!(
+            arg_tys[1],
+            InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
+        );
+        require_simd!(
+            arg_tys[2],
+            InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
+        );
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
 
         // Of the same length:
         let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
         let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
-        require!(in_len == out_len, InvalidMonomorphization::SecondArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[1],
-            out_len
-        });
-        require!(in_len == out_len2, InvalidMonomorphization::ThirdArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[2],
-            out_len: out_len2
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::SecondArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[1],
+                out_len
+            }
+        );
+        require!(
+            in_len == out_len2,
+            InvalidMonomorphization::ThirdArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[2],
+                out_len: out_len2
+            }
+        );
 
         // The return type must match the first argument type
-        require!(ret_ty == in_ty, InvalidMonomorphization::ExpectedReturnType {
-            span,
-            name,
-            in_ty,
-            ret_ty
-        });
+        require!(
+            ret_ty == in_ty,
+            InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty }
+        );
 
         // This counts how many pointers
         fn ptr_count(t: Ty<'_>) -> usize {
@@ -979,15 +980,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
                 (ptr_count(element_ty1), non_ptr(element_ty1))
             }
             _ => {
-                require!(false, InvalidMonomorphization::ExpectedElementType {
-                    span,
-                    name,
-                    expected_element: element_ty1,
-                    second_arg: arg_tys[1],
-                    in_elem,
-                    in_ty,
-                    mutability: ExpectedPointerMutability::Not,
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::ExpectedElementType {
+                        span,
+                        name,
+                        expected_element: element_ty1,
+                        second_arg: arg_tys[1],
+                        in_elem,
+                        in_ty,
+                        mutability: ExpectedPointerMutability::Not,
+                    }
+                );
                 unreachable!();
             }
         };
@@ -1000,12 +1004,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         match *element_ty2.kind() {
             ty::Int(_) => (),
             _ => {
-                require!(false, InvalidMonomorphization::ThirdArgElementType {
-                    span,
-                    name,
-                    expected_element: element_ty2,
-                    third_arg: arg_tys[2]
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::ThirdArgElementType {
+                        span,
+                        name,
+                        expected_element: element_ty2,
+                        third_arg: arg_tys[2]
+                    }
+                );
             }
         }
 
@@ -1029,36 +1036,40 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
         // All types must be simd vector types
         require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
-        require_simd!(arg_tys[1], InvalidMonomorphization::SimdSecond {
-            span,
-            name,
-            ty: arg_tys[1]
-        });
-        require_simd!(arg_tys[2], InvalidMonomorphization::SimdThird {
-            span,
-            name,
-            ty: arg_tys[2]
-        });
+        require_simd!(
+            arg_tys[1],
+            InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
+        );
+        require_simd!(
+            arg_tys[2],
+            InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
+        );
 
         // Of the same length:
         let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx());
         let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
-        require!(in_len == element_len1, InvalidMonomorphization::SecondArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[1],
-            out_len: element_len1
-        });
-        require!(in_len == element_len2, InvalidMonomorphization::ThirdArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[2],
-            out_len: element_len2
-        });
+        require!(
+            in_len == element_len1,
+            InvalidMonomorphization::SecondArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[1],
+                out_len: element_len1
+            }
+        );
+        require!(
+            in_len == element_len2,
+            InvalidMonomorphization::ThirdArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[2],
+                out_len: element_len2
+            }
+        );
 
         // This counts how many pointers
         fn ptr_count(t: Ty<'_>) -> usize {
@@ -1086,15 +1097,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
                 (ptr_count(element_ty1), non_ptr(element_ty1))
             }
             _ => {
-                require!(false, InvalidMonomorphization::ExpectedElementType {
-                    span,
-                    name,
-                    expected_element: element_ty1,
-                    second_arg: arg_tys[1],
-                    in_elem,
-                    in_ty,
-                    mutability: ExpectedPointerMutability::Mut,
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::ExpectedElementType {
+                        span,
+                        name,
+                        expected_element: element_ty1,
+                        second_arg: arg_tys[1],
+                        in_elem,
+                        in_ty,
+                        mutability: ExpectedPointerMutability::Mut,
+                    }
+                );
                 unreachable!();
             }
         };
@@ -1106,12 +1120,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         match *element_ty2.kind() {
             ty::Int(_) => (),
             _ => {
-                require!(false, InvalidMonomorphization::ThirdArgElementType {
-                    span,
-                    name,
-                    expected_element: element_ty2,
-                    third_arg: arg_tys[2]
-                });
+                require!(
+                    false,
+                    InvalidMonomorphization::ThirdArgElementType {
+                        span,
+                        name,
+                        expected_element: element_ty2,
+                        third_arg: arg_tys[2]
+                    }
+                );
             }
         }
 
@@ -1278,13 +1295,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         ($name:ident : $vec_op:expr, $float_reduce:ident, $ordered:expr, $op:ident,
          $identity:expr) => {
             if name == sym::$name {
-                require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                    span,
-                    name,
-                    in_elem,
-                    in_ty,
-                    ret_ty
-                });
+                require!(
+                    ret_ty == in_elem,
+                    InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                );
                 return match *in_elem.kind() {
                     ty::Int(_) | ty::Uint(_) => {
                         let r = bx.vector_reduce_op(args[0].immediate(), $vec_op);
@@ -1350,13 +1364,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     macro_rules! minmax_red {
         ($name:ident: $int_red:ident, $float_red:ident) => {
             if name == sym::$name {
-                require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                    span,
-                    name,
-                    in_elem,
-                    in_ty,
-                    ret_ty
-                });
+                require!(
+                    ret_ty == in_elem,
+                    InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                );
                 return match *in_elem.kind() {
                     ty::Int(_) | ty::Uint(_) => Ok(bx.$int_red(args[0].immediate())),
                     ty::Float(_) => Ok(bx.$float_red(args[0].immediate())),
@@ -1380,13 +1391,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         ($name:ident : $op:expr, $boolean:expr) => {
             if name == sym::$name {
                 let input = if !$boolean {
-                    require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                        span,
-                        name,
-                        in_elem,
-                        in_ty,
-                        ret_ty
-                    });
+                    require!(
+                        ret_ty == in_elem,
+                        InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                    );
                     args[0].immediate()
                 } else {
                     match *in_elem.kind() {
diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs
index 239902df7f0..a2df7b2596f 100644
--- a/compiler/rustc_codegen_gcc/src/mono_item.rs
+++ b/compiler/rustc_codegen_gcc/src/mono_item.rs
@@ -61,10 +61,7 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         // compiler-rt, then we want to implicitly compile everything with hidden
         // visibility as we're going to link this object all over the place but
         // don't want the symbols to get exported.
-        if linkage != Linkage::Internal
-            && linkage != Linkage::Private
-            && self.tcx.is_compiler_builtins(LOCAL_CRATE)
-        {
+        if linkage != Linkage::Internal && self.tcx.is_compiler_builtins(LOCAL_CRATE) {
             #[cfg(feature = "master")]
             decl.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
         } else {
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 31ee0eeca11..685b2f37c9c 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -4,8 +4,7 @@ use std::cmp;
 use libc::c_uint;
 use rustc_abi as abi;
 pub(crate) use rustc_abi::ExternAbi;
-use rustc_abi::Primitive::Int;
-use rustc_abi::{HasDataLayout, Size};
+use rustc_abi::{HasDataLayout, Primitive, Reg, RegKind, Size};
 use rustc_codegen_ssa::MemFlags;
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
@@ -440,7 +439,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
         let apply_range_attr = |idx: AttributePlace, scalar: rustc_abi::Scalar| {
             if cx.sess().opts.optimize != config::OptLevel::No
                 && llvm_util::get_version() >= (19, 0, 0)
-                && matches!(scalar.primitive(), Int(..))
+                && matches!(scalar.primitive(), Primitive::Int(..))
                 // If the value is a boolean, the range is 0..2 and that ultimately
                 // become 0..0 when the type becomes i1, which would be rejected
                 // by the LLVM verifier.
@@ -448,11 +447,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
                 // LLVM also rejects full range.
                 && !scalar.is_always_valid(cx)
             {
-                attributes::apply_to_llfn(llfn, idx, &[llvm::CreateRangeAttr(
-                    cx.llcx,
-                    scalar.size(cx),
-                    scalar.valid_range(cx),
-                )]);
+                attributes::apply_to_llfn(
+                    llfn,
+                    idx,
+                    &[llvm::CreateRangeAttr(cx.llcx, scalar.size(cx), scalar.valid_range(cx))],
+                );
             }
         };
 
@@ -472,10 +471,14 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
                 );
                 attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]);
                 if cx.sess().opts.optimize != config::OptLevel::No {
-                    attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[
-                        llvm::AttributeKind::Writable.create_attr(cx.llcx),
-                        llvm::AttributeKind::DeadOnUnwind.create_attr(cx.llcx),
-                    ]);
+                    attributes::apply_to_llfn(
+                        llfn,
+                        llvm::AttributePlace::Argument(i),
+                        &[
+                            llvm::AttributeKind::Writable.create_attr(cx.llcx),
+                            llvm::AttributeKind::DeadOnUnwind.create_attr(cx.llcx),
+                        ],
+                    );
                 }
             }
             PassMode::Cast { cast, pad_i32: _ } => {
@@ -574,7 +577,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
         if bx.cx.sess().opts.optimize != config::OptLevel::No
                 && llvm_util::get_version() < (19, 0, 0)
                 && let abi::BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr
-                && matches!(scalar.primitive(), Int(..))
+                && matches!(scalar.primitive(), Primitive::Int(..))
                 // If the value is a boolean, the range is 0..2 and that ultimately
                 // become 0..0 when the type becomes i1, which would be rejected
                 // by the LLVM verifier.
@@ -593,9 +596,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
                         bx.cx.llcx,
                         bx.cx.type_array(bx.cx.type_i8(), arg.layout.size.bytes()),
                     );
-                    attributes::apply_to_callsite(callsite, llvm::AttributePlace::Argument(i), &[
-                        byval,
-                    ]);
+                    attributes::apply_to_callsite(
+                        callsite,
+                        llvm::AttributePlace::Argument(i),
+                        &[byval],
+                    );
                 }
                 PassMode::Direct(attrs)
                 | PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => {
@@ -627,9 +632,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
             // This will probably get ignored on all targets but those supporting the TrustZone-M
             // extension (thumbv8m targets).
             let cmse_nonsecure_call = llvm::CreateAttrString(bx.cx.llcx, "cmse_nonsecure_call");
-            attributes::apply_to_callsite(callsite, llvm::AttributePlace::Function, &[
-                cmse_nonsecure_call,
-            ]);
+            attributes::apply_to_callsite(
+                callsite,
+                llvm::AttributePlace::Function,
+                &[cmse_nonsecure_call],
+            );
         }
 
         // Some intrinsics require that an elementtype attribute (with the pointee type of a
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 78c759bbe8c..8bad437eeb7 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -606,10 +606,31 @@ pub(crate) fn run_pass_manager(
 
     // If this rustc version was build with enzyme/autodiff enabled, and if users applied the
     // `#[autodiff]` macro at least once, then we will later call llvm_optimize a second time.
-    let first_run = true;
     debug!("running llvm pm opt pipeline");
     unsafe {
-        write::llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, first_run)?;
+        write::llvm_optimize(
+            cgcx,
+            dcx,
+            module,
+            config,
+            opt_level,
+            opt_stage,
+            write::AutodiffStage::DuringAD,
+        )?;
+    }
+    // FIXME(ZuseZ4): Make this more granular
+    if cfg!(llvm_enzyme) && !thin {
+        unsafe {
+            write::llvm_optimize(
+                cgcx,
+                dcx,
+                module,
+                config,
+                opt_level,
+                llvm::OptStage::FatLTO,
+                write::AutodiffStage::PostAD,
+            )?;
+        }
     }
     debug!("lto done");
     Ok(())
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 4706744f353..ae4c4d5876e 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -530,6 +530,16 @@ fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
     config.instrument_coverage.then(|| c"default_%m_%p.profraw".to_owned())
 }
 
+// PreAD will run llvm opts but disable size increasing opts (vectorization, loop unrolling)
+// DuringAD is the same as above, but also runs the enzyme opt and autodiff passes.
+// PostAD will run all opts, including size increasing opts.
+#[derive(Debug, Eq, PartialEq)]
+pub(crate) enum AutodiffStage {
+    PreAD,
+    DuringAD,
+    PostAD,
+}
+
 pub(crate) unsafe fn llvm_optimize(
     cgcx: &CodegenContext<LlvmCodegenBackend>,
     dcx: DiagCtxtHandle<'_>,
@@ -537,7 +547,7 @@ pub(crate) unsafe fn llvm_optimize(
     config: &ModuleConfig,
     opt_level: config::OptLevel,
     opt_stage: llvm::OptStage,
-    skip_size_increasing_opts: bool,
+    autodiff_stage: AutodiffStage,
 ) -> Result<(), FatalError> {
     // Enzyme:
     // The whole point of compiler based AD is to differentiate optimized IR instead of unoptimized
@@ -550,12 +560,16 @@ pub(crate) unsafe fn llvm_optimize(
     let unroll_loops;
     let vectorize_slp;
     let vectorize_loop;
+    let run_enzyme = cfg!(llvm_enzyme) && autodiff_stage == AutodiffStage::DuringAD;
 
     // When we build rustc with enzyme/autodiff support, we want to postpone size-increasing
-    // optimizations until after differentiation. FIXME(ZuseZ4): Before shipping on nightly,
+    // optimizations until after differentiation. Our pipeline is thus: (opt + enzyme), (full opt).
+    // We therefore have two calls to llvm_optimize, if autodiff is used.
+    //
+    // FIXME(ZuseZ4): Before shipping on nightly,
     // we should make this more granular, or at least check that the user has at least one autodiff
     // call in their code, to justify altering the compilation pipeline.
-    if skip_size_increasing_opts && cfg!(llvm_enzyme) {
+    if cfg!(llvm_enzyme) && autodiff_stage != AutodiffStage::PostAD {
         unroll_loops = false;
         vectorize_slp = false;
         vectorize_loop = false;
@@ -565,7 +579,7 @@ pub(crate) unsafe fn llvm_optimize(
         vectorize_slp = config.vectorize_slp;
         vectorize_loop = config.vectorize_loop;
     }
-    trace!(?unroll_loops, ?vectorize_slp, ?vectorize_loop);
+    trace!(?unroll_loops, ?vectorize_slp, ?vectorize_loop, ?run_enzyme);
     let using_thin_buffers = opt_stage == llvm::OptStage::PreLinkThinLTO || config.bitcode_needed();
     let pgo_gen_path = get_pgo_gen_path(config);
     let pgo_use_path = get_pgo_use_path(config);
@@ -633,6 +647,7 @@ pub(crate) unsafe fn llvm_optimize(
             vectorize_loop,
             config.no_builtins,
             config.emit_lifetime_markers,
+            run_enzyme,
             sanitizer_options.as_ref(),
             pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
             pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
@@ -684,18 +699,14 @@ pub(crate) unsafe fn optimize(
             _ => llvm::OptStage::PreLinkNoLTO,
         };
 
-        // If we know that we will later run AD, then we disable vectorization and loop unrolling
-        let skip_size_increasing_opts = cfg!(llvm_enzyme);
+        // If we know that we will later run AD, then we disable vectorization and loop unrolling.
+        // Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD).
+        // FIXME(ZuseZ4): Make this more granular, only set PreAD if we actually have autodiff
+        // usages, not just if we build rustc with autodiff support.
+        let autodiff_stage =
+            if cfg!(llvm_enzyme) { AutodiffStage::PreAD } else { AutodiffStage::PostAD };
         return unsafe {
-            llvm_optimize(
-                cgcx,
-                dcx,
-                module,
-                config,
-                opt_level,
-                opt_stage,
-                skip_size_increasing_opts,
-            )
+            llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, autodiff_stage)
         };
     }
     Ok(())
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index d05faf5577b..d35c7945bae 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -157,9 +157,7 @@ pub(crate) fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
         Linkage::LinkOnceODR => llvm::Linkage::LinkOnceODRLinkage,
         Linkage::WeakAny => llvm::Linkage::WeakAnyLinkage,
         Linkage::WeakODR => llvm::Linkage::WeakODRLinkage,
-        Linkage::Appending => llvm::Linkage::AppendingLinkage,
         Linkage::Internal => llvm::Linkage::InternalLinkage,
-        Linkage::Private => llvm::Linkage::PrivateLinkage,
         Linkage::ExternalWeak => llvm::Linkage::ExternalWeakLinkage,
         Linkage::Common => llvm::Linkage::CommonLinkage,
     }
diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
index 9e8e4e1c567..b2c1088e3fc 100644
--- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
+++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
@@ -4,10 +4,9 @@ use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, AutoDiffItem, DiffActivit
 use rustc_codegen_ssa::ModuleCodegen;
 use rustc_codegen_ssa::back::write::ModuleConfig;
 use rustc_errors::FatalError;
-use rustc_session::config::Lto;
 use tracing::{debug, trace};
 
-use crate::back::write::{llvm_err, llvm_optimize};
+use crate::back::write::llvm_err;
 use crate::builder::SBuilder;
 use crate::context::SimpleCx;
 use crate::declare::declare_simple_fn;
@@ -53,8 +52,6 @@ fn generate_enzyme_call<'ll>(
     let mut ad_name: String = match attrs.mode {
         DiffMode::Forward => "__enzyme_fwddiff",
         DiffMode::Reverse => "__enzyme_autodiff",
-        DiffMode::ForwardFirst => "__enzyme_fwddiff",
-        DiffMode::ReverseFirst => "__enzyme_autodiff",
         _ => panic!("logic bug in autodiff, unrecognized mode"),
     }
     .to_string();
@@ -153,7 +150,7 @@ fn generate_enzyme_call<'ll>(
             _ => {}
         }
 
-        trace!("matching autodiff arguments");
+        debug!("matching autodiff arguments");
         // We now handle the issue that Rust level arguments not always match the llvm-ir level
         // arguments. A slice, `&[f32]`, for example, is represented as a pointer and a length on
         // llvm-ir level. The number of activities matches the number of Rust level arguments, so we
@@ -164,10 +161,10 @@ fn generate_enzyme_call<'ll>(
         let mut activity_pos = 0;
         let outer_args: Vec<&llvm::Value> = get_params(outer_fn);
         while activity_pos < inputs.len() {
-            let activity = inputs[activity_pos as usize];
+            let diff_activity = inputs[activity_pos as usize];
             // Duplicated arguments received a shadow argument, into which enzyme will write the
             // gradient.
-            let (activity, duplicated): (&Metadata, bool) = match activity {
+            let (activity, duplicated): (&Metadata, bool) = match diff_activity {
                 DiffActivity::None => panic!("not a valid input activity"),
                 DiffActivity::Const => (enzyme_const, false),
                 DiffActivity::Active => (enzyme_out, false),
@@ -222,7 +219,15 @@ fn generate_enzyme_call<'ll>(
                     // A duplicated pointer will have the following two outer_fn arguments:
                     // (..., ptr, ptr, ...). We add the following llvm-ir to our __enzyme call:
                     // (..., metadata! enzyme_dup, ptr, ptr, ...).
-                    assert!(llvm::LLVMRustGetTypeKind(next_outer_ty) == llvm::TypeKind::Pointer);
+                    if matches!(
+                        diff_activity,
+                        DiffActivity::Duplicated | DiffActivity::DuplicatedOnly
+                    ) {
+                        assert!(
+                            llvm::LLVMRustGetTypeKind(next_outer_ty) == llvm::TypeKind::Pointer
+                        );
+                    }
+                    // In the case of Dual we don't have assumptions, e.g. f32 would be valid.
                     args.push(next_outer_arg);
                     outer_pos += 2;
                     activity_pos += 1;
@@ -277,7 +282,7 @@ pub(crate) fn differentiate<'ll>(
     module: &'ll ModuleCodegen<ModuleLlvm>,
     cgcx: &CodegenContext<LlvmCodegenBackend>,
     diff_items: Vec<AutoDiffItem>,
-    config: &ModuleConfig,
+    _config: &ModuleConfig,
 ) -> Result<(), FatalError> {
     for item in &diff_items {
         trace!("{}", item);
@@ -291,20 +296,26 @@ pub(crate) fn differentiate<'ll>(
         let name = item.source.clone();
         let fn_def: Option<&llvm::Value> = cx.get_function(&name);
         let Some(fn_def) = fn_def else {
-            return Err(llvm_err(diag_handler.handle(), LlvmError::PrepareAutoDiff {
-                src: item.source.clone(),
-                target: item.target.clone(),
-                error: "could not find source function".to_owned(),
-            }));
+            return Err(llvm_err(
+                diag_handler.handle(),
+                LlvmError::PrepareAutoDiff {
+                    src: item.source.clone(),
+                    target: item.target.clone(),
+                    error: "could not find source function".to_owned(),
+                },
+            ));
         };
         debug!(?item.target);
         let fn_target: Option<&llvm::Value> = cx.get_function(&item.target);
         let Some(fn_target) = fn_target else {
-            return Err(llvm_err(diag_handler.handle(), LlvmError::PrepareAutoDiff {
-                src: item.source.clone(),
-                target: item.target.clone(),
-                error: "could not find target function".to_owned(),
-            }));
+            return Err(llvm_err(
+                diag_handler.handle(),
+                LlvmError::PrepareAutoDiff {
+                    src: item.source.clone(),
+                    target: item.target.clone(),
+                    error: "could not find target function".to_owned(),
+                },
+            ));
         };
 
         generate_enzyme_call(&cx, fn_def, fn_target, item.attrs.clone());
@@ -312,29 +323,6 @@ pub(crate) fn differentiate<'ll>(
 
     // FIXME(ZuseZ4): support SanitizeHWAddress and prevent illegal/unsupported opts
 
-    if let Some(opt_level) = config.opt_level {
-        let opt_stage = match cgcx.lto {
-            Lto::Fat => llvm::OptStage::PreLinkFatLTO,
-            Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
-            _ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
-            _ => llvm::OptStage::PreLinkNoLTO,
-        };
-        // This is our second opt call, so now we run all opts,
-        // to make sure we get the best performance.
-        let skip_size_increasing_opts = false;
-        trace!("running Module Optimization after differentiation");
-        unsafe {
-            llvm_optimize(
-                cgcx,
-                diag_handler.handle(),
-                module,
-                config,
-                opt_level,
-                opt_stage,
-                skip_size_increasing_opts,
-            )?
-        };
-    }
     trace!("done with differentiate()");
 
     Ok(())
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
index 460a4664615..c53ea6d4666 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
@@ -11,7 +11,8 @@ use rustc_codegen_ssa::traits::{
     BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
 };
 use rustc_middle::mir::coverage::{
-    CovTerm, CoverageIdsInfo, Expression, FunctionCoverageInfo, Mapping, MappingKind, Op,
+    BasicCoverageBlock, CovTerm, CoverageIdsInfo, Expression, FunctionCoverageInfo, Mapping,
+    MappingKind, Op,
 };
 use rustc_middle::ty::{Instance, TyCtxt};
 use rustc_span::Span;
@@ -53,7 +54,7 @@ pub(crate) fn prepare_covfun_record<'tcx>(
     let fn_cov_info = tcx.instance_mir(instance.def).function_coverage_info.as_deref()?;
     let ids_info = tcx.coverage_ids_info(instance.def)?;
 
-    let expressions = prepare_expressions(fn_cov_info, ids_info, is_used);
+    let expressions = prepare_expressions(ids_info);
 
     let mut covfun = CovfunRecord {
         mangled_function_name: tcx.symbol_name(instance).name,
@@ -75,26 +76,14 @@ pub(crate) fn prepare_covfun_record<'tcx>(
 }
 
 /// Convert the function's coverage-counter expressions into a form suitable for FFI.
-fn prepare_expressions(
-    fn_cov_info: &FunctionCoverageInfo,
-    ids_info: &CoverageIdsInfo,
-    is_used: bool,
-) -> Vec<ffi::CounterExpression> {
-    // If any counters or expressions were removed by MIR opts, replace their
-    // terms with zero.
-    let counter_for_term = |term| {
-        if !is_used || ids_info.is_zero_term(term) {
-            ffi::Counter::ZERO
-        } else {
-            ffi::Counter::from_term(term)
-        }
-    };
+fn prepare_expressions(ids_info: &CoverageIdsInfo) -> Vec<ffi::CounterExpression> {
+    let counter_for_term = ffi::Counter::from_term;
 
     // We know that LLVM will optimize out any unused expressions before
     // producing the final coverage map, so there's no need to do the same
     // thing on the Rust side unless we're confident we can do much better.
     // (See `CounterExpressionsMinimizer` in `CoverageMappingWriter.cpp`.)
-    fn_cov_info
+    ids_info
         .expressions
         .iter()
         .map(move |&Expression { lhs, op, rhs }| ffi::CounterExpression {
@@ -136,11 +125,16 @@ fn fill_region_tables<'tcx>(
 
     // For each counter/region pair in this function+file, convert it to a
     // form suitable for FFI.
-    let is_zero_term = |term| !covfun.is_used || ids_info.is_zero_term(term);
     for &Mapping { ref kind, span } in &fn_cov_info.mappings {
-        // If the mapping refers to counters/expressions that were removed by
-        // MIR opts, replace those occurrences with zero.
-        let kind = kind.map_terms(|term| if is_zero_term(term) { CovTerm::Zero } else { term });
+        // If this function is unused, replace all counters with zero.
+        let counter_for_bcb = |bcb: BasicCoverageBlock| -> ffi::Counter {
+            let term = if covfun.is_used {
+                ids_info.term_for_bcb[bcb].expect("every BCB in a mapping was given a term")
+            } else {
+                CovTerm::Zero
+            };
+            ffi::Counter::from_term(term)
+        };
 
         // Convert the `Span` into coordinates that we can pass to LLVM, or
         // discard the span if conversion fails. In rare, cases _all_ of a
@@ -154,23 +148,22 @@ fn fill_region_tables<'tcx>(
             continue;
         }
 
-        match kind {
-            MappingKind::Code(term) => {
-                code_regions
-                    .push(ffi::CodeRegion { cov_span, counter: ffi::Counter::from_term(term) });
+        match *kind {
+            MappingKind::Code { bcb } => {
+                code_regions.push(ffi::CodeRegion { cov_span, counter: counter_for_bcb(bcb) });
             }
-            MappingKind::Branch { true_term, false_term } => {
+            MappingKind::Branch { true_bcb, false_bcb } => {
                 branch_regions.push(ffi::BranchRegion {
                     cov_span,
-                    true_counter: ffi::Counter::from_term(true_term),
-                    false_counter: ffi::Counter::from_term(false_term),
+                    true_counter: counter_for_bcb(true_bcb),
+                    false_counter: counter_for_bcb(false_bcb),
                 });
             }
-            MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => {
+            MappingKind::MCDCBranch { true_bcb, false_bcb, mcdc_params } => {
                 mcdc_branch_regions.push(ffi::MCDCBranchRegion {
                     cov_span,
-                    true_counter: ffi::Counter::from_term(true_term),
-                    false_counter: ffi::Counter::from_term(false_term),
+                    true_counter: counter_for_bcb(true_bcb),
+                    false_counter: counter_for_bcb(false_bcb),
                     mcdc_branch_params: ffi::mcdc::BranchParameters::from(mcdc_params),
                 });
             }
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 021108cd51c..ea7f581a3cb 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -160,21 +160,12 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
             CoverageKind::SpanMarker | CoverageKind::BlockMarker { .. } => unreachable!(
                 "marker statement {kind:?} should have been removed by CleanupPostBorrowck"
             ),
-            CoverageKind::CounterIncrement { id } => {
-                // The number of counters passed to `llvm.instrprof.increment` might
-                // be smaller than the number originally inserted by the instrumentor,
-                // if some high-numbered counters were removed by MIR optimizations.
-                // If so, LLVM's profiler runtime will use fewer physical counters.
-                let num_counters = ids_info.num_counters_after_mir_opts();
-                assert!(
-                    num_counters as usize <= function_coverage_info.num_counters,
-                    "num_counters disagreement: query says {num_counters} but function info only has {}",
-                    function_coverage_info.num_counters
-                );
-
+            CoverageKind::VirtualCounter { bcb }
+                if let Some(&id) = ids_info.phys_counter_for_node.get(&bcb) =>
+            {
                 let fn_name = bx.get_pgo_func_name_var(instance);
                 let hash = bx.const_u64(function_coverage_info.function_source_hash);
-                let num_counters = bx.const_u32(num_counters);
+                let num_counters = bx.const_u32(ids_info.num_counters);
                 let index = bx.const_u32(id.as_u32());
                 debug!(
                     "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
@@ -182,10 +173,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
                 );
                 bx.instrprof_increment(fn_name, hash, num_counters, index);
             }
-            CoverageKind::ExpressionUsed { id: _ } => {
-                // Expression-used statements are markers that are handled by
-                // `coverage_ids_info`, so there's nothing to codegen here.
-            }
+            // If a BCB doesn't have an associated physical counter, there's nothing to codegen.
+            CoverageKind::VirtualCounter { .. } => {}
             CoverageKind::CondBitmapUpdate { index, decision_depth } => {
                 let cond_bitmap = coverage_cx
                     .try_get_mcdc_condition_bitmap(&instance, decision_depth)
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index f497ba95661..59c3fe635d0 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -319,19 +319,16 @@ fn build_subroutine_type_di_node<'ll, 'tcx>(
     // This is actually a function pointer, so wrap it in pointer DI.
     let name = compute_debuginfo_type_name(cx.tcx, fn_ty, false);
     let (size, align) = match fn_ty.kind() {
-        ty::FnDef(..) => (0, 1),
-        ty::FnPtr(..) => (
-            cx.tcx.data_layout.pointer_size.bits(),
-            cx.tcx.data_layout.pointer_align.abi.bits() as u32,
-        ),
+        ty::FnDef(..) => (Size::ZERO, Align::ONE),
+        ty::FnPtr(..) => (cx.tcx.data_layout.pointer_size, cx.tcx.data_layout.pointer_align.abi),
         _ => unreachable!(),
     };
     let di_node = unsafe {
         llvm::LLVMRustDIBuilderCreatePointerType(
             DIB(cx),
             fn_di_node,
-            size,
-            align,
+            size.bits(),
+            align.bits() as u32,
             0, // Ignore DWARF address space.
             name.as_c_char_ptr(),
             name.len(),
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 6a3e7403b65..17f2d5f4e73 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -548,14 +548,17 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                 }
             }
 
-            let scope = namespace::item_namespace(cx, DefId {
-                krate: instance.def_id().krate,
-                index: cx
-                    .tcx
-                    .def_key(instance.def_id())
-                    .parent
-                    .expect("get_containing_scope: missing parent?"),
-            });
+            let scope = namespace::item_namespace(
+                cx,
+                DefId {
+                    krate: instance.def_id().krate,
+                    index: cx
+                        .tcx
+                        .def_key(instance.def_id())
+                        .parent
+                        .expect("get_containing_scope: missing parent?"),
+                },
+            );
             (scope, false)
         }
     }
@@ -637,7 +640,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                 true,
                 DIFlags::FlagZero,
                 argument_index,
-                align.bytes() as u32,
+                align.bits() as u32,
             )
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 43d6ccfcb4a..3200c94d977 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -333,12 +333,15 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     sym::prefetch_write_instruction => (1, 0),
                     _ => bug!(),
                 };
-                self.call_intrinsic("llvm.prefetch", &[
-                    args[0].immediate(),
-                    self.const_i32(rw),
-                    args[1].immediate(),
-                    self.const_i32(cache_type),
-                ])
+                self.call_intrinsic(
+                    "llvm.prefetch",
+                    &[
+                        args[0].immediate(),
+                        self.const_i32(rw),
+                        args[1].immediate(),
+                        self.const_i32(cache_type),
+                    ],
+                )
             }
             sym::carrying_mul_add => {
                 let (size, signed) = fn_args.type_at(0).int_size_and_signed(self.tcx);
@@ -396,10 +399,10 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 match name {
                     sym::ctlz | sym::cttz => {
                         let y = self.const_bool(false);
-                        let ret = self.call_intrinsic(&format!("llvm.{name}.i{width}"), &[
-                            args[0].immediate(),
-                            y,
-                        ]);
+                        let ret = self.call_intrinsic(
+                            &format!("llvm.{name}.i{width}"),
+                            &[args[0].immediate(), y],
+                        );
 
                         self.intcast(ret, llret_ty, false)
                     }
@@ -416,24 +419,26 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                         self.intcast(ret, llret_ty, false)
                     }
                     sym::ctpop => {
-                        let ret = self.call_intrinsic(&format!("llvm.ctpop.i{width}"), &[
-                            args[0].immediate()
-                        ]);
+                        let ret = self.call_intrinsic(
+                            &format!("llvm.ctpop.i{width}"),
+                            &[args[0].immediate()],
+                        );
                         self.intcast(ret, llret_ty, false)
                     }
                     sym::bswap => {
                         if width == 8 {
                             args[0].immediate() // byte swap a u8/i8 is just a no-op
                         } else {
-                            self.call_intrinsic(&format!("llvm.bswap.i{width}"), &[
-                                args[0].immediate()
-                            ])
+                            self.call_intrinsic(
+                                &format!("llvm.bswap.i{width}"),
+                                &[args[0].immediate()],
+                            )
                         }
                     }
-                    sym::bitreverse => self
-                        .call_intrinsic(&format!("llvm.bitreverse.i{width}"), &[
-                            args[0].immediate()
-                        ]),
+                    sym::bitreverse => self.call_intrinsic(
+                        &format!("llvm.bitreverse.i{width}"),
+                        &[args[0].immediate()],
+                    ),
                     sym::rotate_left | sym::rotate_right => {
                         let is_left = name == sym::rotate_left;
                         let val = args[0].immediate();
@@ -500,11 +505,10 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
 
             sym::compare_bytes => {
                 // Here we assume that the `memcmp` provided by the target is a NOP for size 0.
-                let cmp = self.call_intrinsic("memcmp", &[
-                    args[0].immediate(),
-                    args[1].immediate(),
-                    args[2].immediate(),
-                ]);
+                let cmp = self.call_intrinsic(
+                    "memcmp",
+                    &[args[0].immediate(), args[1].immediate(), args[2].immediate()],
+                );
                 // Some targets have `memcmp` returning `i16`, but the intrinsic is always `i32`.
                 self.sext(cmp, self.type_ix(32))
             }
@@ -1305,14 +1309,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     if let Some(cmp_op) = comparison {
         let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
 
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
         require!(
             bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
             InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty }
@@ -1333,21 +1340,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         let n = idx.len() as u64;
 
         let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
-        require!(out_len == n, InvalidMonomorphization::ReturnLength {
-            span,
-            name,
-            in_len: n,
-            ret_ty,
-            out_len
-        });
-        require!(in_elem == out_ty, InvalidMonomorphization::ReturnElement {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            ret_ty,
-            out_ty
-        });
+        require!(
+            out_len == n,
+            InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
+        );
+        require!(
+            in_elem == out_ty,
+            InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
+        );
 
         let total_len = in_len * 2;
 
@@ -1392,21 +1392,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         };
 
         let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
-        require!(out_len == n, InvalidMonomorphization::ReturnLength {
-            span,
-            name,
-            in_len: n,
-            ret_ty,
-            out_len
-        });
-        require!(in_elem == out_ty, InvalidMonomorphization::ReturnElement {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            ret_ty,
-            out_ty
-        });
+        require!(
+            out_len == n,
+            InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
+        );
+        require!(
+            in_elem == out_ty,
+            InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
+        );
 
         let total_len = u128::from(in_len) * 2;
 
@@ -1431,13 +1424,16 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     }
 
     if name == sym::simd_insert {
-        require!(in_elem == arg_tys[2], InvalidMonomorphization::InsertedType {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            out_ty: arg_tys[2]
-        });
+        require!(
+            in_elem == arg_tys[2],
+            InvalidMonomorphization::InsertedType {
+                span,
+                name,
+                in_elem,
+                in_ty,
+                out_ty: arg_tys[2]
+            }
+        );
         let idx = bx
             .const_to_opt_u128(args[1].immediate(), false)
             .expect("typeck should have ensure that this is a const");
@@ -1456,13 +1452,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         ));
     }
     if name == sym::simd_extract {
-        require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-            span,
-            name,
-            in_elem,
-            in_ty,
-            ret_ty
-        });
+        require!(
+            ret_ty == in_elem,
+            InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+        );
         let idx = bx
             .const_to_opt_u128(args[1].immediate(), false)
             .expect("typeck should have ensure that this is a const");
@@ -1481,18 +1474,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         let m_elem_ty = in_elem;
         let m_len = in_len;
         let (v_len, _) = require_simd!(arg_tys[1], SimdArgument);
-        require!(m_len == v_len, InvalidMonomorphization::MismatchedLengths {
-            span,
-            name,
-            m_len,
-            v_len
-        });
-        let in_elem_bitwidth =
-            require_int_ty!(m_elem_ty.kind(), InvalidMonomorphization::MaskType {
-                span,
-                name,
-                ty: m_elem_ty
-            });
+        require!(
+            m_len == v_len,
+            InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
+        );
+        let in_elem_bitwidth = require_int_ty!(
+            m_elem_ty.kind(),
+            InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }
+        );
         let m_i1s = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, m_len);
         return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
     }
@@ -1510,13 +1499,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         let expected_bytes = in_len.div_ceil(8);
 
         // Integer vector <i{in_bitwidth} x in_len>:
-        let in_elem_bitwidth =
-            require_int_or_uint_ty!(in_elem.kind(), InvalidMonomorphization::VectorArgument {
-                span,
-                name,
-                in_ty,
-                in_elem
-            });
+        let in_elem_bitwidth = require_int_or_uint_ty!(
+            in_elem.kind(),
+            InvalidMonomorphization::VectorArgument { span, name, in_ty, in_elem }
+        );
 
         let i1xn = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, in_len);
         // Bitcast <i1 x N> to iN:
@@ -1698,30 +1684,34 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         require_simd!(ret_ty, SimdReturn);
 
         // Of the same length:
-        require!(in_len == out_len, InvalidMonomorphization::SecondArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[1],
-            out_len
-        });
-        require!(in_len == out_len2, InvalidMonomorphization::ThirdArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[2],
-            out_len: out_len2
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::SecondArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[1],
+                out_len
+            }
+        );
+        require!(
+            in_len == out_len2,
+            InvalidMonomorphization::ThirdArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[2],
+                out_len: out_len2
+            }
+        );
 
         // The return type must match the first argument type
-        require!(ret_ty == in_ty, InvalidMonomorphization::ExpectedReturnType {
-            span,
-            name,
-            in_ty,
-            ret_ty
-        });
+        require!(
+            ret_ty == in_ty,
+            InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty }
+        );
 
         require!(
             matches!(
@@ -1739,13 +1729,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             }
         );
 
-        let mask_elem_bitwidth =
-            require_int_ty!(element_ty2.kind(), InvalidMonomorphization::ThirdArgElementType {
+        let mask_elem_bitwidth = require_int_ty!(
+            element_ty2.kind(),
+            InvalidMonomorphization::ThirdArgElementType {
                 span,
                 name,
                 expected_element: element_ty2,
                 third_arg: arg_tys[2]
-            });
+            }
+        );
 
         // Alignment of T, must be a constant integer value:
         let alignment_ty = bx.type_i32();
@@ -1805,22 +1797,23 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         require_simd!(ret_ty, SimdReturn);
 
         // Of the same length:
-        require!(values_len == mask_len, InvalidMonomorphization::ThirdArgumentLength {
-            span,
-            name,
-            in_len: mask_len,
-            in_ty: mask_ty,
-            arg_ty: values_ty,
-            out_len: values_len
-        });
+        require!(
+            values_len == mask_len,
+            InvalidMonomorphization::ThirdArgumentLength {
+                span,
+                name,
+                in_len: mask_len,
+                in_ty: mask_ty,
+                arg_ty: values_ty,
+                out_len: values_len
+            }
+        );
 
         // The return type must match the last argument type
-        require!(ret_ty == values_ty, InvalidMonomorphization::ExpectedReturnType {
-            span,
-            name,
-            in_ty: values_ty,
-            ret_ty
-        });
+        require!(
+            ret_ty == values_ty,
+            InvalidMonomorphization::ExpectedReturnType { span, name, in_ty: values_ty, ret_ty }
+        );
 
         require!(
             matches!(
@@ -1838,13 +1831,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             }
         );
 
-        let m_elem_bitwidth =
-            require_int_ty!(mask_elem.kind(), InvalidMonomorphization::ThirdArgElementType {
+        let m_elem_bitwidth = require_int_ty!(
+            mask_elem.kind(),
+            InvalidMonomorphization::ThirdArgElementType {
                 span,
                 name,
                 expected_element: values_elem,
                 third_arg: mask_ty,
-            });
+            }
+        );
 
         let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len);
         let mask_ty = bx.type_vector(bx.type_i1(), mask_len);
@@ -1896,14 +1891,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         let (values_len, values_elem) = require_simd!(values_ty, SimdThird);
 
         // Of the same length:
-        require!(values_len == mask_len, InvalidMonomorphization::ThirdArgumentLength {
-            span,
-            name,
-            in_len: mask_len,
-            in_ty: mask_ty,
-            arg_ty: values_ty,
-            out_len: values_len
-        });
+        require!(
+            values_len == mask_len,
+            InvalidMonomorphization::ThirdArgumentLength {
+                span,
+                name,
+                in_len: mask_len,
+                in_ty: mask_ty,
+                arg_ty: values_ty,
+                out_len: values_len
+            }
+        );
 
         // The second argument must be a mutable pointer type matching the element type
         require!(
@@ -1923,13 +1921,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             }
         );
 
-        let m_elem_bitwidth =
-            require_int_ty!(mask_elem.kind(), InvalidMonomorphization::ThirdArgElementType {
+        let m_elem_bitwidth = require_int_ty!(
+            mask_elem.kind(),
+            InvalidMonomorphization::ThirdArgElementType {
                 span,
                 name,
                 expected_element: values_elem,
                 third_arg: mask_ty,
-            });
+            }
+        );
 
         let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len);
         let mask_ty = bx.type_vector(bx.type_i1(), mask_len);
@@ -1976,22 +1976,28 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         let (element_len2, element_ty2) = require_simd!(arg_tys[2], SimdThird);
 
         // Of the same length:
-        require!(in_len == element_len1, InvalidMonomorphization::SecondArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[1],
-            out_len: element_len1
-        });
-        require!(in_len == element_len2, InvalidMonomorphization::ThirdArgumentLength {
-            span,
-            name,
-            in_len,
-            in_ty,
-            arg_ty: arg_tys[2],
-            out_len: element_len2
-        });
+        require!(
+            in_len == element_len1,
+            InvalidMonomorphization::SecondArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[1],
+                out_len: element_len1
+            }
+        );
+        require!(
+            in_len == element_len2,
+            InvalidMonomorphization::ThirdArgumentLength {
+                span,
+                name,
+                in_len,
+                in_ty,
+                arg_ty: arg_tys[2],
+                out_len: element_len2
+            }
+        );
 
         require!(
             matches!(
@@ -2011,13 +2017,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         );
 
         // The element type of the third argument must be a signed integer type of any width:
-        let mask_elem_bitwidth =
-            require_int_ty!(element_ty2.kind(), InvalidMonomorphization::ThirdArgElementType {
+        let mask_elem_bitwidth = require_int_ty!(
+            element_ty2.kind(),
+            InvalidMonomorphization::ThirdArgElementType {
                 span,
                 name,
                 expected_element: element_ty2,
                 third_arg: arg_tys[2]
-            });
+            }
+        );
 
         // Alignment of T, must be a constant integer value:
         let alignment_ty = bx.type_i32();
@@ -2058,13 +2066,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         ($name:ident : $integer_reduce:ident, $float_reduce:ident, $ordered:expr, $op:ident,
          $identity:expr) => {
             if name == sym::$name {
-                require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                    span,
-                    name,
-                    in_elem,
-                    in_ty,
-                    ret_ty
-                });
+                require!(
+                    ret_ty == in_elem,
+                    InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                );
                 return match in_elem.kind() {
                     ty::Int(_) | ty::Uint(_) => {
                         let r = bx.$integer_reduce(args[0].immediate());
@@ -2133,13 +2138,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     macro_rules! minmax_red {
         ($name:ident: $int_red:ident, $float_red:ident) => {
             if name == sym::$name {
-                require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                    span,
-                    name,
-                    in_elem,
-                    in_ty,
-                    ret_ty
-                });
+                require!(
+                    ret_ty == in_elem,
+                    InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                );
                 return match in_elem.kind() {
                     ty::Int(_i) => Ok(bx.$int_red(args[0].immediate(), true)),
                     ty::Uint(_u) => Ok(bx.$int_red(args[0].immediate(), false)),
@@ -2164,13 +2166,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         ($name:ident : $red:ident, $boolean:expr) => {
             if name == sym::$name {
                 let input = if !$boolean {
-                    require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
-                        span,
-                        name,
-                        in_elem,
-                        in_ty,
-                        ret_ty
-                    });
+                    require!(
+                        ret_ty == in_elem,
+                        InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
+                    );
                     args[0].immediate()
                 } else {
                     let bitwidth = match in_elem.kind() {
@@ -2218,25 +2217,27 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
 
     if name == sym::simd_cast_ptr {
         let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match in_elem.kind() {
             ty::RawPtr(p_ty, _) => {
                 let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
                     bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
                 });
-                require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
-                    span,
-                    name,
-                    ty: in_elem
-                });
+                require!(
+                    metadata.is_unit(),
+                    InvalidMonomorphization::CastWidePointer { span, name, ty: in_elem }
+                );
             }
             _ => {
                 return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
@@ -2247,11 +2248,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
                 let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
                     bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
                 });
-                require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
-                    span,
-                    name,
-                    ty: out_elem
-                });
+                require!(
+                    metadata.is_unit(),
+                    InvalidMonomorphization::CastWidePointer { span, name, ty: out_elem }
+                );
             }
             _ => {
                 return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
@@ -2263,14 +2263,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
 
     if name == sym::simd_expose_provenance {
         let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match in_elem.kind() {
             ty::RawPtr(_, _) => {}
@@ -2288,14 +2291,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
 
     if name == sym::simd_with_exposed_provenance {
         let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
 
         match in_elem.kind() {
             ty::Uint(ty::UintTy::Usize) => {}
@@ -2313,14 +2319,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
 
     if name == sym::simd_cast || name == sym::simd_as {
         let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
-        require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
-            span,
-            name,
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
-        });
+        require!(
+            in_len == out_len,
+            InvalidMonomorphization::ReturnLengthInputType {
+                span,
+                name,
+                in_len,
+                in_ty,
+                ret_ty,
+                out_len
+            }
+        );
         // casting cares about nominal type, not just structural type
         if in_elem == out_elem {
             return Ok(args[0].immediate());
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 14346795fda..f0d04b2b644 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -13,6 +13,7 @@
 #![feature(extern_types)]
 #![feature(file_buffered)]
 #![feature(hash_raw_entry)]
+#![feature(if_let_guard)]
 #![feature(impl_trait_in_assoc_type)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 50a40c9c309..4d6a76b23ea 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2382,6 +2382,7 @@ unsafe extern "C" {
         LoopVectorize: bool,
         DisableSimplifyLibCalls: bool,
         EmitLifetimeMarkers: bool,
+        RunEnzyme: bool,
         SanitizerOptions: Option<&SanitizerOptions>,
         PGOGenPath: *const c_char,
         PGOUsePath: *const c_char,
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index 33789c6261f..70edee21bd6 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -71,10 +71,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
         // compiler-rt, then we want to implicitly compile everything with hidden
         // visibility as we're going to link this object all over the place but
         // don't want the symbols to get exported.
-        if linkage != Linkage::Internal
-            && linkage != Linkage::Private
-            && self.tcx.is_compiler_builtins(LOCAL_CRATE)
-        {
+        if linkage != Linkage::Internal && self.tcx.is_compiler_builtins(LOCAL_CRATE) {
             llvm::set_visibility(lldecl, llvm::Visibility::Hidden);
         } else {
             llvm::set_visibility(lldecl, base::visibility_to_llvm(visibility));
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index c56ad886120..34cede54aaf 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -1,14 +1,14 @@
 use std::{fmt, ptr};
 
 use libc::{c_char, c_uint};
-use rustc_abi::{AddressSpace, Align, Integer, Size};
+use rustc_abi::{AddressSpace, Align, Integer, Reg, Size};
 use rustc_codegen_ssa::common::TypeKind;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_middle::bug;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{self, Ty};
-use rustc_target::callconv::{CastTarget, FnAbi, Reg};
+use rustc_target::callconv::{CastTarget, FnAbi};
 
 use crate::abi::{FnAbiLlvmExt, LlvmType};
 use crate::context::{CodegenCx, SimpleCx};
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index b22357acdc2..2afc1efc1b3 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -11,7 +11,7 @@ bitflags = "2.4.1"
 bstr = "1.11.3"
 # Pinned so `cargo update` bumps don't cause breakage. Please also update the
 # `cc` in `rustc_llvm` if you update the `cc` here.
-cc = "=1.2.7"
+cc = "=1.2.13"
 either = "1.5.0"
 itertools = "0.12"
 pathdiff = "0.2.0"
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 58eb137c068..60af462b6b6 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -414,10 +414,10 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
                     let member_path = archive_path.parent().unwrap().join(Path::new(&file_name));
                     self.entries.push((file_name.into_bytes(), ArchiveEntry::File(member_path)));
                 } else {
-                    self.entries.push((file_name.into_bytes(), ArchiveEntry::FromArchive {
-                        archive_index,
-                        file_range: entry.file_range(),
-                    }));
+                    self.entries.push((
+                        file_name.into_bytes(),
+                        ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() },
+                    ));
                 }
             }
         }
diff --git a/compiler/rustc_codegen_ssa/src/back/linker/tests.rs b/compiler/rustc_codegen_ssa/src/back/linker/tests.rs
index bf3e8c90200..143df085dbf 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker/tests.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker/tests.rs
@@ -10,23 +10,22 @@ fn test_rpaths_to_args() {
 #[test]
 fn test_xlinker() {
     let mut cmd = Command::new("foo");
-    convert_link_args_to_cc_args(&mut cmd, &[
-        "arg1",
-        "arg2",
-        "arg3,with,comma",
-        "arg4,with,comma",
-        "arg5",
-        "arg6,with,comma",
-    ]);
+    convert_link_args_to_cc_args(
+        &mut cmd,
+        &["arg1", "arg2", "arg3,with,comma", "arg4,with,comma", "arg5", "arg6,with,comma"],
+    );
 
-    assert_eq!(cmd.get_args(), [
-        OsStr::new("-Wl,arg1,arg2"),
-        OsStr::new("-Xlinker"),
-        OsStr::new("arg3,with,comma"),
-        OsStr::new("-Xlinker"),
-        OsStr::new("arg4,with,comma"),
-        OsStr::new("-Wl,arg5"),
-        OsStr::new("-Xlinker"),
-        OsStr::new("arg6,with,comma"),
-    ]);
+    assert_eq!(
+        cmd.get_args(),
+        [
+            OsStr::new("-Wl,arg1,arg2"),
+            OsStr::new("-Xlinker"),
+            OsStr::new("arg3,with,comma"),
+            OsStr::new("-Xlinker"),
+            OsStr::new("arg4,with,comma"),
+            OsStr::new("-Wl,arg5"),
+            OsStr::new("-Xlinker"),
+            OsStr::new("arg6,with,comma"),
+        ]
+    );
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index ba7b53321a8..d70413b8a47 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -704,13 +704,17 @@ pub fn create_metadata_file_for_wasm(sess: &Session, data: &[u8], section_name:
     let mut imports = wasm_encoder::ImportSection::new();
 
     if sess.target.pointer_width == 64 {
-        imports.import("env", "__linear_memory", wasm_encoder::MemoryType {
-            minimum: 0,
-            maximum: None,
-            memory64: true,
-            shared: false,
-            page_size_log2: None,
-        });
+        imports.import(
+            "env",
+            "__linear_memory",
+            wasm_encoder::MemoryType {
+                minimum: 0,
+                maximum: None,
+                memory64: true,
+                shared: false,
+                page_size_log2: None,
+            },
+        );
     }
 
     if imports.len() > 0 {
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index f8f7bb2dbc6..1dbaffaa577 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -140,11 +140,14 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
         .into();
 
     if let Some(id) = tcx.proc_macro_decls_static(()) {
-        reachable_non_generics.insert(id.to_def_id(), SymbolExportInfo {
-            level: SymbolExportLevel::C,
-            kind: SymbolExportKind::Data,
-            used: false,
-        });
+        reachable_non_generics.insert(
+            id.to_def_id(),
+            SymbolExportInfo {
+                level: SymbolExportLevel::C,
+                kind: SymbolExportKind::Data,
+                used: false,
+            },
+        );
     }
 
     reachable_non_generics
@@ -185,11 +188,14 @@ fn exported_symbols_provider_local(
     if !tcx.sess.target.dll_tls_export {
         symbols.extend(sorted.iter().filter_map(|(&def_id, &info)| {
             tcx.needs_thread_local_shim(def_id).then(|| {
-                (ExportedSymbol::ThreadLocalShim(def_id), SymbolExportInfo {
-                    level: info.level,
-                    kind: SymbolExportKind::Text,
-                    used: info.used,
-                })
+                (
+                    ExportedSymbol::ThreadLocalShim(def_id),
+                    SymbolExportInfo {
+                        level: info.level,
+                        kind: SymbolExportKind::Text,
+                        used: info.used,
+                    },
+                )
             })
         }))
     }
@@ -198,11 +204,14 @@ fn exported_symbols_provider_local(
         let exported_symbol =
             ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref()));
 
-        symbols.push((exported_symbol, SymbolExportInfo {
-            level: SymbolExportLevel::C,
-            kind: SymbolExportKind::Text,
-            used: false,
-        }));
+        symbols.push((
+            exported_symbol,
+            SymbolExportInfo {
+                level: SymbolExportLevel::C,
+                kind: SymbolExportKind::Text,
+                used: false,
+            },
+        ));
     }
 
     // Mark allocator shim symbols as exported only if they were generated.
@@ -214,20 +223,26 @@ fn exported_symbols_provider_local(
         {
             let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
 
-            symbols.push((exported_symbol, SymbolExportInfo {
-                level: SymbolExportLevel::Rust,
-                kind: SymbolExportKind::Text,
-                used: false,
-            }));
+            symbols.push((
+                exported_symbol,
+                SymbolExportInfo {
+                    level: SymbolExportLevel::Rust,
+                    kind: SymbolExportKind::Text,
+                    used: false,
+                },
+            ));
         }
 
         let exported_symbol =
             ExportedSymbol::NoDefId(SymbolName::new(tcx, NO_ALLOC_SHIM_IS_UNSTABLE));
-        symbols.push((exported_symbol, SymbolExportInfo {
-            level: SymbolExportLevel::Rust,
-            kind: SymbolExportKind::Data,
-            used: false,
-        }))
+        symbols.push((
+            exported_symbol,
+            SymbolExportInfo {
+                level: SymbolExportLevel::Rust,
+                kind: SymbolExportKind::Data,
+                used: false,
+            },
+        ))
     }
 
     if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
@@ -239,11 +254,14 @@ fn exported_symbols_provider_local(
 
         symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| {
             let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
-            (exported_symbol, SymbolExportInfo {
-                level: SymbolExportLevel::C,
-                kind: SymbolExportKind::Data,
-                used: false,
-            })
+            (
+                exported_symbol,
+                SymbolExportInfo {
+                    level: SymbolExportLevel::C,
+                    kind: SymbolExportKind::Data,
+                    used: false,
+                },
+            )
         }));
     }
 
@@ -261,11 +279,14 @@ fn exported_symbols_provider_local(
 
         symbols.extend(msan_weak_symbols.into_iter().map(|sym| {
             let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
-            (exported_symbol, SymbolExportInfo {
-                level: SymbolExportLevel::C,
-                kind: SymbolExportKind::Data,
-                used: false,
-            })
+            (
+                exported_symbol,
+                SymbolExportInfo {
+                    level: SymbolExportLevel::C,
+                    kind: SymbolExportKind::Data,
+                    used: false,
+                },
+            )
         }));
     }
 
@@ -275,11 +296,14 @@ fn exported_symbols_provider_local(
         let symbol_name = metadata_symbol_name(tcx);
         let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
 
-        symbols.push((exported_symbol, SymbolExportInfo {
-            level: SymbolExportLevel::C,
-            kind: SymbolExportKind::Data,
-            used: true,
-        }));
+        symbols.push((
+            exported_symbol,
+            SymbolExportInfo {
+                level: SymbolExportLevel::C,
+                kind: SymbolExportKind::Data,
+                used: true,
+            },
+        ));
     }
 
     if tcx.local_crate_exports_generics() {
@@ -325,21 +349,27 @@ fn exported_symbols_provider_local(
                 MonoItem::Fn(Instance { def: InstanceKind::Item(def), args }) => {
                     if args.non_erasable_generics().next().is_some() {
                         let symbol = ExportedSymbol::Generic(def, args);
-                        symbols.push((symbol, SymbolExportInfo {
-                            level: SymbolExportLevel::Rust,
-                            kind: SymbolExportKind::Text,
-                            used: false,
-                        }));
+                        symbols.push((
+                            symbol,
+                            SymbolExportInfo {
+                                level: SymbolExportLevel::Rust,
+                                kind: SymbolExportKind::Text,
+                                used: false,
+                            },
+                        ));
                     }
                 }
                 MonoItem::Fn(Instance { def: InstanceKind::DropGlue(_, Some(ty)), args }) => {
                     // A little sanity-check
                     assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty)));
-                    symbols.push((ExportedSymbol::DropGlue(ty), SymbolExportInfo {
-                        level: SymbolExportLevel::Rust,
-                        kind: SymbolExportKind::Text,
-                        used: false,
-                    }));
+                    symbols.push((
+                        ExportedSymbol::DropGlue(ty),
+                        SymbolExportInfo {
+                            level: SymbolExportLevel::Rust,
+                            kind: SymbolExportKind::Text,
+                            used: false,
+                        },
+                    ));
                 }
                 MonoItem::Fn(Instance {
                     def: InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)),
@@ -347,11 +377,14 @@ fn exported_symbols_provider_local(
                 }) => {
                     // A little sanity-check
                     assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty)));
-                    symbols.push((ExportedSymbol::AsyncDropGlueCtorShim(ty), SymbolExportInfo {
-                        level: SymbolExportLevel::Rust,
-                        kind: SymbolExportKind::Text,
-                        used: false,
-                    }));
+                    symbols.push((
+                        ExportedSymbol::AsyncDropGlueCtorShim(ty),
+                        SymbolExportInfo {
+                            level: SymbolExportLevel::Rust,
+                            kind: SymbolExportKind::Text,
+                            used: false,
+                        },
+                    ));
                 }
                 _ => {
                     // Any other symbols don't qualify for sharing
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 4166387dad0..2c38fb5658f 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -41,7 +41,6 @@ fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
     // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
     // and don't have to be, LLVM treats them as no-ops.
     match name {
-        "appending" => Appending,
         "available_externally" => AvailableExternally,
         "common" => Common,
         "extern_weak" => ExternalWeak,
@@ -49,7 +48,6 @@ fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
         "internal" => Internal,
         "linkonce" => LinkOnceAny,
         "linkonce_odr" => LinkOnceODR,
-        "private" => Private,
         "weak" => WeakAny,
         "weak_odr" => WeakODR,
         _ => tcx.dcx().span_fatal(tcx.def_span(def_id), "invalid linkage specified"),
@@ -916,8 +914,6 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
     let mode = match mode.as_str() {
         "Forward" => DiffMode::Forward,
         "Reverse" => DiffMode::Reverse,
-        "ForwardFirst" => DiffMode::ForwardFirst,
-        "ReverseFirst" => DiffMode::ReverseFirst,
         _ => {
             span_bug!(mode.span, "rustc_autodiff attribute contains invalid mode");
         }
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 66008a47650..45003c83edc 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1,6 +1,6 @@
 use std::cmp;
 
-use rustc_abi::{self as abi, ExternAbi, HasDataLayout, WrappingRange};
+use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, WrappingRange};
 use rustc_ast as ast;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir::lang_items::LangItem;
@@ -14,7 +14,7 @@ use rustc_middle::{bug, span_bug};
 use rustc_session::config::OptLevel;
 use rustc_span::source_map::Spanned;
 use rustc_span::{Span, sym};
-use rustc_target::callconv::{ArgAbi, FnAbi, PassMode, Reg};
+use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
 use tracing::{debug, info};
 
 use super::operand::OperandRef;
@@ -1568,7 +1568,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 // the load would just produce `OperandValue::Ref` instead
                 // of the `OperandValue::Immediate` we need for the call.
                 llval = bx.load(bx.backend_type(arg.layout), llval, align);
-                if let abi::BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
+                if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
                     if scalar.is_bool() {
                         bx.range_metadata(llval, WrappingRange { start: 0, end: 1 });
                     }
@@ -1627,10 +1627,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         if let Some(slot) = self.personality_slot {
             slot
         } else {
-            let layout = cx.layout_of(Ty::new_tup(cx.tcx(), &[
-                Ty::new_mut_ptr(cx.tcx(), cx.tcx().types.u8),
-                cx.tcx().types.i32,
-            ]));
+            let layout = cx.layout_of(Ty::new_tup(
+                cx.tcx(),
+                &[Ty::new_mut_ptr(cx.tcx(), cx.tcx().types.u8), cx.tcx().types.i32],
+            ));
             let slot = PlaceRef::alloca(bx, layout);
             self.personality_slot = Some(slot);
             slot
@@ -1731,15 +1731,32 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let mut cs_bx = Bx::build(self.cx, llbb);
             let cs = cs_bx.catch_switch(None, None, &[cp_llbb]);
 
-            // The "null" here is actually a RTTI type descriptor for the
-            // C++ personality function, but `catch (...)` has no type so
-            // it's null. The 64 here is actually a bitfield which
-            // represents that this is a catch-all block.
             bx = Bx::build(self.cx, cp_llbb);
             let null =
                 bx.const_null(bx.type_ptr_ext(bx.cx().data_layout().instruction_address_space));
-            let sixty_four = bx.const_i32(64);
-            funclet = Some(bx.catch_pad(cs, &[null, sixty_four, null]));
+
+            // The `null` in first argument here is actually a RTTI type
+            // descriptor for the C++ personality function, but `catch (...)`
+            // has no type so it's null.
+            let args = if base::wants_msvc_seh(self.cx.sess()) {
+                // This bitmask is a single `HT_IsStdDotDot` flag, which
+                // represents that this is a C++-style `catch (...)` block that
+                // only captures programmatic exceptions, not all SEH
+                // exceptions. The second `null` points to a non-existent
+                // `alloca` instruction, which an LLVM pass would inline into
+                // the initial SEH frame allocation.
+                let adjectives = bx.const_i32(0x40);
+                &[null, adjectives, null] as &[_]
+            } else {
+                // Specifying more arguments than necessary usually doesn't
+                // hurt, but the `WasmEHPrepare` LLVM pass does not recognize
+                // anything other than a single `null` as a `catch (...)` block,
+                // leading to problems down the line during instruction
+                // selection.
+                &[null] as &[_]
+            };
+
+            funclet = Some(bx.catch_pad(cs, args));
         } else {
             llbb = Bx::append_block(self.cx, self.llfn, "terminate");
             bx = Bx::build(self.cx, llbb);
diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
index dc406809874..eb0711dbb32 100644
--- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
@@ -187,10 +187,9 @@ fn prefix_and_suffix<'tcx>(
                     }
                 }
             }
-            Linkage::Internal | Linkage::Private => {
+            Linkage::Internal => {
                 // write nothing
             }
-            Linkage::Appending => emit_fatal("Only global variables can have appending linkage!"),
             Linkage::Common => emit_fatal("Functions may not have common linkage"),
             Linkage::AvailableExternally => {
                 // this would make the function equal an extern definition
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 73a41676802..eb4270ffe80 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -474,10 +474,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             LocalRef::Operand(..) => {
                 if place_ref.is_indirect_first_projection() {
                     base = 1;
-                    let cg_base = self.codegen_consume(bx, mir::PlaceRef {
-                        projection: &place_ref.projection[..0],
-                        ..place_ref
-                    });
+                    let cg_base = self.codegen_consume(
+                        bx,
+                        mir::PlaceRef { projection: &place_ref.projection[..0], ..place_ref },
+                    );
                     cg_base.deref(bx.cx())
                 } else {
                     bug!("using operand local {:?} as place", place_ref);
diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs
index d0de7ff0b5f..5cfb56ebace 100644
--- a/compiler/rustc_codegen_ssa/src/traits/consts.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs
@@ -1,5 +1,5 @@
+use rustc_abi as abi;
 use rustc_middle::mir::interpret::{ConstAllocation, Scalar};
-use rustc_target::abi;
 
 use super::BackendTypes;
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index 6292d321f6b..c178ebc596e 100644
--- a/compiler/rustc_codegen_ssa/src/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
@@ -1,8 +1,8 @@
-use rustc_abi::{AddressSpace, Float, Integer};
+use rustc_abi::{AddressSpace, Float, Integer, Reg};
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout};
 use rustc_middle::ty::{self, Ty};
-use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi, Reg};
+use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi};
 
 use super::BackendTypes;
 use super::misc::MiscCodegenMethods;
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index 9c99782d223..dfcd1969a73 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -188,12 +188,14 @@ impl Qualif for NeedsNonConstDrop {
             ObligationCause::misc(cx.body.span, cx.def_id()),
             param_env,
             ty::Binder::dummy(ty::TraitRef::new(cx.tcx, destruct_def_id, [ty]))
-                .to_host_effect_clause(cx.tcx, match cx.const_kind() {
-                    rustc_hir::ConstContext::ConstFn => ty::BoundConstness::Maybe,
-                    rustc_hir::ConstContext::Static(_) | rustc_hir::ConstContext::Const { .. } => {
-                        ty::BoundConstness::Const
-                    }
-                }),
+                .to_host_effect_clause(
+                    cx.tcx,
+                    match cx.const_kind() {
+                        rustc_hir::ConstContext::ConstFn => ty::BoundConstness::Maybe,
+                        rustc_hir::ConstContext::Static(_)
+                        | rustc_hir::ConstContext::Const { .. } => ty::BoundConstness::Const,
+                    },
+                ),
         ));
         !ocx.select_all_or_error().is_empty()
     }
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index a2635885098..8df9877cabc 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -578,10 +578,13 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
             }
             ShiftOverflow { intrinsic, shift_amount } => {
                 diag.arg("intrinsic", intrinsic);
-                diag.arg("shift_amount", match shift_amount {
-                    Either::Left(v) => v.to_string(),
-                    Either::Right(v) => v.to_string(),
-                });
+                diag.arg(
+                    "shift_amount",
+                    match shift_amount {
+                        Either::Left(v) => v.to_string(),
+                        Either::Right(v) => v.to_string(),
+                    },
+                );
             }
             BoundsCheckFailed { len, index } => {
                 diag.arg("len", len);
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index e2e6e16d8a7..cdf706f3752 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -381,10 +381,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 "caller ABI: {:#?}, args: {:#?}",
                 caller_fn_abi,
                 args.iter()
-                    .map(|arg| (arg.layout().ty, match arg {
-                        FnArg::Copy(op) => format!("copy({op:?})"),
-                        FnArg::InPlace(mplace) => format!("in-place({mplace:?})"),
-                    }))
+                    .map(|arg| (
+                        arg.layout().ty,
+                        match arg {
+                            FnArg::Copy(op) => format!("copy({op:?})"),
+                            FnArg::InPlace(mplace) => format!("in-place({mplace:?})"),
+                        }
+                    ))
                     .collect::<Vec<_>>()
             );
             trace!(
@@ -874,10 +877,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         );
 
         // Check `unwinding`.
-        assert_eq!(unwinding, match self.frame().loc {
-            Left(loc) => self.body().basic_blocks[loc.block].is_cleanup,
-            Right(_) => true,
-        });
+        assert_eq!(
+            unwinding,
+            match self.frame().loc {
+                Left(loc) => self.body().basic_blocks[loc.block].is_cleanup,
+                Right(_) => true,
+            }
+        );
         if unwinding && self.frame_idx() == 0 {
             throw_ub_custom!(fluent::const_eval_unwind_past_top);
         }
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 0cbb3b157f3..e14cc1dad36 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -102,11 +102,11 @@ fn intern_as_new_static<'tcx>(
     alloc_id: AllocId,
     alloc: ConstAllocation<'tcx>,
 ) {
-    let feed = tcx.create_def(static_id, sym::nested, DefKind::Static {
-        safety: hir::Safety::Safe,
-        mutability: alloc.0.mutability,
-        nested: true,
-    });
+    let feed = tcx.create_def(
+        static_id,
+        sym::nested,
+        DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true },
+    );
     tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());
 
     if tcx.is_thread_local_static(static_id.into()) {
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 8e544798742..0ac34f4633b 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -812,10 +812,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                 if start == 1 && end == max_value {
                     // Only null is the niche. So make sure the ptr is NOT null.
                     if self.ecx.scalar_may_be_null(scalar)? {
-                        throw_validation_failure!(self.path, NullablePtrOutOfRange {
-                            range: valid_range,
-                            max_value
-                        })
+                        throw_validation_failure!(
+                            self.path,
+                            NullablePtrOutOfRange { range: valid_range, max_value }
+                        )
                     } else {
                         return interp_ok(());
                     }
@@ -825,10 +825,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                 } else {
                     // Conservatively, we reject, because the pointer *could* have a bad
                     // value.
-                    throw_validation_failure!(self.path, PtrOutOfRange {
-                        range: valid_range,
-                        max_value
-                    })
+                    throw_validation_failure!(
+                        self.path,
+                        PtrOutOfRange { range: valid_range, max_value }
+                    )
                 }
             }
         };
@@ -836,11 +836,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
         if valid_range.contains(bits) {
             interp_ok(())
         } else {
-            throw_validation_failure!(self.path, OutOfRange {
-                value: format!("{bits}"),
-                range: valid_range,
-                max_value
-            })
+            throw_validation_failure!(
+                self.path,
+                OutOfRange { value: format!("{bits}"), range: valid_range, max_value }
+            )
         }
     }
 
diff --git a/compiler/rustc_data_structures/src/graph/dominators/tests.rs b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
index ef82193a4b9..6c078ca7c6e 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
@@ -15,17 +15,10 @@ fn diamond() {
 #[test]
 fn paper() {
     // example from the paper:
-    let graph = TestGraph::new(6, &[
-        (6, 5),
-        (6, 4),
-        (5, 1),
-        (4, 2),
-        (4, 3),
-        (1, 2),
-        (2, 3),
-        (3, 2),
-        (2, 1),
-    ]);
+    let graph = TestGraph::new(
+        6,
+        &[(6, 5), (6, 4), (5, 1), (4, 2), (4, 3), (1, 2), (2, 3), (3, 2), (2, 1)],
+    );
 
     let d = dominators(&graph);
     assert_eq!(d.immediate_dominator(0), None); // <-- note that 0 is not in graph
@@ -40,19 +33,10 @@ fn paper() {
 #[test]
 fn paper_slt() {
     // example from the paper:
-    let graph = TestGraph::new(1, &[
-        (1, 2),
-        (1, 3),
-        (2, 3),
-        (2, 7),
-        (3, 4),
-        (3, 6),
-        (4, 5),
-        (5, 4),
-        (6, 7),
-        (7, 8),
-        (8, 5),
-    ]);
+    let graph = TestGraph::new(
+        1,
+        &[(1, 2), (1, 3), (2, 3), (2, 7), (3, 4), (3, 6), (4, 5), (5, 4), (6, 7), (7, 8), (8, 5)],
+    );
 
     dominators(&graph);
 }
@@ -69,21 +53,24 @@ fn immediate_dominator() {
 
 #[test]
 fn transitive_dominator() {
-    let graph = TestGraph::new(0, &[
-        // First tree branch.
-        (0, 1),
-        (1, 2),
-        (2, 3),
-        (3, 4),
-        // Second tree branch.
-        (1, 5),
-        (5, 6),
-        // Third tree branch.
-        (0, 7),
-        // These links make 0 the dominator for 2 and 3.
-        (7, 2),
-        (5, 3),
-    ]);
+    let graph = TestGraph::new(
+        0,
+        &[
+            // First tree branch.
+            (0, 1),
+            (1, 2),
+            (2, 3),
+            (3, 4),
+            // Second tree branch.
+            (1, 5),
+            (5, 6),
+            // Third tree branch.
+            (0, 7),
+            // These links make 0 the dominator for 2 and 3.
+            (7, 2),
+            (5, 3),
+        ],
+    );
 
     let d = dominators(&graph);
     assert_eq!(d.immediate_dominator(2), Some(0));
diff --git a/compiler/rustc_data_structures/src/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/implementation/tests.rs
index 7a240f4e58b..32a6d9ec881 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/implementation/tests.rs
@@ -110,10 +110,13 @@ fn each_adjacent_from_a() {
 #[test]
 fn each_adjacent_from_b() {
     let graph = create_graph();
-    test_adjacent_edges(&graph, NodeIndex(1), "B", &[("FB", "F"), ("AB", "A")], &[
-        ("BD", "D"),
-        ("BC", "C"),
-    ]);
+    test_adjacent_edges(
+        &graph,
+        NodeIndex(1),
+        "B",
+        &[("FB", "F"), ("AB", "A")],
+        &[("BD", "D"), ("BC", "C")],
+    );
 }
 
 #[test]
diff --git a/compiler/rustc_data_structures/src/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs
index 7c876c82af2..373f87bfdbc 100644
--- a/compiler/rustc_data_structures/src/graph/scc/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs
@@ -326,46 +326,49 @@ fn test_bug_max_leak_minimised() {
 
 #[test]
 fn test_bug_max_leak() {
-    let graph = TestGraph::new(8, &[
-        (0, 0),
-        (0, 18),
-        (0, 19),
-        (0, 1),
-        (0, 2),
-        (0, 7),
-        (0, 8),
-        (0, 23),
-        (18, 0),
-        (18, 12),
-        (19, 0),
-        (19, 25),
-        (12, 18),
-        (12, 3),
-        (12, 5),
-        (3, 12),
-        (3, 21),
-        (3, 22),
-        (5, 13),
-        (21, 3),
-        (22, 3),
-        (13, 5),
-        (13, 4),
-        (4, 13),
-        (4, 0),
-        (2, 11),
-        (7, 6),
-        (6, 20),
-        (20, 6),
-        (8, 17),
-        (17, 9),
-        (9, 16),
-        (16, 26),
-        (26, 15),
-        (15, 10),
-        (10, 14),
-        (14, 27),
-        (23, 24),
-    ]);
+    let graph = TestGraph::new(
+        8,
+        &[
+            (0, 0),
+            (0, 18),
+            (0, 19),
+            (0, 1),
+            (0, 2),
+            (0, 7),
+            (0, 8),
+            (0, 23),
+            (18, 0),
+            (18, 12),
+            (19, 0),
+            (19, 25),
+            (12, 18),
+            (12, 3),
+            (12, 5),
+            (3, 12),
+            (3, 21),
+            (3, 22),
+            (5, 13),
+            (21, 3),
+            (22, 3),
+            (13, 5),
+            (13, 4),
+            (4, 13),
+            (4, 0),
+            (2, 11),
+            (7, 6),
+            (6, 20),
+            (20, 6),
+            (8, 17),
+            (17, 9),
+            (9, 16),
+            (16, 26),
+            (26, 15),
+            (15, 10),
+            (10, 14),
+            (14, 27),
+            (23, 24),
+        ],
+    );
     let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, |w| match w {
         22 => MaxReached(1),
         24 => MaxReached(2),
diff --git a/compiler/rustc_data_structures/src/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
index 739ef74e3f7..1916a8e2b6b 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/tests.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
@@ -349,10 +349,10 @@ fn diamond() {
     ));
     assert_eq!(d_count, 1);
     assert_eq!(ok.len(), 0);
-    assert_eq!(err, vec![super::Error {
-        error: "operation failed",
-        backtrace: vec!["D'", "A'.1", "A'"]
-    }]);
+    assert_eq!(
+        err,
+        vec![super::Error { error: "operation failed", backtrace: vec!["D'", "A'.1", "A'"] }]
+    );
 
     let errors = forest.to_errors(());
     assert_eq!(errors.len(), 0);
diff --git a/compiler/rustc_data_structures/src/vec_cache/tests.rs b/compiler/rustc_data_structures/src/vec_cache/tests.rs
index a05f2741362..3b65c14162e 100644
--- a/compiler/rustc_data_structures/src/vec_cache/tests.rs
+++ b/compiler/rustc_data_structures/src/vec_cache/tests.rs
@@ -58,11 +58,14 @@ fn concurrent_stress_check() {
 
 #[test]
 fn slot_entries_table() {
-    assert_eq!(ENTRIES_BY_BUCKET, [
-        4096, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
-        8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824,
-        2147483648
-    ]);
+    assert_eq!(
+        ENTRIES_BY_BUCKET,
+        [
+            4096, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152,
+            4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912,
+            1073741824, 2147483648
+        ]
+    );
 }
 
 #[test]
diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs
index f7892db2961..40973e8e5d8 100644
--- a/compiler/rustc_errors/src/json/tests.rs
+++ b/compiler/rustc_errors/src/json/tests.rs
@@ -69,96 +69,128 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
 
 #[test]
 fn empty() {
-    test_positions(" ", (0, 1), SpanTestData {
-        byte_start: 0,
-        byte_end: 1,
-        line_start: 1,
-        column_start: 1,
-        line_end: 1,
-        column_end: 2,
-    })
+    test_positions(
+        " ",
+        (0, 1),
+        SpanTestData {
+            byte_start: 0,
+            byte_end: 1,
+            line_start: 1,
+            column_start: 1,
+            line_end: 1,
+            column_end: 2,
+        },
+    )
 }
 
 #[test]
 fn bom() {
-    test_positions("\u{feff} ", (0, 1), SpanTestData {
-        byte_start: 3,
-        byte_end: 4,
-        line_start: 1,
-        column_start: 1,
-        line_end: 1,
-        column_end: 2,
-    })
+    test_positions(
+        "\u{feff} ",
+        (0, 1),
+        SpanTestData {
+            byte_start: 3,
+            byte_end: 4,
+            line_start: 1,
+            column_start: 1,
+            line_end: 1,
+            column_end: 2,
+        },
+    )
 }
 
 #[test]
 fn lf_newlines() {
-    test_positions("\nmod foo;\nmod bar;\n", (5, 12), SpanTestData {
-        byte_start: 5,
-        byte_end: 12,
-        line_start: 2,
-        column_start: 5,
-        line_end: 3,
-        column_end: 3,
-    })
+    test_positions(
+        "\nmod foo;\nmod bar;\n",
+        (5, 12),
+        SpanTestData {
+            byte_start: 5,
+            byte_end: 12,
+            line_start: 2,
+            column_start: 5,
+            line_end: 3,
+            column_end: 3,
+        },
+    )
 }
 
 #[test]
 fn crlf_newlines() {
-    test_positions("\r\nmod foo;\r\nmod bar;\r\n", (5, 12), SpanTestData {
-        byte_start: 6,
-        byte_end: 14,
-        line_start: 2,
-        column_start: 5,
-        line_end: 3,
-        column_end: 3,
-    })
+    test_positions(
+        "\r\nmod foo;\r\nmod bar;\r\n",
+        (5, 12),
+        SpanTestData {
+            byte_start: 6,
+            byte_end: 14,
+            line_start: 2,
+            column_start: 5,
+            line_end: 3,
+            column_end: 3,
+        },
+    )
 }
 
 #[test]
 fn crlf_newlines_with_bom() {
-    test_positions("\u{feff}\r\nmod foo;\r\nmod bar;\r\n", (5, 12), SpanTestData {
-        byte_start: 9,
-        byte_end: 17,
-        line_start: 2,
-        column_start: 5,
-        line_end: 3,
-        column_end: 3,
-    })
+    test_positions(
+        "\u{feff}\r\nmod foo;\r\nmod bar;\r\n",
+        (5, 12),
+        SpanTestData {
+            byte_start: 9,
+            byte_end: 17,
+            line_start: 2,
+            column_start: 5,
+            line_end: 3,
+            column_end: 3,
+        },
+    )
 }
 
 #[test]
 fn span_before_crlf() {
-    test_positions("foo\r\nbar", (2, 3), SpanTestData {
-        byte_start: 2,
-        byte_end: 3,
-        line_start: 1,
-        column_start: 3,
-        line_end: 1,
-        column_end: 4,
-    })
+    test_positions(
+        "foo\r\nbar",
+        (2, 3),
+        SpanTestData {
+            byte_start: 2,
+            byte_end: 3,
+            line_start: 1,
+            column_start: 3,
+            line_end: 1,
+            column_end: 4,
+        },
+    )
 }
 
 #[test]
 fn span_on_crlf() {
-    test_positions("foo\r\nbar", (3, 4), SpanTestData {
-        byte_start: 3,
-        byte_end: 5,
-        line_start: 1,
-        column_start: 4,
-        line_end: 2,
-        column_end: 1,
-    })
+    test_positions(
+        "foo\r\nbar",
+        (3, 4),
+        SpanTestData {
+            byte_start: 3,
+            byte_end: 5,
+            line_start: 1,
+            column_start: 4,
+            line_end: 2,
+            column_end: 1,
+        },
+    )
 }
 
 #[test]
 fn span_after_crlf() {
-    test_positions("foo\r\nbar", (4, 5), SpanTestData {
-        byte_start: 5,
-        byte_end: 6,
-        line_start: 2,
-        column_start: 1,
-        line_end: 2,
-        column_end: 2,
-    })
+    test_positions(
+        "foo\r\nbar",
+        (4, 5),
+        SpanTestData {
+            byte_start: 5,
+            byte_end: 6,
+            line_start: 2,
+            column_start: 1,
+            line_end: 2,
+            column_end: 2,
+        },
+    )
 }
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 8bf09cf96b3..046213b5a6a 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -233,11 +233,14 @@ impl<'a> ExtCtxt<'a> {
     }
 
     pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
-        self.block(expr.span, thin_vec![ast::Stmt {
-            id: ast::DUMMY_NODE_ID,
-            span: expr.span,
-            kind: ast::StmtKind::Expr(expr),
-        }])
+        self.block(
+            expr.span,
+            thin_vec![ast::Stmt {
+                id: ast::DUMMY_NODE_ID,
+                span: expr.span,
+                kind: ast::StmtKind::Expr(expr),
+            }],
+        )
     }
     pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> P<ast::Block> {
         P(ast::Block {
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 7ac9f453bae..b02a9b93c8a 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -405,26 +405,35 @@ pub fn compile_declarative_macro(
     // ...quasiquoting this would be nice.
     // These spans won't matter, anyways
     let argument_gram = vec![
-        mbe::TokenTree::Sequence(DelimSpan::dummy(), mbe::SequenceRepetition {
-            tts: vec![
-                mbe::TokenTree::MetaVarDecl(span, lhs_nm, tt_spec),
-                mbe::TokenTree::token(token::FatArrow, span),
-                mbe::TokenTree::MetaVarDecl(span, rhs_nm, tt_spec),
-            ],
-            separator: Some(Token::new(if macro_rules { token::Semi } else { token::Comma }, span)),
-            kleene: mbe::KleeneToken::new(mbe::KleeneOp::OneOrMore, span),
-            num_captures: 2,
-        }),
+        mbe::TokenTree::Sequence(
+            DelimSpan::dummy(),
+            mbe::SequenceRepetition {
+                tts: vec![
+                    mbe::TokenTree::MetaVarDecl(span, lhs_nm, tt_spec),
+                    mbe::TokenTree::token(token::FatArrow, span),
+                    mbe::TokenTree::MetaVarDecl(span, rhs_nm, tt_spec),
+                ],
+                separator: Some(Token::new(
+                    if macro_rules { token::Semi } else { token::Comma },
+                    span,
+                )),
+                kleene: mbe::KleeneToken::new(mbe::KleeneOp::OneOrMore, span),
+                num_captures: 2,
+            },
+        ),
         // to phase into semicolon-termination instead of semicolon-separation
-        mbe::TokenTree::Sequence(DelimSpan::dummy(), mbe::SequenceRepetition {
-            tts: vec![mbe::TokenTree::token(
-                if macro_rules { token::Semi } else { token::Comma },
-                span,
-            )],
-            separator: None,
-            kleene: mbe::KleeneToken::new(mbe::KleeneOp::ZeroOrMore, span),
-            num_captures: 0,
-        }),
+        mbe::TokenTree::Sequence(
+            DelimSpan::dummy(),
+            mbe::SequenceRepetition {
+                tts: vec![mbe::TokenTree::token(
+                    if macro_rules { token::Semi } else { token::Comma },
+                    span,
+                )],
+                separator: None,
+                kleene: mbe::KleeneToken::new(mbe::KleeneOp::ZeroOrMore, span),
+                num_captures: 0,
+            },
+        ),
     ];
     // Convert it into `MatcherLoc` form.
     let argument_gram = mbe::macro_parser::compute_locs(&argument_gram);
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index a27d47892e4..b9a06157907 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -179,10 +179,10 @@ fn parse_tree<'a>(
                 Some(&tokenstream::TokenTree::Delimited(delim_span, _, delim, ref tts)) => {
                     if parsing_patterns {
                         if delim != Delimiter::Parenthesis {
-                            span_dollar_dollar_or_metavar_in_the_lhs_err(sess, &Token {
-                                kind: token::OpenDelim(delim),
-                                span: delim_span.entire(),
-                            });
+                            span_dollar_dollar_or_metavar_in_the_lhs_err(
+                                sess,
+                                &Token { kind: token::OpenDelim(delim), span: delim_span.entire() },
+                            );
                         }
                     } else {
                         match delim {
@@ -235,12 +235,10 @@ fn parse_tree<'a>(
                     // Count the number of captured "names" (i.e., named metavars)
                     let num_captures =
                         if parsing_patterns { count_metavar_decls(&sequence) } else { 0 };
-                    TokenTree::Sequence(delim_span, SequenceRepetition {
-                        tts: sequence,
-                        separator,
-                        kleene,
-                        num_captures,
-                    })
+                    TokenTree::Sequence(
+                        delim_span,
+                        SequenceRepetition { tts: sequence, separator, kleene, num_captures },
+                    )
                 }
 
                 // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate`
@@ -261,10 +259,10 @@ fn parse_tree<'a>(
                     _,
                 )) => {
                     if parsing_patterns {
-                        span_dollar_dollar_or_metavar_in_the_lhs_err(sess, &Token {
-                            kind: token::Dollar,
-                            span: dollar_span2,
-                        });
+                        span_dollar_dollar_or_metavar_in_the_lhs_err(
+                            sess,
+                            &Token { kind: token::Dollar, span: dollar_span2 },
+                        );
                     } else {
                         maybe_emit_macro_metavar_expr_feature(features, sess, dollar_span2);
                     }
@@ -289,12 +287,14 @@ fn parse_tree<'a>(
 
         // `tree` is the beginning of a delimited set of tokens (e.g., `(` or `{`). We need to
         // descend into the delimited set and further parse it.
-        &tokenstream::TokenTree::Delimited(span, spacing, delim, ref tts) => {
-            TokenTree::Delimited(span, spacing, Delimited {
+        &tokenstream::TokenTree::Delimited(span, spacing, delim, ref tts) => TokenTree::Delimited(
+            span,
+            spacing,
+            Delimited {
                 delim,
                 tts: parse(tts, parsing_patterns, sess, node_id, features, edition),
-            })
-        }
+            },
+        ),
     }
 }
 
diff --git a/compiler/rustc_graphviz/src/tests.rs b/compiler/rustc_graphviz/src/tests.rs
index 712620a2000..bf2f43fde2e 100644
--- a/compiler/rustc_graphviz/src/tests.rs
+++ b/compiler/rustc_graphviz/src/tests.rs
@@ -360,12 +360,16 @@ fn left_aligned_text() {
 
     let mut writer = Vec::new();
 
-    let g = LabelledGraphWithEscStrs::new("syntax_tree", labels, vec![
-        edge(0, 1, "then", Style::None),
-        edge(0, 2, "else", Style::None),
-        edge(1, 3, ";", Style::None),
-        edge(2, 3, ";", Style::None),
-    ]);
+    let g = LabelledGraphWithEscStrs::new(
+        "syntax_tree",
+        labels,
+        vec![
+            edge(0, 1, "then", Style::None),
+            edge(0, 2, "else", Style::None),
+            edge(1, 3, ";", Style::None),
+            edge(2, 3, ";", Style::None),
+        ],
+    );
 
     render(&g, &mut writer).unwrap();
     let mut r = String::new();
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index e7b6a97c9d9..eafc60f9d72 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3101,10 +3101,10 @@ impl<'hir> Ty<'hir> {
             fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
                 if matches!(
                     &t.kind,
-                    TyKind::Path(QPath::Resolved(_, Path {
-                        res: crate::def::Res::SelfTyAlias { .. },
-                        ..
-                    },))
+                    TyKind::Path(QPath::Resolved(
+                        _,
+                        Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
+                    ))
                 ) {
                     self.0.push(t.span);
                     return;
@@ -3446,11 +3446,10 @@ impl<'hir> InlineAsmOperand<'hir> {
     }
 
     pub fn is_clobber(&self) -> bool {
-        matches!(self, InlineAsmOperand::Out {
-            reg: InlineAsmRegOrRegClass::Reg(_),
-            late: _,
-            expr: None
-        })
+        matches!(
+            self,
+            InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
+        )
     }
 }
 
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 a91d72e9225..bb5087e864c 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -182,12 +182,15 @@ fn compare_method_predicate_entailment<'tcx>(
     // obligations.
     let impl_m_def_id = impl_m.def_id.expect_local();
     let impl_m_span = tcx.def_span(impl_m_def_id);
-    let cause =
-        ObligationCause::new(impl_m_span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
+    let cause = ObligationCause::new(
+        impl_m_span,
+        impl_m_def_id,
+        ObligationCauseCode::CompareImplItem {
             impl_item_def_id: impl_m_def_id,
             trait_item_def_id: trait_m.def_id,
             kind: impl_m.kind,
-        });
+        },
+    );
 
     // Create mapping from trait method to impl method.
     let impl_def_id = impl_m.container_id(tcx);
@@ -248,12 +251,15 @@ fn compare_method_predicate_entailment<'tcx>(
         let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
         let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
 
-        let cause =
-            ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
+        let cause = ObligationCause::new(
+            span,
+            impl_m_def_id,
+            ObligationCauseCode::CompareImplItem {
                 impl_item_def_id: impl_m_def_id,
                 trait_item_def_id: trait_m.def_id,
                 kind: impl_m.kind,
-            });
+            },
+        );
         ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
     }
 
@@ -270,12 +276,15 @@ fn compare_method_predicate_entailment<'tcx>(
             let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
             let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
 
-            let cause =
-                ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
+            let cause = ObligationCause::new(
+                span,
+                impl_m_def_id,
+                ObligationCauseCode::CompareImplItem {
                     impl_item_def_id: impl_m_def_id,
                     trait_item_def_id: trait_m.def_id,
                     kind: impl_m.kind,
-                });
+                },
+            );
             ocx.register_obligation(traits::Obligation::new(
                 tcx,
                 cause,
@@ -493,12 +502,15 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
 
     let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
     let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
-    let cause =
-        ObligationCause::new(return_span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
+    let cause = ObligationCause::new(
+        return_span,
+        impl_m_def_id,
+        ObligationCauseCode::CompareImplItem {
             impl_item_def_id: impl_m_def_id,
             trait_item_def_id: trait_m.def_id,
             kind: impl_m.kind,
-        });
+        },
+    );
 
     // Create mapping from trait to impl (i.e. impl trait header + impl method identity args).
     let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
@@ -534,12 +546,15 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
         let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
 
-        let cause =
-            ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
+        let cause = ObligationCause::new(
+            span,
+            impl_m_def_id,
+            ObligationCauseCode::CompareImplItem {
                 impl_item_def_id: impl_m_def_id,
                 trait_item_def_id: trait_m.def_id,
                 kind: impl_m.kind,
-            });
+            },
+        );
         ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
     }
 
@@ -606,13 +621,16 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
             idx += 1;
             (
                 ty,
-                Ty::new_placeholder(tcx, ty::Placeholder {
-                    universe,
-                    bound: ty::BoundTy {
-                        var: ty::BoundVar::from_usize(idx),
-                        kind: ty::BoundTyKind::Anon,
+                Ty::new_placeholder(
+                    tcx,
+                    ty::Placeholder {
+                        universe,
+                        bound: ty::BoundTy {
+                            var: ty::BoundVar::from_usize(idx),
+                            kind: ty::BoundTyKind::Anon,
+                        },
                     },
-                }),
+                ),
             )
         })
         .collect();
@@ -969,10 +987,13 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
             return Err(guar);
         };
 
-        Ok(ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
-            name: e.name,
-            index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
-        }))
+        Ok(ty::Region::new_early_param(
+            self.tcx,
+            ty::EarlyParamRegion {
+                name: e.name,
+                index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
+            },
+        ))
     }
 }
 
@@ -1967,12 +1988,15 @@ fn compare_type_predicate_entailment<'tcx>(
         let cause = ObligationCause::misc(span, impl_ty_def_id);
         let predicate = ocx.normalize(&cause, param_env, predicate);
 
-        let cause =
-            ObligationCause::new(span, impl_ty_def_id, ObligationCauseCode::CompareImplItem {
+        let cause = ObligationCause::new(
+            span,
+            impl_ty_def_id,
+            ObligationCauseCode::CompareImplItem {
                 impl_item_def_id: impl_ty.def_id.expect_local(),
                 trait_item_def_id: trait_ty.def_id,
                 kind: impl_ty.kind,
-            });
+            },
+        );
         ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
     }
 
@@ -1984,12 +2008,15 @@ fn compare_type_predicate_entailment<'tcx>(
             let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id);
             let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
 
-            let cause =
-                ObligationCause::new(span, impl_ty_def_id, ObligationCauseCode::CompareImplItem {
+            let cause = ObligationCause::new(
+                span,
+                impl_ty_def_id,
+                ObligationCauseCode::CompareImplItem {
                     impl_item_def_id: impl_ty_def_id,
                     trait_item_def_id: trait_ty.def_id,
                     kind: impl_ty.kind,
-                });
+                },
+            );
             ocx.register_obligation(traits::Obligation::new(
                 tcx,
                 cause,
@@ -2244,20 +2271,25 @@ fn param_env_with_gat_bounds<'tcx>(
                     let kind = ty::BoundTyKind::Param(param.def_id, param.name);
                     let bound_var = ty::BoundVariableKind::Ty(kind);
                     bound_vars.push(bound_var);
-                    Ty::new_bound(tcx, ty::INNERMOST, ty::BoundTy {
-                        var: ty::BoundVar::from_usize(bound_vars.len() - 1),
-                        kind,
-                    })
+                    Ty::new_bound(
+                        tcx,
+                        ty::INNERMOST,
+                        ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
+                    )
                     .into()
                 }
                 GenericParamDefKind::Lifetime => {
                     let kind = ty::BoundRegionKind::Named(param.def_id, param.name);
                     let bound_var = ty::BoundVariableKind::Region(kind);
                     bound_vars.push(bound_var);
-                    ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
-                        var: ty::BoundVar::from_usize(bound_vars.len() - 1),
-                        kind,
-                    })
+                    ty::Region::new_bound(
+                        tcx,
+                        ty::INNERMOST,
+                        ty::BoundRegion {
+                            var: ty::BoundVar::from_usize(bound_vars.len() - 1),
+                            kind,
+                        },
+                    )
                     .into()
                 }
                 GenericParamDefKind::Const { .. } => {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 40769ef7536..08e0e52a492 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -185,14 +185,19 @@ pub fn check_intrinsic_type(
     ]);
     let mk_va_list_ty = |mutbl| {
         tcx.lang_items().va_list().map(|did| {
-            let region = ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
-                var: ty::BoundVar::ZERO,
-                kind: ty::BoundRegionKind::Anon,
-            });
-            let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
-                var: ty::BoundVar::from_u32(2),
-                kind: ty::BoundRegionKind::ClosureEnv,
-            });
+            let region = ty::Region::new_bound(
+                tcx,
+                ty::INNERMOST,
+                ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon },
+            );
+            let env_region = ty::Region::new_bound(
+                tcx,
+                ty::INNERMOST,
+                ty::BoundRegion {
+                    var: ty::BoundVar::from_u32(2),
+                    kind: ty::BoundRegionKind::ClosureEnv,
+                },
+            );
             let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]);
             (Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty)
         })
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 20eb96f3ab1..1689437ffb0 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -675,10 +675,10 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
                 // Same for the region. In our example, 'a corresponds
                 // to the 'me parameter.
                 let region_param = gat_generics.param_at(*region_a_idx, tcx);
-                let region_param = ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
-                    index: region_param.index,
-                    name: region_param.name,
-                });
+                let region_param = ty::Region::new_early_param(
+                    tcx,
+                    ty::EarlyParamRegion { index: region_param.index, name: region_param.name },
+                );
                 // The predicate we expect to see. (In our example,
                 // `Self: 'me`.)
                 bounds.insert(
@@ -704,16 +704,16 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
                 debug!("required clause: {region_a} must outlive {region_b}");
                 // Translate into the generic parameters of the GAT.
                 let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
-                let region_a_param = ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
-                    index: region_a_param.index,
-                    name: region_a_param.name,
-                });
+                let region_a_param = ty::Region::new_early_param(
+                    tcx,
+                    ty::EarlyParamRegion { index: region_a_param.index, name: region_a_param.name },
+                );
                 // Same for the region.
                 let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
-                let region_b_param = ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
-                    index: region_b_param.index,
-                    name: region_b_param.name,
-                });
+                let region_b_param = ty::Region::new_early_param(
+                    tcx,
+                    ty::EarlyParamRegion { index: region_b_param.index, name: region_b_param.name },
+                );
                 // The predicate we expect to see.
                 bounds.insert(
                     ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
@@ -1647,10 +1647,15 @@ fn check_fn_or_method<'tcx>(
     }
 
     // If the function has a body, additionally require that the return type is sized.
-    check_sized_if_body(wfcx, def_id, sig.output(), match hir_decl.output {
-        hir::FnRetTy::Return(ty) => Some(ty.span),
-        hir::FnRetTy::DefaultReturn(_) => None,
-    });
+    check_sized_if_body(
+        wfcx,
+        def_id,
+        sig.output(),
+        match hir_decl.output {
+            hir::FnRetTy::Return(ty) => Some(ty.span),
+            hir::FnRetTy::DefaultReturn(_) => None,
+        },
+    );
 }
 
 fn check_sized_if_body<'tcx>(
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 3511dbc6252..66082f4c282 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -333,10 +333,11 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
                         tcx,
                         cause.clone(),
                         param_env,
-                        ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [
-                            field.ty(tcx, args_a),
-                            field.ty(tcx, args_b),
-                        ]),
+                        ty::TraitRef::new(
+                            tcx,
+                            dispatch_from_dyn_trait,
+                            [field.ty(tcx, args_a), field.ty(tcx, args_b)],
+                        ),
                     ));
                 }
                 let errors = ocx.select_all_or_error();
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 5127e73d978..c72f6201831 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -251,10 +251,13 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
                         for ident in &idents_to_add {
                             connected_region_ids.insert(*ident, id_to_set);
                         }
-                        connected_regions.insert(id_to_set, ConnectedRegion {
-                            idents: idents_to_add,
-                            impl_blocks: std::iter::once(i).collect(),
-                        });
+                        connected_regions.insert(
+                            id_to_set,
+                            ConnectedRegion {
+                                idents: idents_to_add,
+                                impl_blocks: std::iter::once(i).collect(),
+                            },
+                        );
                     }
                     // Take the only id inside the list
                     &[id_to_set] => {
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index e37a11b6844..d2e2ab1da77 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -242,10 +242,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
                 // Allocate a new var idx, and insert a new bound ty.
                 let var = ty::BoundVar::from_usize(self.still_bound_vars.len());
                 self.still_bound_vars.push(ty::BoundVariableKind::Ty(old_bound.kind));
-                let mapped = Ty::new_bound(self.tcx, ty::INNERMOST, ty::BoundTy {
-                    var,
-                    kind: old_bound.kind,
-                });
+                let mapped = Ty::new_bound(
+                    self.tcx,
+                    ty::INNERMOST,
+                    ty::BoundTy { var, kind: old_bound.kind },
+                );
                 self.mapping.insert(old_bound.var, mapped.into());
                 mapped
             };
@@ -265,10 +266,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
             } else {
                 let var = ty::BoundVar::from_usize(self.still_bound_vars.len());
                 self.still_bound_vars.push(ty::BoundVariableKind::Region(old_bound.kind));
-                let mapped = ty::Region::new_bound(self.tcx, ty::INNERMOST, ty::BoundRegion {
-                    var,
-                    kind: old_bound.kind,
-                });
+                let mapped = ty::Region::new_bound(
+                    self.tcx,
+                    ty::INNERMOST,
+                    ty::BoundRegion { var, kind: old_bound.kind },
+                );
                 self.mapping.insert(old_bound.var, mapped.into());
                 mapped
             };
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 8a975786a92..d94383d6f3d 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -350,10 +350,10 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
     for param in opaque_own_params {
         let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
         if let ty::ReEarlyParam(..) = *orig_lifetime {
-            let dup_lifetime = ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
-                index: param.index,
-                name: param.name,
-            });
+            let dup_lifetime = ty::Region::new_early_param(
+                tcx,
+                ty::EarlyParamRegion { index: param.index, name: param.name },
+            );
             let span = tcx.def_span(param.def_id);
             predicates.push((
                 ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_lifetime, dup_lifetime))
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 76006354717..c03a1f6240f 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1143,20 +1143,23 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             .params
             .iter()
             .map(|param| {
-                (param.def_id, match param.kind {
-                    GenericParamKind::Lifetime { .. } => {
-                        if self.tcx.is_late_bound(param.hir_id) {
-                            let late_bound_idx = named_late_bound_vars;
-                            named_late_bound_vars += 1;
-                            ResolvedArg::late(late_bound_idx, param)
-                        } else {
+                (
+                    param.def_id,
+                    match param.kind {
+                        GenericParamKind::Lifetime { .. } => {
+                            if self.tcx.is_late_bound(param.hir_id) {
+                                let late_bound_idx = named_late_bound_vars;
+                                named_late_bound_vars += 1;
+                                ResolvedArg::late(late_bound_idx, param)
+                            } else {
+                                ResolvedArg::early(param)
+                            }
+                        }
+                        GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
                             ResolvedArg::early(param)
                         }
-                    }
-                    GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
-                        ResolvedArg::early(param)
-                    }
-                })
+                    },
+                )
             })
             .collect();
 
diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs
index ed45833b614..4dbdfa3d85a 100644
--- a/compiler/rustc_hir_analysis/src/delegation.rs
+++ b/compiler/rustc_hir_analysis/src/delegation.rs
@@ -41,10 +41,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamIndexRemapper<'tcx> {
         if let ty::ReEarlyParam(param) = r.kind()
             && let Some(index) = self.remap_table.get(&param.index).copied()
         {
-            return ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
-                index,
-                name: param.name,
-            });
+            return ty::Region::new_early_param(
+                self.tcx,
+                ty::EarlyParamRegion { index, name: param.name },
+            );
         }
         r
     }
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 e949d4a1126..2834d497694 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -640,13 +640,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let mut num_bound_vars = candidate.bound_vars().len();
         let args = candidate.skip_binder().args.extend_to(tcx, item_def_id, |param, _| {
             let arg = match param.kind {
-                ty::GenericParamDefKind::Lifetime => {
-                    ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
+                ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
+                    tcx,
+                    ty::INNERMOST,
+                    ty::BoundRegion {
                         var: ty::BoundVar::from_usize(num_bound_vars),
                         kind: ty::BoundRegionKind::Named(param.def_id, param.name),
-                    })
-                    .into()
-                }
+                    },
+                )
+                .into(),
                 ty::GenericParamDefKind::Type { .. } => {
                     let guar = *emitted_bad_param_err.get_or_insert_with(|| {
                         self.dcx().emit_err(crate::errors::ReturnTypeNotationIllegalParam::Type {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index e59ff02642c..a8b37fa5054 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -107,12 +107,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let mut needed_associated_types = FxIndexSet::default();
         if let Some((principal_trait, spans)) = &principal_trait {
             let pred: ty::Predicate<'tcx> = (*principal_trait).upcast(tcx);
-            for ClauseWithSupertraitSpan { pred, supertrait_span } in
-                traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(
-                    pred,
-                    *spans.last().unwrap(),
-                )])
-                .filter_only_self()
+            for ClauseWithSupertraitSpan { pred, supertrait_span } in traits::elaborate(
+                tcx,
+                [ClauseWithSupertraitSpan::new(pred, *spans.last().unwrap())],
+            )
+            .filter_only_self()
             {
                 debug!("observing object predicate `{pred:?}`");
 
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 079e8921627..ffddf6f73aa 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2219,10 +2219,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         match self.try_lower_anon_const_lit(ty, expr) {
             Some(v) => v,
-            None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst {
-                def: anon.def_id.to_def_id(),
-                args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
-            }),
+            None => ty::Const::new_unevaluated(
+                tcx,
+                ty::UnevaluatedConst {
+                    def: anon.def_id.to_def_id(),
+                    args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
+                },
+            ),
         }
     }
 
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index fb1df518a88..57df3127a02 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2226,10 +2226,13 @@ impl<'a> State<'a> {
         let generic_params = generic_params
             .iter()
             .filter(|p| {
-                matches!(p, GenericParam {
-                    kind: GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit },
-                    ..
-                })
+                matches!(
+                    p,
+                    GenericParam {
+                        kind: GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit },
+                        ..
+                    }
+                )
             })
             .collect::<Vec<_>>();
 
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index edc3702d90b..f2d0b911731 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -153,13 +153,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     closure_sig,
                 );
                 let adjustments = self.adjust_steps(autoderef);
-                self.record_deferred_call_resolution(def_id, DeferredCallResolution {
-                    call_expr,
-                    callee_expr,
-                    closure_ty: adjusted_ty,
-                    adjustments,
-                    fn_sig: closure_sig,
-                });
+                self.record_deferred_call_resolution(
+                    def_id,
+                    DeferredCallResolution {
+                        call_expr,
+                        callee_expr,
+                        closure_ty: adjusted_ty,
+                        adjustments,
+                        fn_sig: closure_sig,
+                    },
+                );
                 return Some(CallStep::DeferredClosure(def_id, closure_sig));
             }
 
@@ -196,13 +199,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     coroutine_closure_sig.abi,
                 );
                 let adjustments = self.adjust_steps(autoderef);
-                self.record_deferred_call_resolution(def_id, DeferredCallResolution {
-                    call_expr,
-                    callee_expr,
-                    closure_ty: adjusted_ty,
-                    adjustments,
-                    fn_sig: call_sig,
-                });
+                self.record_deferred_call_resolution(
+                    def_id,
+                    DeferredCallResolution {
+                        call_expr,
+                        callee_expr,
+                        closure_ty: adjusted_ty,
+                        adjustments,
+                        fn_sig: call_sig,
+                    },
+                );
                 return Some(CallStep::DeferredClosure(def_id, call_sig));
             }
 
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 65021a0cd11..d8015bcc914 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -666,11 +666,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
         };
         let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
         let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
-        fcx.tcx.emit_node_span_lint(lint, self.expr.hir_id, self.span, errors::TrivialCast {
-            numeric,
-            expr_ty,
-            cast_ty,
-        });
+        fcx.tcx.emit_node_span_lint(
+            lint,
+            self.expr.hir_id,
+            self.span,
+            errors::TrivialCast { numeric, expr_ty, cast_ty },
+        );
     }
 
     #[instrument(skip(fcx), level = "debug")]
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 9fdc5a0ae4e..6fb5f6af091 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -186,18 +186,21 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
     let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span));
 
     // build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
-    let panic_info_ty = tcx.type_of(panic_info_did).instantiate(tcx, &[ty::GenericArg::from(
-        ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
-            var: ty::BoundVar::from_u32(1),
-            kind: ty::BoundRegionKind::Anon,
-        }),
-    )]);
+    let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
+        tcx,
+        &[ty::GenericArg::from(ty::Region::new_bound(
+            tcx,
+            ty::INNERMOST,
+            ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon },
+        ))],
+    );
     let panic_info_ref_ty = Ty::new_imm_ref(
         tcx,
-        ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
-            var: ty::BoundVar::ZERO,
-            kind: ty::BoundRegionKind::Anon,
-        }),
+        ty::Region::new_bound(
+            tcx,
+            ty::INNERMOST,
+            ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon },
+        ),
         panic_info_ty,
     );
 
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 62dfffb560b..43124f44ca6 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -103,12 +103,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     None => self.next_ty_var(expr_span),
                 };
 
-                let closure_args = ty::ClosureArgs::new(tcx, ty::ClosureArgsParts {
-                    parent_args,
-                    closure_kind_ty,
-                    closure_sig_as_fn_ptr_ty: Ty::new_fn_ptr(tcx, sig),
-                    tupled_upvars_ty,
-                });
+                let closure_args = ty::ClosureArgs::new(
+                    tcx,
+                    ty::ClosureArgsParts {
+                        parent_args,
+                        closure_kind_ty,
+                        closure_sig_as_fn_ptr_ty: Ty::new_fn_ptr(tcx, sig),
+                        tupled_upvars_ty,
+                    },
+                );
 
                 (Ty::new_closure(tcx, expr_def_id.to_def_id(), closure_args.args), None)
             }
@@ -177,15 +180,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     _ => tcx.types.unit,
                 };
 
-                let coroutine_args = ty::CoroutineArgs::new(tcx, ty::CoroutineArgsParts {
-                    parent_args,
-                    kind_ty,
-                    resume_ty,
-                    yield_ty,
-                    return_ty: liberated_sig.output(),
-                    witness: interior,
-                    tupled_upvars_ty,
-                });
+                let coroutine_args = ty::CoroutineArgs::new(
+                    tcx,
+                    ty::CoroutineArgsParts {
+                        parent_args,
+                        kind_ty,
+                        resume_ty,
+                        yield_ty,
+                        return_ty: liberated_sig.output(),
+                        witness: interior,
+                        tupled_upvars_ty,
+                    },
+                );
 
                 (
                     Ty::new_coroutine(tcx, expr_def_id.to_def_id(), coroutine_args.args),
@@ -216,8 +222,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 };
 
                 let coroutine_captures_by_ref_ty = self.next_ty_var(expr_span);
-                let closure_args =
-                    ty::CoroutineClosureArgs::new(tcx, ty::CoroutineClosureArgsParts {
+                let closure_args = ty::CoroutineClosureArgs::new(
+                    tcx,
+                    ty::CoroutineClosureArgsParts {
                         parent_args,
                         closure_kind_ty,
                         signature_parts_ty: Ty::new_fn_ptr(
@@ -238,7 +245,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         tupled_upvars_ty,
                         coroutine_captures_by_ref_ty,
                         coroutine_witness_ty: interior,
-                    });
+                    },
+                );
 
                 let coroutine_kind_ty = match expected_kind {
                     Some(kind) => Ty::from_coroutine_closure_kind(tcx, kind),
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 56cc9b6d551..14dd0f32d82 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -555,18 +555,24 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 // the reborrow in coerce_borrowed_ptr will pick it up.
                 let mutbl = AutoBorrowMutability::new(mutbl_b, AllowTwoPhase::No);
 
-                Some((Adjustment { kind: Adjust::Deref(None), target: ty_a }, Adjustment {
-                    kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
-                    target: Ty::new_ref(self.tcx, r_borrow, ty_a, mutbl_b),
-                }))
+                Some((
+                    Adjustment { kind: Adjust::Deref(None), target: ty_a },
+                    Adjustment {
+                        kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
+                        target: Ty::new_ref(self.tcx, r_borrow, ty_a, mutbl_b),
+                    },
+                ))
             }
             (&ty::Ref(_, ty_a, mt_a), &ty::RawPtr(_, mt_b)) => {
                 coerce_mutbls(mt_a, mt_b)?;
 
-                Some((Adjustment { kind: Adjust::Deref(None), target: ty_a }, Adjustment {
-                    kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b)),
-                    target: Ty::new_ptr(self.tcx, ty_a, mt_b),
-                }))
+                Some((
+                    Adjustment { kind: Adjust::Deref(None), target: ty_a },
+                    Adjustment {
+                        kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b)),
+                        target: Ty::new_ptr(self.tcx, ty_a, mt_b),
+                    },
+                ))
             }
             _ => None,
         };
@@ -1033,10 +1039,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         // regionck knows that the region for `a` must be valid here.
         if is_ref {
             self.unify_and(a_unsafe, b, |target| {
-                vec![Adjustment { kind: Adjust::Deref(None), target: mt_a.ty }, Adjustment {
-                    kind: Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b)),
-                    target,
-                }]
+                vec![
+                    Adjustment { kind: Adjust::Deref(None), target: mt_a.ty },
+                    Adjustment { kind: Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b)), target },
+                ]
             })
         } else if mt_a.mutbl != mutbl_b {
             self.unify_and(a_unsafe, b, simple(Adjust::Pointer(PointerCoercion::MutToConstPointer)))
@@ -1288,10 +1294,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 _ => span_bug!(new.span, "should not try to coerce a {new_ty} to a fn pointer"),
             };
             for expr in exprs.iter().map(|e| e.as_coercion_site()) {
-                self.apply_adjustments(expr, vec![Adjustment {
-                    kind: prev_adjustment.clone(),
-                    target: fn_ptr,
-                }]);
+                self.apply_adjustments(
+                    expr,
+                    vec![Adjustment { kind: prev_adjustment.clone(), target: fn_ptr }],
+                );
             }
             self.apply_adjustments(new, vec![Adjustment { kind: next_adjustment, target: fn_ptr }]);
             return Ok(fn_ptr);
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 49f712090f0..9dd965a4dcb 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -84,10 +84,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
 
             let adj_ty = self.next_ty_var(expr.span);
-            self.apply_adjustments(expr, vec![Adjustment {
-                kind: Adjust::NeverToAny,
-                target: adj_ty,
-            }]);
+            self.apply_adjustments(
+                expr,
+                vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty }],
+            );
             ty = adj_ty;
         }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 9277d71234f..6bb8cf5f331 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -290,10 +290,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let autoborrow_mut = adj.iter().any(|adj| {
-            matches!(adj, &Adjustment {
-                kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })),
-                ..
-            })
+            matches!(
+                adj,
+                &Adjustment {
+                    kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })),
+                    ..
+                }
+            )
         });
 
         match self.typeck_results.borrow_mut().adjustments_mut().entry(expr.hir_id) {
@@ -972,11 +975,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut sp = MultiSpan::from_span(path_segment.ident.span);
         sp.push_span_label(
             path_segment.ident.span,
-            format!("this call modifies {} in-place", match rcvr.kind {
-                ExprKind::Path(QPath::Resolved(None, hir::Path { segments: [segment], .. })) =>
-                    format!("`{}`", segment.ident),
-                _ => "its receiver".to_string(),
-            }),
+            format!(
+                "this call modifies {} in-place",
+                match rcvr.kind {
+                    ExprKind::Path(QPath::Resolved(
+                        None,
+                        hir::Path { segments: [segment], .. },
+                    )) => format!("`{}`", segment.ident),
+                    _ => "its receiver".to_string(),
+                }
+            ),
         );
 
         let modifies_rcvr_note =
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 5ce9e0556b4..77081548d11 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -2641,8 +2641,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Returns the parameters of a function, with their generic parameters if those are the full
-    /// type of that parameter. Returns `None` if the function has no generics or the body is
-    /// unavailable (eg is an instrinsic).
+    /// type of that parameter.
+    ///
+    /// Returns `None` if the body is not a named function (e.g. a closure).
     fn get_hir_param_info(
         &self,
         def_id: DefId,
@@ -2667,6 +2668,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 kind: hir::ItemKind::Fn { sig, generics, body, .. },
                 ..
             }) => (sig, generics, Some(body), None),
+            hir::Node::ForeignItem(&hir::ForeignItem {
+                kind: hir::ForeignItemKind::Fn(sig, params, generics),
+                ..
+            }) => (sig, generics, None, Some(params)),
             _ => return None,
         };
 
@@ -2700,7 +2705,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ))
             }
             (None, Some(params)) => {
-                let params = params.get(is_method as usize..)?;
+                let params =
+                    params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?;
                 debug_assert_eq!(params.len(), fn_inputs.len());
                 Some((
                     fn_inputs.zip(params.iter().map(|param| FnParam::Name(param))).collect(),
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 217ebd9cd2b..4ec8d0b1f60 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1988,17 +1988,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             expr.kind,
             hir::ExprKind::Call(
                 hir::Expr {
-                    kind: hir::ExprKind::Path(hir::QPath::Resolved(None, hir::Path {
-                        res: Res::Def(hir::def::DefKind::Ctor(_, _), _),
-                        ..
-                    },)),
+                    kind: hir::ExprKind::Path(hir::QPath::Resolved(
+                        None,
+                        hir::Path { res: Res::Def(hir::def::DefKind::Ctor(_, _), _), .. },
+                    )),
                     ..
                 },
                 ..,
-            ) | hir::ExprKind::Path(hir::QPath::Resolved(None, hir::Path {
-                res: Res::Def(hir::def::DefKind::Ctor(_, _), _),
-                ..
-            },)),
+            ) | hir::ExprKind::Path(hir::QPath::Resolved(
+                None,
+                hir::Path { res: Res::Def(hir::def::DefKind::Ctor(_, _), _), .. },
+            )),
         );
 
         let (article, kind, variant, sugg_operator) =
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 5c1c38aeb95..3e48e8d15c3 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -347,9 +347,17 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         // yield an object-type (e.g., `&Object` or `Box<Object>`
         // etc).
 
-        // FIXME: this feels, like, super dubious
-        self.fcx
-            .autoderef(self.span, self_ty)
+        let mut autoderef = self.fcx.autoderef(self.span, self_ty);
+
+        // We don't need to gate this behind arbitrary self types
+        // per se, but it does make things a bit more gated.
+        if self.tcx.features().arbitrary_self_types()
+            || self.tcx.features().arbitrary_self_types_pointers()
+        {
+            autoderef = autoderef.use_receiver_trait();
+        }
+
+        autoderef
             .include_raw_pointers()
             .find_map(|(ty, _)| match ty.kind() {
                 ty::Dynamic(data, ..) => Some(closure(
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index cbbda0b6cbc..6c4ad65be6a 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3922,11 +3922,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 };
 
                             let all_suggs = candidate_strs.iter().map(|cand| {
-                                let suggestion = format!("{} {cand}", match introducer {
-                                    Introducer::Plus => " +",
-                                    Introducer::Colon => ":",
-                                    Introducer::Nothing => "",
-                                },);
+                                let suggestion = format!(
+                                    "{} {cand}",
+                                    match introducer {
+                                        Introducer::Plus => " +",
+                                        Introducer::Colon => ":",
+                                        Introducer::Nothing => "",
+                                    },
+                                );
 
                                 let mut suggs = vec![];
 
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index 47c1f784448..fc07c985849 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -918,13 +918,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let opname = Ident::with_dummy_span(opname);
         let (opt_rhs_expr, opt_rhs_ty) = opt_rhs.unzip();
-        let cause = self.cause(span, ObligationCauseCode::BinOp {
-            lhs_hir_id: lhs_expr.hir_id,
-            rhs_hir_id: opt_rhs_expr.map(|expr| expr.hir_id),
-            rhs_span: opt_rhs_expr.map(|expr| expr.span),
-            rhs_is_lit: opt_rhs_expr.is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
-            output_ty: expected.only_has_type(self),
-        });
+        let cause = self.cause(
+            span,
+            ObligationCauseCode::BinOp {
+                lhs_hir_id: lhs_expr.hir_id,
+                rhs_hir_id: opt_rhs_expr.map(|expr| expr.hir_id),
+                rhs_span: opt_rhs_expr.map(|expr| expr.span),
+                rhs_is_lit: opt_rhs_expr
+                    .is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
+                output_ty: expected.only_has_type(self),
+            },
+        );
 
         let method =
             self.lookup_method_in_trait(cause.clone(), opname, trait_did, lhs_ty, opt_rhs_ty);
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index e1bd9ae2e67..4fc903cf68b 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -30,10 +30,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ok = self.try_overloaded_deref(expr.span, oprnd_ty)?;
         let method = self.register_infer_ok_obligations(ok);
         if let ty::Ref(_, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() {
-            self.apply_adjustments(oprnd_expr, vec![Adjustment {
-                kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
-                target: method.sig.inputs()[0],
-            }]);
+            self.apply_adjustments(
+                oprnd_expr,
+                vec![Adjustment {
+                    kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
+                    target: method.sig.inputs()[0],
+                }],
+            );
         } else {
             span_bug!(expr.span, "input to deref is not a ref?");
         }
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index cac891c4e4c..c986429c1b2 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -288,11 +288,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     bug!();
                 };
                 let place = self.place_for_root_variable(closure_def_id, local_id);
-                delegate.capture_information.push((place, ty::CaptureInfo {
-                    capture_kind_expr_id: Some(init.hir_id),
-                    path_expr_id: Some(init.hir_id),
-                    capture_kind: UpvarCapture::ByValue,
-                }));
+                delegate.capture_information.push((
+                    place,
+                    ty::CaptureInfo {
+                        capture_kind_expr_id: Some(init.hir_id),
+                        path_expr_id: Some(init.hir_id),
+                        capture_kind: UpvarCapture::ByValue,
+                    },
+                ));
             }
         }
 
@@ -379,11 +382,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let UpvarArgs::CoroutineClosure(args) = args
             && !args.references_error()
         {
-            let closure_env_region: ty::Region<'_> =
-                ty::Region::new_bound(self.tcx, ty::INNERMOST, ty::BoundRegion {
-                    var: ty::BoundVar::ZERO,
-                    kind: ty::BoundRegionKind::ClosureEnv,
-                });
+            let closure_env_region: ty::Region<'_> = ty::Region::new_bound(
+                self.tcx,
+                ty::INNERMOST,
+                ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::ClosureEnv },
+            );
 
             let num_args = args
                 .as_coroutine_closure()
@@ -2009,11 +2012,14 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> {
         let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return };
         assert_eq!(self.closure_def_id, upvar_id.closure_expr_id);
 
-        self.capture_information.push((place_with_id.place.clone(), ty::CaptureInfo {
-            capture_kind_expr_id: Some(diag_expr_id),
-            path_expr_id: Some(diag_expr_id),
-            capture_kind: ty::UpvarCapture::ByValue,
-        }));
+        self.capture_information.push((
+            place_with_id.place.clone(),
+            ty::CaptureInfo {
+                capture_kind_expr_id: Some(diag_expr_id),
+                path_expr_id: Some(diag_expr_id),
+                capture_kind: ty::UpvarCapture::ByValue,
+            },
+        ));
     }
 
     #[instrument(skip(self), level = "debug")]
@@ -2040,11 +2046,14 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> {
             capture_kind = ty::UpvarCapture::ByRef(ty::BorrowKind::Immutable);
         }
 
-        self.capture_information.push((place, ty::CaptureInfo {
-            capture_kind_expr_id: Some(diag_expr_id),
-            path_expr_id: Some(diag_expr_id),
-            capture_kind,
-        }));
+        self.capture_information.push((
+            place,
+            ty::CaptureInfo {
+                capture_kind_expr_id: Some(diag_expr_id),
+                path_expr_id: Some(diag_expr_id),
+                capture_kind,
+            },
+        ));
     }
 
     #[instrument(skip(self), level = "debug")]
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 35e5c250f78..30590bf5d3c 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -107,11 +107,10 @@ const LABELS_FN_IN_TRAIT: &[&[&str]] =
 const LABELS_HIR_ONLY: &[&[&str]] = &[BASE_HIR];
 
 /// Impl `DepNode`s.
-const LABELS_TRAIT: &[&[&str]] = &[BASE_HIR, &[
-    label_strs::associated_item_def_ids,
-    label_strs::predicates_of,
-    label_strs::generics_of,
-]];
+const LABELS_TRAIT: &[&[&str]] = &[
+    BASE_HIR,
+    &[label_strs::associated_item_def_ids, label_strs::predicates_of, label_strs::generics_of],
+];
 
 /// Impl `DepNode`s.
 const LABELS_IMPL: &[&[&str]] = &[BASE_HIR, BASE_IMPL];
diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs
index eaa4aafe721..323a66ddc6f 100644
--- a/compiler/rustc_index/src/bit_set/tests.rs
+++ b/compiler/rustc_index/src/bit_set/tests.rs
@@ -118,11 +118,10 @@ fn chunked_bitset() {
     //-----------------------------------------------------------------------
 
     let mut b1 = ChunkedBitSet::<usize>::new_empty(1);
-    assert_eq!(b1, ChunkedBitSet {
-        domain_size: 1,
-        chunks: Box::new([Zeros(1)]),
-        marker: PhantomData
-    });
+    assert_eq!(
+        b1,
+        ChunkedBitSet { domain_size: 1, chunks: Box::new([Zeros(1)]), marker: PhantomData }
+    );
 
     b1.assert_valid();
     assert!(!b1.contains(0));
@@ -141,11 +140,10 @@ fn chunked_bitset() {
     //-----------------------------------------------------------------------
 
     let mut b100 = ChunkedBitSet::<usize>::new_filled(100);
-    assert_eq!(b100, ChunkedBitSet {
-        domain_size: 100,
-        chunks: Box::new([Ones(100)]),
-        marker: PhantomData
-    });
+    assert_eq!(
+        b100,
+        ChunkedBitSet { domain_size: 100, chunks: Box::new([Ones(100)]), marker: PhantomData }
+    );
 
     b100.assert_valid();
     for i in 0..100 {
@@ -160,17 +158,20 @@ fn chunked_bitset() {
     );
     assert_eq!(b100.count(), 97);
     assert!(!b100.contains(20) && b100.contains(30) && !b100.contains(99) && b100.contains(50));
-    assert_eq!(b100.chunks(), vec![Mixed(
-        100,
-        97,
-        #[rustfmt::skip]
+    assert_eq!(
+        b100.chunks(),
+        vec![Mixed(
+            100,
+            97,
+            #[rustfmt::skip]
             Rc::new([
                 0b11111111_11111111_11111110_11111111_11111111_11101111_11111111_11111111,
                 0b00000000_00000000_00000000_00000111_11111111_11111111_11111111_11111111,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0,
             ])
-    )],);
+        )],
+    );
     b100.assert_valid();
     let mut num_removed = 0;
     for i in 0..100 {
@@ -185,11 +186,14 @@ fn chunked_bitset() {
     //-----------------------------------------------------------------------
 
     let mut b2548 = ChunkedBitSet::<usize>::new_empty(2548);
-    assert_eq!(b2548, ChunkedBitSet {
-        domain_size: 2548,
-        chunks: Box::new([Zeros(2048), Zeros(500)]),
-        marker: PhantomData,
-    });
+    assert_eq!(
+        b2548,
+        ChunkedBitSet {
+            domain_size: 2548,
+            chunks: Box::new([Zeros(2048), Zeros(500)]),
+            marker: PhantomData,
+        }
+    );
 
     b2548.assert_valid();
     b2548.insert(14);
@@ -206,11 +210,14 @@ fn chunked_bitset() {
     //-----------------------------------------------------------------------
 
     let mut b4096 = ChunkedBitSet::<usize>::new_empty(4096);
-    assert_eq!(b4096, ChunkedBitSet {
-        domain_size: 4096,
-        chunks: Box::new([Zeros(2048), Zeros(2048)]),
-        marker: PhantomData,
-    });
+    assert_eq!(
+        b4096,
+        ChunkedBitSet {
+            domain_size: 4096,
+            chunks: Box::new([Zeros(2048), Zeros(2048)]),
+            marker: PhantomData,
+        }
+    );
 
     b4096.assert_valid();
     for i in 0..4096 {
@@ -240,11 +247,14 @@ fn chunked_bitset() {
     //-----------------------------------------------------------------------
 
     let mut b10000 = ChunkedBitSet::<usize>::new_empty(10000);
-    assert_eq!(b10000, ChunkedBitSet {
-        domain_size: 10000,
-        chunks: Box::new([Zeros(2048), Zeros(2048), Zeros(2048), Zeros(2048), Zeros(1808),]),
-        marker: PhantomData,
-    });
+    assert_eq!(
+        b10000,
+        ChunkedBitSet {
+            domain_size: 10000,
+            chunks: Box::new([Zeros(2048), Zeros(2048), Zeros(2048), Zeros(2048), Zeros(1808),]),
+            marker: PhantomData,
+        }
+    );
 
     b10000.assert_valid();
     assert!(b10000.insert(3000) && b10000.insert(5000));
diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs
index 9cee2f2f5b2..381d79c24fc 100644
--- a/compiler/rustc_index/src/vec/tests.rs
+++ b/compiler/rustc_index/src/vec/tests.rs
@@ -29,21 +29,19 @@ fn index_size_is_optimized() {
 #[test]
 fn range_iterator_iterates_forwards() {
     let range = MyIdx::from_u32(1)..MyIdx::from_u32(4);
-    assert_eq!(range.collect::<Vec<_>>(), [
-        MyIdx::from_u32(1),
-        MyIdx::from_u32(2),
-        MyIdx::from_u32(3)
-    ]);
+    assert_eq!(
+        range.collect::<Vec<_>>(),
+        [MyIdx::from_u32(1), MyIdx::from_u32(2), MyIdx::from_u32(3)]
+    );
 }
 
 #[test]
 fn range_iterator_iterates_backwards() {
     let range = MyIdx::from_u32(1)..MyIdx::from_u32(4);
-    assert_eq!(range.rev().collect::<Vec<_>>(), [
-        MyIdx::from_u32(3),
-        MyIdx::from_u32(2),
-        MyIdx::from_u32(1)
-    ]);
+    assert_eq!(
+        range.rev().collect::<Vec<_>>(),
+        [MyIdx::from_u32(3), MyIdx::from_u32(2), MyIdx::from_u32(1)]
+    );
 }
 
 #[test]
diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
index c02ab98b2ba..379410641fe 100644
--- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
+++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
@@ -48,7 +48,7 @@ where
             return ty.super_visit_with(self);
         }
 
-        match ty.kind() {
+        match *ty.kind() {
             // We can prove that an alias is live two ways:
             // 1. All the components are live.
             //
@@ -95,11 +95,9 @@ where
                     assert!(r.type_flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS));
                     r.visit_with(self);
                 } else {
-                    // Skip lifetime parameters that are not captures.
-                    let variances = match kind {
-                        ty::Opaque => Some(self.tcx.variances_of(*def_id)),
-                        _ => None,
-                    };
+                    // Skip lifetime parameters that are not captured, since they do
+                    // not need to be live.
+                    let variances = tcx.opt_alias_variances(kind, def_id);
 
                     for (idx, s) in args.iter().enumerate() {
                         if variances.map(|variances| variances[idx]) != Some(ty::Bivariant) {
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 84e51b18dc5..a89cef50c9b 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -100,16 +100,20 @@ impl<'tcx> InferCtxt<'tcx> {
     ) {
         debug!(?sup_type, ?sub_region, ?cause);
         let origin = SubregionOrigin::from_obligation_cause(cause, || {
-            infer::RelateParamBound(cause.span, sup_type, match cause.code().peel_derives() {
-                ObligationCauseCode::WhereClause(_, span)
-                | ObligationCauseCode::WhereClauseInExpr(_, span, ..)
-                | ObligationCauseCode::OpaqueTypeBound(span, _)
-                    if !span.is_dummy() =>
-                {
-                    Some(*span)
-                }
-                _ => None,
-            })
+            infer::RelateParamBound(
+                cause.span,
+                sup_type,
+                match cause.code().peel_derives() {
+                    ObligationCauseCode::WhereClause(_, span)
+                    | ObligationCauseCode::WhereClauseInExpr(_, span, ..)
+                    | ObligationCauseCode::OpaqueTypeBound(span, _)
+                        if !span.is_dummy() =>
+                    {
+                        Some(*span)
+                    }
+                    _ => None,
+                },
+            )
         });
 
         self.register_region_obligation(RegionObligation { sup_type, sub_region, origin });
@@ -392,13 +396,13 @@ where
         // the problem is to add `T: 'r`, which isn't true. So, if there are no
         // inference variables, we use a verify constraint instead of adding
         // edges, which winds up enforcing the same condition.
-        let is_opaque = alias_ty.kind(self.tcx) == ty::Opaque;
+        let kind = alias_ty.kind(self.tcx);
         if approx_env_bounds.is_empty()
             && trait_bounds.is_empty()
-            && (alias_ty.has_infer_regions() || is_opaque)
+            && (alias_ty.has_infer_regions() || kind == ty::Opaque)
         {
             debug!("no declared bounds");
-            let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id));
+            let opt_variances = self.tcx.opt_alias_variances(kind, alias_ty.def_id);
             self.args_must_outlive(alias_ty.args, origin, region, opt_variances);
             return;
         }
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index d68f3639176..c14c288c6e4 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -102,12 +102,11 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
 
     #[instrument(level = "debug", skip(self))]
     pub(crate) fn alias_bound(&self, alias_ty: ty::AliasTy<'tcx>) -> VerifyBound<'tcx> {
-        let alias_ty_as_ty = alias_ty.to_ty(self.tcx);
-
         // Search the env for where clauses like `P: 'a`.
         let env_bounds = self.approx_declared_bounds_from_env(alias_ty).into_iter().map(|binder| {
             if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars()
-                && ty == alias_ty_as_ty
+                && let ty::Alias(_, alias_ty_from_bound) = *ty.kind()
+                && alias_ty_from_bound == alias_ty
             {
                 // Micro-optimize if this is an exact match (this
                 // occurs often when there are no region variables
@@ -127,7 +126,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         // see the extensive comment in projection_must_outlive
         let recursive_bound = {
             let mut components = smallvec![];
-            compute_alias_components_recursive(self.tcx, alias_ty_as_ty, &mut components);
+            let kind = alias_ty.kind(self.tcx);
+            compute_alias_components_recursive(self.tcx, kind, alias_ty, &mut components);
             self.bound_from_components(&components)
         };
 
diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index 061f7e6c22a..0998f3c4790 100644
--- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -34,22 +34,22 @@ impl<'tcx> InferCtxt<'tcx> {
 
         let delegate = FnMutDelegate {
             regions: &mut |br: ty::BoundRegion| {
-                ty::Region::new_placeholder(self.tcx, ty::PlaceholderRegion {
-                    universe: next_universe,
-                    bound: br,
-                })
+                ty::Region::new_placeholder(
+                    self.tcx,
+                    ty::PlaceholderRegion { universe: next_universe, bound: br },
+                )
             },
             types: &mut |bound_ty: ty::BoundTy| {
-                Ty::new_placeholder(self.tcx, ty::PlaceholderType {
-                    universe: next_universe,
-                    bound: bound_ty,
-                })
+                Ty::new_placeholder(
+                    self.tcx,
+                    ty::PlaceholderType { universe: next_universe, bound: bound_ty },
+                )
             },
             consts: &mut |bound_var: ty::BoundVar| {
-                ty::Const::new_placeholder(self.tcx, ty::PlaceholderConst {
-                    universe: next_universe,
-                    bound: bound_var,
-                })
+                ty::Const::new_placeholder(
+                    self.tcx,
+                    ty::PlaceholderConst { universe: next_universe, bound: bound_var },
+                )
             },
         };
 
diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs
index 51282b900ed..1eae10673b6 100644
--- a/compiler/rustc_infer/src/traits/engine.rs
+++ b/compiler/rustc_infer/src/traits/engine.rs
@@ -45,12 +45,15 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
         cause: ObligationCause<'tcx>,
     ) {
         let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
-        self.register_predicate_obligation(infcx, Obligation {
-            cause,
-            recursion_depth: 0,
-            param_env,
-            predicate: trait_ref.upcast(infcx.tcx),
-        });
+        self.register_predicate_obligation(
+            infcx,
+            Obligation {
+                cause,
+                recursion_depth: 0,
+                param_env,
+                predicate: trait_ref.upcast(infcx.tcx),
+            },
+        );
     }
 
     fn register_predicate_obligation(
diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs
index cab2ce9f5a0..9082db4f448 100644
--- a/compiler/rustc_infer/src/traits/project.rs
+++ b/compiler/rustc_infer/src/traits/project.rs
@@ -193,10 +193,10 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
                 if result.must_apply_considering_regions() {
                     ty.obligations = PredicateObligations::new();
                 }
-                map.insert(key, ProjectionCacheEntry::NormalizedTerm {
-                    ty,
-                    complete: Some(result),
-                });
+                map.insert(
+                    key,
+                    ProjectionCacheEntry::NormalizedTerm { ty, complete: Some(result) },
+                );
             }
             ref value => {
                 // Type inference could "strand behind" old cache entries. Leave
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index dcb9c5d22d6..295a988d2da 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2021"
 # tidy-alphabetical-start
 rustc-rayon = { version = "0.5.0" }
 rustc-rayon-core = { version = "0.5.0" }
+rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_lowering = { path = "../rustc_ast_lowering" }
 rustc_ast_passes = { path = "../rustc_ast_passes" }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index eda9c4e03fe..e5adcdb244f 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -827,7 +827,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
     if tcx.sess.opts.unstable_opts.input_stats {
         rustc_passes::input_stats::print_hir_stats(tcx);
     }
-    #[cfg(debug_assertions)]
+    // When using rustdoc's "jump to def" feature, it enters this code and `check_crate`
+    // is not defined. So we need to cfg it out.
+    #[cfg(all(not(doc), debug_assertions))]
     rustc_passes::hir_id_validator::check_crate(tcx);
     let sess = tcx.sess;
     sess.time("misc_checking_1", || {
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 46d6f37a91c..233bfcb5297 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -4,6 +4,7 @@ use std::num::NonZero;
 use std::path::{Path, PathBuf};
 use std::sync::atomic::AtomicBool;
 
+use rustc_abi::Align;
 use rustc_data_structures::profiling::TimePassesFormat;
 use rustc_errors::emitter::HumanReadableErrorType;
 use rustc_errors::{ColorConfig, registry};
@@ -24,7 +25,6 @@ use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, build_session, filesearc
 use rustc_span::edition::{DEFAULT_EDITION, Edition};
 use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
 use rustc_span::{FileName, SourceFileHashAlgorithm, sym};
-use rustc_target::abi::Align;
 use rustc_target::spec::{
     CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
     RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel, WasmCAbi,
@@ -770,11 +770,14 @@ fn test_unstable_options_tracking_hash() {
         })
     );
     tracked!(codegen_backend, Some("abc".to_string()));
-    tracked!(coverage_options, CoverageOptions {
-        level: CoverageLevel::Mcdc,
-        no_mir_spans: true,
-        discard_all_spans_in_codegen: true
-    });
+    tracked!(
+        coverage_options,
+        CoverageOptions {
+            level: CoverageLevel::Mcdc,
+            no_mir_spans: true,
+            discard_all_spans_in_codegen: true
+        }
+    );
     tracked!(crate_attr, vec!["abc".to_string()]);
     tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
     tracked!(debug_info_for_profiling, true);
diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs
index db7225fc2a8..8203ae70b07 100644
--- a/compiler/rustc_lexer/src/tests.rs
+++ b/compiler/rustc_lexer/src/tests.rs
@@ -131,7 +131,9 @@ fn check_lexing(src: &str, expect: Expect) {
 
 #[test]
 fn smoke_test() {
-    check_lexing("/* my source file */ fn main() { println!(\"zebra\"); }\n", expect![[r#"
+    check_lexing(
+        "/* my source file */ fn main() { println!(\"zebra\"); }\n",
+        expect![[r#"
             Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 }
             Token { kind: Whitespace, len: 1 }
             Token { kind: Ident, len: 2 }
@@ -151,7 +153,8 @@ fn smoke_test() {
             Token { kind: Whitespace, len: 1 }
             Token { kind: CloseBrace, len: 1 }
             Token { kind: Whitespace, len: 1 }
-        "#]])
+        "#]],
+    )
 }
 
 #[test]
@@ -194,35 +197,47 @@ fn comment_flavors() {
 
 #[test]
 fn nested_block_comments() {
-    check_lexing("/* /* */ */'a'", expect![[r#"
+    check_lexing(
+        "/* /* */ */'a'",
+        expect![[r#"
             Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
-        "#]])
+        "#]],
+    )
 }
 
 #[test]
 fn characters() {
-    check_lexing("'a' ' ' '\\n'", expect![[r#"
+    check_lexing(
+        "'a' ' ' '\\n'",
+        expect![[r#"
             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
             Token { kind: Whitespace, len: 1 }
             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
             Token { kind: Whitespace, len: 1 }
             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 4 }, len: 4 }
-        "#]]);
+        "#]],
+    );
 }
 
 #[test]
 fn lifetime() {
-    check_lexing("'abc", expect![[r#"
+    check_lexing(
+        "'abc",
+        expect![[r#"
             Token { kind: Lifetime { starts_with_number: false }, len: 4 }
-        "#]]);
+        "#]],
+    );
 }
 
 #[test]
 fn raw_string() {
-    check_lexing("r###\"\"#a\\b\x00c\"\"###", expect![[r#"
+    check_lexing(
+        "r###\"\"#a\\b\x00c\"\"###",
+        expect![[r#"
             Token { kind: Literal { kind: RawStr { n_hashes: Some(3) }, suffix_start: 17 }, len: 17 }
-        "#]])
+        "#]],
+    )
 }
 
 #[test]
diff --git a/compiler/rustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs
index 6fa7a150516..5b99495f475 100644
--- a/compiler/rustc_lexer/src/unescape/tests.rs
+++ b/compiler/rustc_lexer/src/unescape/tests.rs
@@ -108,12 +108,15 @@ fn test_unescape_str_warn() {
     check("\\\n", &[]);
     check("\\\n ", &[]);
 
-    check("\\\n \u{a0} x", &[
-        (0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
-        (3..5, Ok('\u{a0}')),
-        (5..6, Ok(' ')),
-        (6..7, Ok('x')),
-    ]);
+    check(
+        "\\\n \u{a0} x",
+        &[
+            (0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
+            (3..5, Ok('\u{a0}')),
+            (5..6, Ok(' ')),
+            (6..7, Ok('x')),
+        ],
+    );
     check("\\\n  \n  x", &[(0..7, Err(EscapeError::MultipleSkippedLinesWarning)), (7..8, Ok('x'))]);
 }
 
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index e2bafbed6e1..5e6b854ff52 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -102,10 +102,11 @@ impl EarlyLintPass for WhileTrue {
                 "{}loop",
                 label.map_or_else(String::new, |label| format!("{}: ", label.ident,))
             );
-            cx.emit_span_lint(WHILE_TRUE, condition_span, BuiltinWhileTrue {
-                suggestion: condition_span,
-                replace,
-            });
+            cx.emit_span_lint(
+                WHILE_TRUE,
+                condition_span,
+                BuiltinWhileTrue { suggestion: condition_span, replace },
+            );
         }
     }
 }
@@ -421,10 +422,11 @@ impl MissingDoc {
         let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id));
         let has_doc = attrs.iter().any(has_doc);
         if !has_doc {
-            cx.emit_span_lint(MISSING_DOCS, cx.tcx.def_span(def_id), BuiltinMissingDoc {
-                article,
-                desc,
-            });
+            cx.emit_span_lint(
+                MISSING_DOCS,
+                cx.tcx.def_span(def_id),
+                BuiltinMissingDoc { article, desc },
+            );
         }
     }
 }
@@ -706,10 +708,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
             .next()
             .is_some();
         if !has_impl {
-            cx.emit_span_lint(MISSING_DEBUG_IMPLEMENTATIONS, item.span, BuiltinMissingDebugImpl {
-                tcx: cx.tcx,
-                def_id: debug,
-            });
+            cx.emit_span_lint(
+                MISSING_DEBUG_IMPLEMENTATIONS,
+                item.span,
+                BuiltinMissingDebugImpl { tcx: cx.tcx, def_id: debug },
+            );
         }
     }
 }
@@ -831,12 +834,11 @@ impl EarlyLintPass for DeprecatedAttr {
                             BuiltinDeprecatedAttrLinkSuggestion::Default { suggestion: attr.span }
                         }
                     };
-                    cx.emit_span_lint(DEPRECATED, attr.span, BuiltinDeprecatedAttrLink {
-                        name,
-                        reason,
-                        link,
-                        suggestion,
-                    });
+                    cx.emit_span_lint(
+                        DEPRECATED,
+                        attr.span,
+                        BuiltinDeprecatedAttrLink { name, reason, link, suggestion },
+                    );
                 }
                 return;
             }
@@ -874,11 +876,11 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
                     BuiltinUnusedDocCommentSub::BlockHelp
                 }
             };
-            cx.emit_span_lint(UNUSED_DOC_COMMENTS, span, BuiltinUnusedDocComment {
-                kind: node_kind,
-                label: node_span,
-                sub,
-            });
+            cx.emit_span_lint(
+                UNUSED_DOC_COMMENTS,
+                span,
+                BuiltinUnusedDocComment { kind: node_kind, label: node_span, sub },
+            );
         }
     }
 }
@@ -1008,9 +1010,11 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
                 match param.kind {
                     GenericParamKind::Lifetime { .. } => {}
                     GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
-                        cx.emit_span_lint(NO_MANGLE_GENERIC_ITEMS, span, BuiltinNoMangleGeneric {
-                            suggestion: no_mangle_attr.span,
-                        });
+                        cx.emit_span_lint(
+                            NO_MANGLE_GENERIC_ITEMS,
+                            span,
+                            BuiltinNoMangleGeneric { suggestion: no_mangle_attr.span },
+                        );
                         break;
                     }
                 }
@@ -1037,9 +1041,11 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
 
                     // Const items do not refer to a particular location in memory, and therefore
                     // don't have anything to attach a symbol to
-                    cx.emit_span_lint(NO_MANGLE_CONST_ITEMS, it.span, BuiltinConstNoMangle {
-                        suggestion,
-                    });
+                    cx.emit_span_lint(
+                        NO_MANGLE_CONST_ITEMS,
+                        it.span,
+                        BuiltinConstNoMangle { suggestion },
+                    );
                 }
             }
             hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => {
@@ -1305,12 +1311,16 @@ impl UnreachablePub {
                 applicability = Applicability::MaybeIncorrect;
             }
             let def_span = cx.tcx.def_span(def_id);
-            cx.emit_span_lint(UNREACHABLE_PUB, def_span, BuiltinUnreachablePub {
-                what,
-                new_vis,
-                suggestion: (vis_span, applicability),
-                help: exportable,
-            });
+            cx.emit_span_lint(
+                UNREACHABLE_PUB,
+                def_span,
+                BuiltinUnreachablePub {
+                    what,
+                    new_vis,
+                    suggestion: (vis_span, applicability),
+                    help: exportable,
+                },
+            );
         }
     }
 }
@@ -1454,24 +1464,32 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
         let enable_feat_help = cx.tcx.sess.is_nightly_build();
 
         if let [.., label_sp] = *where_spans {
-            cx.emit_span_lint(TYPE_ALIAS_BOUNDS, where_spans, BuiltinTypeAliasBounds {
-                in_where_clause: true,
-                label: label_sp,
-                enable_feat_help,
-                suggestions: vec![(generics.where_clause_span, String::new())],
-                preds: generics.predicates,
-                ty: ty.take(),
-            });
+            cx.emit_span_lint(
+                TYPE_ALIAS_BOUNDS,
+                where_spans,
+                BuiltinTypeAliasBounds {
+                    in_where_clause: true,
+                    label: label_sp,
+                    enable_feat_help,
+                    suggestions: vec![(generics.where_clause_span, String::new())],
+                    preds: generics.predicates,
+                    ty: ty.take(),
+                },
+            );
         }
         if let [.., label_sp] = *inline_spans {
-            cx.emit_span_lint(TYPE_ALIAS_BOUNDS, inline_spans, BuiltinTypeAliasBounds {
-                in_where_clause: false,
-                label: label_sp,
-                enable_feat_help,
-                suggestions: inline_sugg,
-                preds: generics.predicates,
-                ty,
-            });
+            cx.emit_span_lint(
+                TYPE_ALIAS_BOUNDS,
+                inline_spans,
+                BuiltinTypeAliasBounds {
+                    in_where_clause: false,
+                    label: label_sp,
+                    enable_feat_help,
+                    suggestions: inline_sugg,
+                    preds: generics.predicates,
+                    ty,
+                },
+            );
         }
     }
 }
@@ -1559,10 +1577,11 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
                     | ty::ClauseKind::HostEffect(..) => continue,
                 };
                 if predicate.is_global() {
-                    cx.emit_span_lint(TRIVIAL_BOUNDS, span, BuiltinTrivialBounds {
-                        predicate_kind_name,
-                        predicate,
-                    });
+                    cx.emit_span_lint(
+                        TRIVIAL_BOUNDS,
+                        span,
+                        BuiltinTrivialBounds { predicate_kind_name, predicate },
+                    );
                 }
             }
         }
@@ -1611,12 +1630,16 @@ impl EarlyLintPass for DoubleNegations {
             && let ExprKind::Unary(UnOp::Neg, ref inner2) = inner.kind
             && !matches!(inner2.kind, ExprKind::Unary(UnOp::Neg, _))
         {
-            cx.emit_span_lint(DOUBLE_NEGATIONS, expr.span, BuiltinDoubleNegations {
-                add_parens: BuiltinDoubleNegationsAddParens {
-                    start_span: inner.span.shrink_to_lo(),
-                    end_span: inner.span.shrink_to_hi(),
+            cx.emit_span_lint(
+                DOUBLE_NEGATIONS,
+                expr.span,
+                BuiltinDoubleNegations {
+                    add_parens: BuiltinDoubleNegationsAddParens {
+                        start_span: inner.span.shrink_to_lo(),
+                        end_span: inner.span.shrink_to_hi(),
+                    },
                 },
-            });
+            );
         }
     }
 }
@@ -1931,12 +1954,11 @@ impl KeywordIdents {
             return;
         }
 
-        cx.emit_span_lint(lint, ident.span, BuiltinKeywordIdents {
-            kw: ident,
-            next: edition,
-            suggestion: ident.span,
-            prefix,
-        });
+        cx.emit_span_lint(
+            lint,
+            ident.span,
+            BuiltinKeywordIdents { kw: ident, next: edition, suggestion: ident.span, prefix },
+        );
     }
 }
 
@@ -2357,11 +2379,11 @@ impl EarlyLintPass for IncompleteInternalFeatures {
                     let help =
                         HAS_MIN_FEATURES.contains(&name).then_some(BuiltinIncompleteFeaturesHelp);
 
-                    cx.emit_span_lint(INCOMPLETE_FEATURES, span, BuiltinIncompleteFeatures {
-                        name,
-                        note,
-                        help,
-                    });
+                    cx.emit_span_lint(
+                        INCOMPLETE_FEATURES,
+                        span,
+                        BuiltinIncompleteFeatures { name, note, help },
+                    );
                 } else {
                     cx.emit_span_lint(INTERNAL_FEATURES, span, BuiltinInternalFeatures { name });
                 }
@@ -2684,13 +2706,17 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
                     InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_uninit,
                 };
                 let sub = BuiltinUnpermittedTypeInitSub { err };
-                cx.emit_span_lint(INVALID_VALUE, expr.span, BuiltinUnpermittedTypeInit {
-                    msg,
-                    ty: conjured_ty,
-                    label: expr.span,
-                    sub,
-                    tcx: cx.tcx,
-                });
+                cx.emit_span_lint(
+                    INVALID_VALUE,
+                    expr.span,
+                    BuiltinUnpermittedTypeInit {
+                        msg,
+                        ty: conjured_ty,
+                        label: expr.span,
+                        sub,
+                        tcx: cx.tcx,
+                    },
+                );
             }
         }
     }
@@ -2776,9 +2802,11 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
             {
                 // `&raw *NULL` is ok.
             } else {
-                cx.emit_span_lint(DEREF_NULLPTR, expr.span, BuiltinDerefNullptr {
-                    label: expr.span,
-                });
+                cx.emit_span_lint(
+                    DEREF_NULLPTR,
+                    expr.span,
+                    BuiltinDerefNullptr { label: expr.span },
+                );
             }
         }
     }
@@ -2995,14 +3023,18 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels {
                     let span = span.unwrap_or(*template_span);
                     match label_kind {
                         AsmLabelKind::Named => {
-                            cx.emit_span_lint(NAMED_ASM_LABELS, span, InvalidAsmLabel::Named {
-                                missing_precise_span,
-                            });
+                            cx.emit_span_lint(
+                                NAMED_ASM_LABELS,
+                                span,
+                                InvalidAsmLabel::Named { missing_precise_span },
+                            );
                         }
                         AsmLabelKind::FormatArg => {
-                            cx.emit_span_lint(NAMED_ASM_LABELS, span, InvalidAsmLabel::FormatArg {
-                                missing_precise_span,
-                            });
+                            cx.emit_span_lint(
+                                NAMED_ASM_LABELS,
+                                span,
+                                InvalidAsmLabel::FormatArg { missing_precise_span },
+                            );
                         }
                         // the binary asm issue only occurs when using intel syntax on x86 targets
                         AsmLabelKind::Binary
@@ -3012,10 +3044,11 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels {
                                     Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) | None
                                 ) =>
                         {
-                            cx.emit_span_lint(BINARY_ASM_LABELS, span, InvalidAsmLabel::Binary {
-                                missing_precise_span,
+                            cx.emit_span_lint(
+                                BINARY_ASM_LABELS,
                                 span,
-                            })
+                                InvalidAsmLabel::Binary { missing_precise_span, span },
+                            )
                         }
                         // No lint on anything other than x86
                         AsmLabelKind::Binary => (),
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index e0863aa035c..a67b404e6e1 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -233,11 +233,14 @@ impl LintStore {
     }
 
     pub fn register_group_alias(&mut self, lint_name: &'static str, alias: &'static str) {
-        self.lint_groups.insert(alias, LintGroup {
-            lint_ids: vec![],
-            is_externally_loaded: false,
-            depr: Some(LintAlias { name: lint_name, silent: true }),
-        });
+        self.lint_groups.insert(
+            alias,
+            LintGroup {
+                lint_ids: vec![],
+                is_externally_loaded: false,
+                depr: Some(LintAlias { name: lint_name, silent: true }),
+            },
+        );
     }
 
     pub fn register_group(
@@ -252,11 +255,14 @@ impl LintStore {
             .insert(name, LintGroup { lint_ids: to, is_externally_loaded, depr: None })
             .is_none();
         if let Some(deprecated) = deprecated_name {
-            self.lint_groups.insert(deprecated, LintGroup {
-                lint_ids: vec![],
-                is_externally_loaded,
-                depr: Some(LintAlias { name, silent: false }),
-            });
+            self.lint_groups.insert(
+                deprecated,
+                LintGroup {
+                    lint_ids: vec![],
+                    is_externally_loaded,
+                    depr: Some(LintAlias { name, silent: false }),
+                },
+            );
         }
 
         if !new {
diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
index 181f44fb4de..f418d6d8753 100644
--- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
+++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
@@ -85,14 +85,19 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
                 .find_map(|i| (i.ident.name == sym::Target).then_some(i.span))
                 .map(|label| SupertraitAsDerefTargetLabel { label });
             let span = tcx.def_span(item.owner_id.def_id);
-            cx.emit_span_lint(DEREF_INTO_DYN_SUPERTRAIT, span, SupertraitAsDerefTarget {
-                self_ty,
-                supertrait_principal: supertrait_principal
-                    .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)),
-                target_principal,
-                label: span,
-                label2,
-            });
+            cx.emit_span_lint(
+                DEREF_INTO_DYN_SUPERTRAIT,
+                span,
+                SupertraitAsDerefTarget {
+                    self_ty,
+                    supertrait_principal: supertrait_principal.map_bound(|trait_ref| {
+                        ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+                    }),
+                    target_principal,
+                    label: span,
+                    label2,
+                },
+            );
         }
     }
 }
diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs
index ce23892508b..1ca2e4e74ea 100644
--- a/compiler/rustc_lint/src/drop_forget_useless.rs
+++ b/compiler/rustc_lint/src/drop_forget_useless.rs
@@ -163,32 +163,44 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
             };
             match fn_name {
                 sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
-                    cx.emit_span_lint(DROPPING_REFERENCES, expr.span, DropRefDiag {
-                        arg_ty,
-                        label: arg.span,
-                        sugg: let_underscore_ignore_sugg(),
-                    });
+                    cx.emit_span_lint(
+                        DROPPING_REFERENCES,
+                        expr.span,
+                        DropRefDiag { arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg() },
+                    );
                 }
                 sym::mem_forget if arg_ty.is_ref() => {
-                    cx.emit_span_lint(FORGETTING_REFERENCES, expr.span, ForgetRefDiag {
-                        arg_ty,
-                        label: arg.span,
-                        sugg: let_underscore_ignore_sugg(),
-                    });
+                    cx.emit_span_lint(
+                        FORGETTING_REFERENCES,
+                        expr.span,
+                        ForgetRefDiag {
+                            arg_ty,
+                            label: arg.span,
+                            sugg: let_underscore_ignore_sugg(),
+                        },
+                    );
                 }
                 sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {
-                    cx.emit_span_lint(DROPPING_COPY_TYPES, expr.span, DropCopyDiag {
-                        arg_ty,
-                        label: arg.span,
-                        sugg: let_underscore_ignore_sugg(),
-                    });
+                    cx.emit_span_lint(
+                        DROPPING_COPY_TYPES,
+                        expr.span,
+                        DropCopyDiag {
+                            arg_ty,
+                            label: arg.span,
+                            sugg: let_underscore_ignore_sugg(),
+                        },
+                    );
                 }
                 sym::mem_forget if is_copy => {
-                    cx.emit_span_lint(FORGETTING_COPY_TYPES, expr.span, ForgetCopyDiag {
-                        arg_ty,
-                        label: arg.span,
-                        sugg: let_underscore_ignore_sugg(),
-                    });
+                    cx.emit_span_lint(
+                        FORGETTING_COPY_TYPES,
+                        expr.span,
+                        ForgetCopyDiag {
+                            arg_ty,
+                            label: arg.span,
+                            sugg: let_underscore_ignore_sugg(),
+                        },
+                    );
                 }
                 sym::mem_drop
                     if let ty::Adt(adt, _) = arg_ty.kind()
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index bc7cd3d118c..723b894c43b 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -246,6 +246,14 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
                 }
             }
             ast_visit::walk_assoc_item(cx, item, ctxt);
+            match ctxt {
+                ast_visit::AssocCtxt::Trait => {
+                    lint_callback!(cx, check_trait_item_post, item);
+                }
+                ast_visit::AssocCtxt::Impl => {
+                    lint_callback!(cx, check_impl_item_post, item);
+                }
+            }
         });
     }
 
diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
index 6556a8d8f2d..7ead8eafbd5 100644
--- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
+++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
@@ -54,10 +54,11 @@ fn enforce_mem_discriminant(
 ) {
     let ty_param = cx.typeck_results().node_args(func_expr.hir_id).type_at(0);
     if is_non_enum(ty_param) {
-        cx.emit_span_lint(ENUM_INTRINSICS_NON_ENUMS, expr_span, EnumIntrinsicsMemDiscriminate {
-            ty_param,
-            note: args_span,
-        });
+        cx.emit_span_lint(
+            ENUM_INTRINSICS_NON_ENUMS,
+            expr_span,
+            EnumIntrinsicsMemDiscriminate { ty_param, note: args_span },
+        );
     }
 }
 
diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
index dbc920ea5ae..0a5c52d65ec 100644
--- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs
+++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
@@ -96,14 +96,11 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
             end_span: pat.span.between(arg.span),
         };
 
-        cx.emit_span_lint(FOR_LOOPS_OVER_FALLIBLES, arg.span, ForLoopsOverFalliblesDiag {
-            article,
-            ref_prefix,
-            ty,
-            sub,
-            question_mark,
-            suggestion,
-        });
+        cx.emit_span_lint(
+            FOR_LOOPS_OVER_FALLIBLES,
+            arg.span,
+            ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
+        );
     }
 }
 
diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
index 406aa1005df..491c2826baa 100644
--- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
+++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
@@ -74,13 +74,11 @@ impl HiddenUnicodeCodepoints {
             HiddenUnicodeCodepointsDiagSub::NoEscape { spans }
         };
 
-        cx.emit_span_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, span, HiddenUnicodeCodepointsDiag {
-            label,
-            count,
-            span_label: span,
-            labels,
-            sub,
-        });
+        cx.emit_span_lint(
+            TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
+            span,
+            HiddenUnicodeCodepointsDiag { label, count, span_label: span, labels, sub },
+        );
     }
 
     fn check_literal(
diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs
index b5a6159bd0a..869dab6799d 100644
--- a/compiler/rustc_lint/src/if_let_rescope.rs
+++ b/compiler/rustc_lint/src/if_let_rescope.rs
@@ -221,20 +221,25 @@ impl IfLetRescope {
             }
         }
         if let Some((span, hir_id)) = first_if_to_lint {
-            tcx.emit_node_span_lint(IF_LET_RESCOPE, hir_id, span, IfLetRescopeLint {
-                significant_droppers,
-                lifetime_ends,
-                rewrite: first_if_to_rewrite.then_some(IfLetRescopeRewrite {
-                    match_heads,
-                    consequent_heads,
-                    closing_brackets: ClosingBrackets {
-                        span: expr_end,
-                        count: closing_brackets,
-                        empty_alt,
-                    },
-                    alt_heads,
-                }),
-            });
+            tcx.emit_node_span_lint(
+                IF_LET_RESCOPE,
+                hir_id,
+                span,
+                IfLetRescopeLint {
+                    significant_droppers,
+                    lifetime_ends,
+                    rewrite: first_if_to_rewrite.then_some(IfLetRescopeRewrite {
+                        match_heads,
+                        consequent_heads,
+                        closing_brackets: ClosingBrackets {
+                            span: expr_end,
+                            count: closing_brackets,
+                            empty_alt,
+                        },
+                        alt_heads,
+                    }),
+                },
+            );
         }
     }
 }
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index d251b4b7459..d2956d94685 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -314,12 +314,10 @@ where
                     // We only computed variance of lifetimes...
                     debug_assert_matches!(self.tcx.def_kind(def_id), DefKind::LifetimeParam);
                     let uncaptured = match *kind {
-                        ParamKind::Early(name, index) => {
-                            ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
-                                name,
-                                index,
-                            })
-                        }
+                        ParamKind::Early(name, index) => ty::Region::new_early_param(
+                            self.tcx,
+                            ty::EarlyParamRegion { name, index },
+                        ),
                         ParamKind::Free(def_id, name) => ty::Region::new_late_param(
                             self.tcx,
                             self.parent_def_id.to_def_id(),
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 546df4497ad..ddc9ae1594f 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -48,10 +48,11 @@ impl LateLintPass<'_> for DefaultHashTypes {
             Some(sym::HashSet) => "FxHashSet",
             _ => return,
         };
-        cx.emit_span_lint(DEFAULT_HASH_TYPES, path.span, DefaultHashTypesDiag {
-            preferred,
-            used: cx.tcx.item_name(def_id),
-        });
+        cx.emit_span_lint(
+            DEFAULT_HASH_TYPES,
+            path.span,
+            DefaultHashTypesDiag { preferred, used: cx.tcx.item_name(def_id) },
+        );
     }
 }
 
@@ -107,14 +108,18 @@ impl LateLintPass<'_> for QueryStability {
         {
             let def_id = instance.def_id();
             if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
-                cx.emit_span_lint(POTENTIAL_QUERY_INSTABILITY, span, QueryInstability {
-                    query: cx.tcx.item_name(def_id),
-                });
+                cx.emit_span_lint(
+                    POTENTIAL_QUERY_INSTABILITY,
+                    span,
+                    QueryInstability { query: cx.tcx.item_name(def_id) },
+                );
             }
             if cx.tcx.has_attr(def_id, sym::rustc_lint_untracked_query_information) {
-                cx.emit_span_lint(UNTRACKED_QUERY_INFORMATION, span, QueryUntracked {
-                    method: cx.tcx.item_name(def_id),
-                });
+                cx.emit_span_lint(
+                    UNTRACKED_QUERY_INFORMATION,
+                    span,
+                    QueryUntracked { method: cx.tcx.item_name(def_id) },
+                );
             }
         }
     }
@@ -186,9 +191,11 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
 
                     match span {
                         Some(span) => {
-                            cx.emit_span_lint(USAGE_OF_TY_TYKIND, path.span, TykindKind {
-                                suggestion: span,
-                            });
+                            cx.emit_span_lint(
+                                USAGE_OF_TY_TYKIND,
+                                path.span,
+                                TykindKind { suggestion: span },
+                            );
                         }
                         None => cx.emit_span_lint(USAGE_OF_TY_TYKIND, path.span, TykindDiag),
                     }
@@ -196,10 +203,11 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
                     && path.segments.len() > 1
                     && let Some(ty) = is_ty_or_ty_ctxt(cx, path)
                 {
-                    cx.emit_span_lint(USAGE_OF_QUALIFIED_TY, path.span, TyQualified {
-                        ty,
-                        suggestion: path.span,
-                    });
+                    cx.emit_span_lint(
+                        USAGE_OF_QUALIFIED_TY,
+                        path.span,
+                        TyQualified { ty, suggestion: path.span },
+                    );
                 }
             }
             _ => {}
@@ -553,9 +561,11 @@ impl LateLintPass<'_> for BadOptAccess {
                 && let Some(lit) = item.lit()
                 && let ast::LitKind::Str(val, _) = lit.kind
             {
-                cx.emit_span_lint(BAD_OPT_ACCESS, expr.span, BadOptAccessDiag {
-                    msg: val.as_str(),
-                });
+                cx.emit_span_lint(
+                    BAD_OPT_ACCESS,
+                    expr.span,
+                    BadOptAccessDiag { msg: val.as_str() },
+                );
             }
         }
     }
diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs
index 9e4e8333164..3e2c1af97f4 100644
--- a/compiler/rustc_lint/src/let_underscore.rs
+++ b/compiler/rustc_lint/src/let_underscore.rs
@@ -156,10 +156,11 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
             };
             if is_sync_lock {
                 let span = MultiSpan::from_span(pat.span);
-                cx.emit_span_lint(LET_UNDERSCORE_LOCK, span, NonBindingLet::SyncLock {
-                    sub,
-                    pat: pat.span,
-                });
+                cx.emit_span_lint(
+                    LET_UNDERSCORE_LOCK,
+                    span,
+                    NonBindingLet::SyncLock { sub, pat: pat.span },
+                );
             // Only emit let_underscore_drop for top-level `_` patterns.
             } else if can_use_init.is_some() {
                 cx.emit_span_lint(LET_UNDERSCORE_DROP, local.span, NonBindingLet::DropType { sub });
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 3e97f4c86ba..d89e615e14a 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -627,18 +627,23 @@ fn register_internals(store: &mut LintStore) {
     // `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
     // these lints will trigger all of the time - change this once migration to diagnostic structs
     // and translation is completed
-    store.register_group(false, "rustc::internal", None, vec![
-        LintId::of(DEFAULT_HASH_TYPES),
-        LintId::of(POTENTIAL_QUERY_INSTABILITY),
-        LintId::of(UNTRACKED_QUERY_INFORMATION),
-        LintId::of(USAGE_OF_TY_TYKIND),
-        LintId::of(PASS_BY_VALUE),
-        LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
-        LintId::of(USAGE_OF_QUALIFIED_TY),
-        LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT),
-        LintId::of(BAD_OPT_ACCESS),
-        LintId::of(SPAN_USE_EQ_CTXT),
-    ]);
+    store.register_group(
+        false,
+        "rustc::internal",
+        None,
+        vec![
+            LintId::of(DEFAULT_HASH_TYPES),
+            LintId::of(POTENTIAL_QUERY_INSTABILITY),
+            LintId::of(UNTRACKED_QUERY_INFORMATION),
+            LintId::of(USAGE_OF_TY_TYKIND),
+            LintId::of(PASS_BY_VALUE),
+            LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
+            LintId::of(USAGE_OF_QUALIFIED_TY),
+            LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT),
+            LintId::of(BAD_OPT_ACCESS),
+            LintId::of(SPAN_USE_EQ_CTXT),
+        ],
+    );
 }
 
 #[cfg(test)]
diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs
index 776d51a6727..3b27e456136 100644
--- a/compiler/rustc_lint/src/map_unit_fn.rs
+++ b/compiler/rustc_lint/src/map_unit_fn.rs
@@ -60,25 +60,39 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
                         let fn_ty = cx.tcx.fn_sig(id).skip_binder();
                         let ret_ty = fn_ty.output().skip_binder();
                         if is_unit_type(ret_ty) {
-                            cx.emit_span_lint(MAP_UNIT_FN, span, MappingToUnit {
-                                function_label: cx.tcx.span_of_impl(*id).unwrap_or(default_span),
-                                argument_label: args[0].span,
-                                map_label: arg_ty.default_span(cx.tcx),
-                                suggestion: path.ident.span,
-                                replace: "for_each".to_string(),
-                            })
+                            cx.emit_span_lint(
+                                MAP_UNIT_FN,
+                                span,
+                                MappingToUnit {
+                                    function_label: cx
+                                        .tcx
+                                        .span_of_impl(*id)
+                                        .unwrap_or(default_span),
+                                    argument_label: args[0].span,
+                                    map_label: arg_ty.default_span(cx.tcx),
+                                    suggestion: path.ident.span,
+                                    replace: "for_each".to_string(),
+                                },
+                            )
                         }
                     } else if let ty::Closure(id, subs) = arg_ty.kind() {
                         let cl_ty = subs.as_closure().sig();
                         let ret_ty = cl_ty.output().skip_binder();
                         if is_unit_type(ret_ty) {
-                            cx.emit_span_lint(MAP_UNIT_FN, span, MappingToUnit {
-                                function_label: cx.tcx.span_of_impl(*id).unwrap_or(default_span),
-                                argument_label: args[0].span,
-                                map_label: arg_ty.default_span(cx.tcx),
-                                suggestion: path.ident.span,
-                                replace: "for_each".to_string(),
-                            })
+                            cx.emit_span_lint(
+                                MAP_UNIT_FN,
+                                span,
+                                MappingToUnit {
+                                    function_label: cx
+                                        .tcx
+                                        .span_of_impl(*id)
+                                        .unwrap_or(default_span),
+                                    argument_label: args[0].span,
+                                    map_label: arg_ty.default_span(cx.tcx),
+                                    suggestion: path.ident.span,
+                                    replace: "for_each".to_string(),
+                                },
+                            )
                         }
                     }
                 }
diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index 593c8616c1d..2f9cf98848e 100644
--- a/compiler/rustc_lint/src/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
@@ -209,22 +209,30 @@ impl EarlyLintPass for NonAsciiIdents {
                     if codepoints.is_empty() {
                         continue;
                     }
-                    cx.emit_span_lint(UNCOMMON_CODEPOINTS, sp, IdentifierUncommonCodepoints {
-                        codepoints_len: codepoints.len(),
-                        codepoints: codepoints.into_iter().map(|(c, _)| c).collect(),
-                        identifier_type: id_ty_descr,
-                    });
+                    cx.emit_span_lint(
+                        UNCOMMON_CODEPOINTS,
+                        sp,
+                        IdentifierUncommonCodepoints {
+                            codepoints_len: codepoints.len(),
+                            codepoints: codepoints.into_iter().map(|(c, _)| c).collect(),
+                            identifier_type: id_ty_descr,
+                        },
+                    );
                 }
 
                 let remaining = chars
                     .extract_if(.., |(c, _)| !GeneralSecurityProfile::identifier_allowed(*c))
                     .collect::<Vec<_>>();
                 if !remaining.is_empty() {
-                    cx.emit_span_lint(UNCOMMON_CODEPOINTS, sp, IdentifierUncommonCodepoints {
-                        codepoints_len: remaining.len(),
-                        codepoints: remaining.into_iter().map(|(c, _)| c).collect(),
-                        identifier_type: "Restricted",
-                    });
+                    cx.emit_span_lint(
+                        UNCOMMON_CODEPOINTS,
+                        sp,
+                        IdentifierUncommonCodepoints {
+                            codepoints_len: remaining.len(),
+                            codepoints: remaining.into_iter().map(|(c, _)| c).collect(),
+                            identifier_type: "Restricted",
+                        },
+                    );
                 }
             }
         }
@@ -253,12 +261,16 @@ impl EarlyLintPass for NonAsciiIdents {
                     .entry(skeleton_sym)
                     .and_modify(|(existing_symbol, existing_span, existing_is_ascii)| {
                         if !*existing_is_ascii || !is_ascii {
-                            cx.emit_span_lint(CONFUSABLE_IDENTS, sp, ConfusableIdentifierPair {
-                                existing_sym: *existing_symbol,
-                                sym: symbol,
-                                label: *existing_span,
-                                main_label: sp,
-                            });
+                            cx.emit_span_lint(
+                                CONFUSABLE_IDENTS,
+                                sp,
+                                ConfusableIdentifierPair {
+                                    existing_sym: *existing_symbol,
+                                    sym: symbol,
+                                    label: *existing_span,
+                                    main_label: sp,
+                                },
+                            );
                         }
                         if *existing_is_ascii && !is_ascii {
                             *existing_symbol = symbol;
@@ -370,10 +382,11 @@ impl EarlyLintPass for NonAsciiIdents {
                         let char_info = format!("'{}' (U+{:04X})", ch, ch as u32);
                         includes += &char_info;
                     }
-                    cx.emit_span_lint(MIXED_SCRIPT_CONFUSABLES, sp, MixedScriptConfusables {
-                        set: script_set.to_string(),
-                        includes,
-                    });
+                    cx.emit_span_lint(
+                        MIXED_SCRIPT_CONFUSABLES,
+                        sp,
+                        MixedScriptConfusables { set: script_set.to_string(), includes },
+                    );
                 }
             }
         }
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index 648d0675627..ac9f8d92dac 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -256,10 +256,14 @@ fn check_panic_str<'tcx>(
                 .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end)))
                 .collect(),
         };
-        cx.emit_span_lint(NON_FMT_PANICS, arg_spans, NonFmtPanicUnused {
-            count: n_arguments,
-            suggestion: is_arg_inside_call(arg.span, span).then_some(arg.span),
-        });
+        cx.emit_span_lint(
+            NON_FMT_PANICS,
+            arg_spans,
+            NonFmtPanicUnused {
+                count: n_arguments,
+                suggestion: is_arg_inside_call(arg.span, span).then_some(arg.span),
+            },
+        );
     } else {
         let brace_spans: Option<Vec<_>> =
             snippet.filter(|s| s.starts_with('"') || s.starts_with("r#")).map(|s| {
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 4e9d793be5b..0890890d12c 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -222,17 +222,21 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                         None
                     };
 
-                cx.emit_span_lint(NON_LOCAL_DEFINITIONS, ms, NonLocalDefinitionsDiag::Impl {
-                    depth: self.body_depth,
-                    body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
-                    body_name: parent_opt_item_name
-                        .map(|s| s.to_ident_string())
-                        .unwrap_or_else(|| "<unnameable>".to_string()),
-                    cargo_update: cargo_update(),
-                    const_anon,
-                    doctest,
-                    macro_to_change,
-                })
+                cx.emit_span_lint(
+                    NON_LOCAL_DEFINITIONS,
+                    ms,
+                    NonLocalDefinitionsDiag::Impl {
+                        depth: self.body_depth,
+                        body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
+                        body_name: parent_opt_item_name
+                            .map(|s| s.to_ident_string())
+                            .unwrap_or_else(|| "<unnameable>".to_string()),
+                        cargo_update: cargo_update(),
+                        const_anon,
+                        doctest,
+                        macro_to_change,
+                    },
+                )
             }
             ItemKind::Macro(_macro, MacroKind::Bang)
                 if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 0c180ab9570..5636f80d600 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -150,11 +150,11 @@ impl NonCamelCaseTypes {
             } else {
                 NonCamelCaseTypeSub::Label { span: ident.span }
             };
-            cx.emit_span_lint(NON_CAMEL_CASE_TYPES, ident.span, NonCamelCaseType {
-                sort,
-                name,
-                sub,
-            });
+            cx.emit_span_lint(
+                NON_CAMEL_CASE_TYPES,
+                ident.span,
+                NonCamelCaseType { sort, name, sub },
+            );
         }
     }
 }
@@ -488,11 +488,11 @@ impl NonUpperCaseGlobals {
             } else {
                 NonUpperCaseGlobalSub::Label { span: ident.span }
             };
-            cx.emit_span_lint(NON_UPPER_CASE_GLOBALS, ident.span, NonUpperCaseGlobal {
-                sort,
-                name,
-                sub,
-            });
+            cx.emit_span_lint(
+                NON_UPPER_CASE_GLOBALS,
+                ident.span,
+                NonUpperCaseGlobal { sort, name, sub },
+            );
         }
     }
 }
diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs
index 790ef910b04..b7835e6c36a 100644
--- a/compiler/rustc_lint/src/noop_method_call.rs
+++ b/compiler/rustc_lint/src/noop_method_call.rs
@@ -128,13 +128,17 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
                 ty::Adt(def, _) => Some(cx.tcx.def_span(def.did()).shrink_to_lo()),
                 _ => None,
             };
-            cx.emit_span_lint(NOOP_METHOD_CALL, span, NoopMethodCallDiag {
-                method: call.ident,
-                orig_ty,
-                trait_,
-                label: span,
-                suggest_derive,
-            });
+            cx.emit_span_lint(
+                NOOP_METHOD_CALL,
+                span,
+                NoopMethodCallDiag {
+                    method: call.ident,
+                    orig_ty,
+                    trait_,
+                    label: span,
+                    suggest_derive,
+                },
+            );
         } else {
             match name {
                 // If `type_of(x) == T` and `x.borrow()` is used to get `&T`,
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index d347a8c1bc7..7eaf83f5acf 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -113,10 +113,13 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
                 // return type is well-formed in traits even when `Self` isn't sized.
                 if let ty::Param(param_ty) = *proj_term.kind()
                     && param_ty.name == kw::SelfUpper
-                    && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn {
-                        in_trait_or_impl: Some(hir::RpitContext::Trait),
-                        ..
-                    })
+                    && matches!(
+                        opaque.origin,
+                        hir::OpaqueTyOrigin::AsyncFn {
+                            in_trait_or_impl: Some(hir::RpitContext::Trait),
+                            ..
+                        }
+                    )
                 {
                     return;
                 }
diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs
index a1d66047058..d85618f664d 100644
--- a/compiler/rustc_lint/src/pass_by_value.rs
+++ b/compiler/rustc_lint/src/pass_by_value.rs
@@ -30,10 +30,11 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
                     }
                 }
                 if let Some(t) = path_for_pass_by_value(cx, inner_ty) {
-                    cx.emit_span_lint(PASS_BY_VALUE, ty.span, PassByValueDiag {
-                        ty: t,
-                        suggestion: ty.span,
-                    });
+                    cx.emit_span_lint(
+                        PASS_BY_VALUE,
+                        ty.span,
+                        PassByValueDiag { ty: t, suggestion: ty.span },
+                    );
                 }
             }
             _ => {}
diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs
index 77bd13aacf7..409a23d1da0 100644
--- a/compiler/rustc_lint/src/passes.rs
+++ b/compiler/rustc_lint/src/passes.rs
@@ -162,7 +162,9 @@ macro_rules! early_lint_methods {
                 c: rustc_span::Span,
                 d_: rustc_ast::NodeId);
             fn check_trait_item(a: &rustc_ast::AssocItem);
+            fn check_trait_item_post(a: &rustc_ast::AssocItem);
             fn check_impl_item(a: &rustc_ast::AssocItem);
+            fn check_impl_item_post(a: &rustc_ast::AssocItem);
             fn check_variant(a: &rustc_ast::Variant);
             fn check_attribute(a: &rustc_ast::Attribute);
             fn check_attributes(a: &[rustc_ast::Attribute]);
diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs
index 036bfd06856..b43e4938b73 100644
--- a/compiler/rustc_lint/src/redundant_semicolon.rs
+++ b/compiler/rustc_lint/src/redundant_semicolon.rs
@@ -50,9 +50,10 @@ fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, boo
             return;
         }
 
-        cx.emit_span_lint(REDUNDANT_SEMICOLONS, span, RedundantSemicolonsDiag {
-            multiple,
-            suggestion: span,
-        });
+        cx.emit_span_lint(
+            REDUNDANT_SEMICOLONS,
+            span,
+            RedundantSemicolonsDiag { multiple, suggestion: span },
+        );
     }
 }
diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs
index f5ab44d7469..7cc35e20fcb 100644
--- a/compiler/rustc_lint/src/shadowed_into_iter.rs
+++ b/compiler/rustc_lint/src/shadowed_into_iter.rs
@@ -147,11 +147,10 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter {
             None
         };
 
-        cx.emit_span_lint(lint, call.ident.span, ShadowedIntoIterDiag {
-            target,
-            edition,
-            suggestion: call.ident.span,
-            sub,
-        });
+        cx.emit_span_lint(
+            lint,
+            call.ident.span,
+            ShadowedIntoIterDiag { target, edition, suggestion: call.ident.span, sub },
+        );
     }
 }
diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs
index fed5c29284b..50021157dda 100644
--- a/compiler/rustc_lint/src/static_mut_refs.rs
+++ b/compiler/rustc_lint/src/static_mut_refs.rs
@@ -157,11 +157,9 @@ fn emit_static_mut_refs(
         }
     };
 
-    cx.emit_span_lint(STATIC_MUT_REFS, span, RefOfMutStatic {
+    cx.emit_span_lint(
+        STATIC_MUT_REFS,
         span,
-        sugg,
-        shared_label,
-        shared_note,
-        mut_note,
-    });
+        RefOfMutStatic { span, sugg, shared_label, shared_note, mut_note },
+    );
 }
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index e0937e43c9a..99222742b65 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -101,11 +101,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
                     continue;
                 }
                 let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return };
-                cx.emit_span_lint(DROP_BOUNDS, span, DropTraitConstraintsDiag {
-                    predicate,
-                    tcx: cx.tcx,
-                    def_id,
-                });
+                cx.emit_span_lint(
+                    DROP_BOUNDS,
+                    span,
+                    DropTraitConstraintsDiag { predicate, tcx: cx.tcx, def_id },
+                );
             }
         }
     }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 80007f34db3..601d2fbfb67 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -543,7 +543,11 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
         lit: &'tcx hir::Lit,
         negated: bool,
     ) {
-        lint_literal(cx, self, hir_id, lit.span, lit, negated)
+        if negated {
+            self.negated_expr_id = Some(hir_id);
+            self.negated_expr_span = Some(lit.span);
+        }
+        lint_literal(cx, self, hir_id, lit.span, lit, negated);
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>) {
@@ -599,13 +603,16 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
         }
 
         fn rev_binop(binop: hir::BinOp) -> hir::BinOp {
-            source_map::respan(binop.span, match binop.node {
-                hir::BinOpKind::Lt => hir::BinOpKind::Gt,
-                hir::BinOpKind::Le => hir::BinOpKind::Ge,
-                hir::BinOpKind::Gt => hir::BinOpKind::Lt,
-                hir::BinOpKind::Ge => hir::BinOpKind::Le,
-                _ => return binop,
-            })
+            source_map::respan(
+                binop.span,
+                match binop.node {
+                    hir::BinOpKind::Lt => hir::BinOpKind::Gt,
+                    hir::BinOpKind::Le => hir::BinOpKind::Ge,
+                    hir::BinOpKind::Gt => hir::BinOpKind::Lt,
+                    hir::BinOpKind::Ge => hir::BinOpKind::Le,
+                    _ => return binop,
+                },
+            )
         }
 
         fn check_limits(
@@ -1386,14 +1393,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         } else {
             None
         };
-        self.cx.emit_span_lint(lint, sp, ImproperCTypes {
-            ty,
-            desc,
-            label: sp,
-            help,
-            note,
-            span_note,
-        });
+        self.cx.emit_span_lint(
+            lint,
+            sp,
+            ImproperCTypes { ty, desc, label: sp, help, note, span_note },
+        );
     }
 
     fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
@@ -1930,11 +1934,11 @@ impl InvalidAtomicOrdering {
     }
 
     fn check_atomic_compare_exchange(cx: &LateContext<'_>, expr: &Expr<'_>) {
-        let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[
-            sym::fetch_update,
-            sym::compare_exchange,
-            sym::compare_exchange_weak,
-        ]) else {
+        let Some((method, args)) = Self::inherent_atomic_method_call(
+            cx,
+            expr,
+            &[sym::fetch_update, sym::compare_exchange, sym::compare_exchange_weak],
+        ) else {
             return;
         };
 
diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs
index 71e6e229907..3e4532a6dbe 100644
--- a/compiler/rustc_lint/src/types/literal.rs
+++ b/compiler/rustc_lint/src/types/literal.rs
@@ -77,10 +77,11 @@ fn lint_overflowing_range_endpoint<'tcx>(
         }
     };
 
-    cx.emit_span_lint(OVERFLOWING_LITERALS, struct_expr.span, RangeEndpointOutOfRange {
-        ty,
-        sub: sub_sugg,
-    });
+    cx.emit_span_lint(
+        OVERFLOWING_LITERALS,
+        struct_expr.span,
+        RangeEndpointOutOfRange { ty, sub: sub_sugg },
+    );
 
     // We've just emitted a lint, special cased for `(...)..MAX+1` ranges,
     // return `true` so the callers don't also emit a lint
@@ -190,15 +191,19 @@ fn report_bin_hex_error(
         })
         .flatten();
 
-    cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingBinHex {
-        ty: t,
-        lit: repr_str.clone(),
-        dec: val,
-        actually,
-        sign,
-        sub,
-        sign_bit_sub,
-    })
+    cx.emit_span_lint(
+        OVERFLOWING_LITERALS,
+        span,
+        OverflowingBinHex {
+            ty: t,
+            lit: repr_str.clone(),
+            dec: val,
+            actually,
+            sign,
+            sub,
+            sign_bit_sub,
+        },
+    )
 }
 
 // Find the "next" fitting integer and return a suggestion string
@@ -245,12 +250,11 @@ fn lint_int_literal<'tcx>(
     lit: &hir::Lit,
     t: ty::IntTy,
     v: u128,
-    negated: bool,
 ) {
     let int_type = t.normalize(cx.sess().target.pointer_width);
     let (min, max) = int_ty_range(int_type);
     let max = max as u128;
-    let negative = negated ^ (type_limits.negated_expr_id == Some(hir_id));
+    let negative = type_limits.negated_expr_id == Some(hir_id);
 
     // Detect literal value out of range [min, max] inclusive
     // avoiding use of -min to prevent overflow/panic
@@ -283,13 +287,11 @@ fn lint_int_literal<'tcx>(
         let help = get_type_suggestion(cx.typeck_results().node_type(hir_id), v, negative)
             .map(|suggestion_ty| OverflowingIntHelp { suggestion_ty });
 
-        cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingInt {
-            ty: t.name_str(),
-            lit,
-            min,
-            max,
-            help,
-        });
+        cx.emit_span_lint(
+            OVERFLOWING_LITERALS,
+            span,
+            OverflowingInt { ty: t.name_str(), lit, min, max, help },
+        );
     }
 }
 
@@ -314,10 +316,11 @@ fn lint_uint_literal<'tcx>(
             match par_e.kind {
                 hir::ExprKind::Cast(..) => {
                     if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
-                        cx.emit_span_lint(OVERFLOWING_LITERALS, par_e.span, OnlyCastu8ToChar {
-                            span: par_e.span,
-                            literal: lit_val,
-                        });
+                        cx.emit_span_lint(
+                            OVERFLOWING_LITERALS,
+                            par_e.span,
+                            OnlyCastu8ToChar { span: par_e.span, literal: lit_val },
+                        );
                         return;
                     }
                 }
@@ -341,16 +344,20 @@ fn lint_uint_literal<'tcx>(
             );
             return;
         }
-        cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingUInt {
-            ty: t.name_str(),
-            lit: cx
-                .sess()
-                .source_map()
-                .span_to_snippet(lit.span)
-                .unwrap_or_else(|_| lit_val.to_string()),
-            min,
-            max,
-        });
+        cx.emit_span_lint(
+            OVERFLOWING_LITERALS,
+            span,
+            OverflowingUInt {
+                ty: t.name_str(),
+                lit: cx
+                    .sess()
+                    .source_map()
+                    .span_to_snippet(lit.span)
+                    .unwrap_or_else(|_| lit_val.to_string()),
+                min,
+                max,
+            },
+        );
     }
 }
 
@@ -366,7 +373,7 @@ pub(crate) fn lint_literal<'tcx>(
         ty::Int(t) => {
             match lit.node {
                 ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => {
-                    lint_int_literal(cx, type_limits, hir_id, span, lit, t, v.get(), negated)
+                    lint_int_literal(cx, type_limits, hir_id, span, lit, t, v.get())
                 }
                 _ => bug!(),
             };
@@ -388,14 +395,18 @@ pub(crate) fn lint_literal<'tcx>(
                 _ => bug!(),
             };
             if is_infinite == Ok(true) {
-                cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingLiteral {
-                    ty: t.name_str(),
-                    lit: cx
-                        .sess()
-                        .source_map()
-                        .span_to_snippet(lit.span)
-                        .unwrap_or_else(|_| sym.to_string()),
-                });
+                cx.emit_span_lint(
+                    OVERFLOWING_LITERALS,
+                    span,
+                    OverflowingLiteral {
+                        ty: t.name_str(),
+                        lit: cx
+                            .sess()
+                            .source_map()
+                            .span_to_snippet(lit.span)
+                            .unwrap_or_else(|_| sym.to_string()),
+                    },
+                );
             }
         }
         _ => {}
diff --git a/compiler/rustc_lint/src/unit_bindings.rs b/compiler/rustc_lint/src/unit_bindings.rs
index 3c2c5f8fae0..ed015908ae5 100644
--- a/compiler/rustc_lint/src/unit_bindings.rs
+++ b/compiler/rustc_lint/src/unit_bindings.rs
@@ -63,9 +63,11 @@ impl<'tcx> LateLintPass<'tcx> for UnitBindings {
             && !matches!(init.kind, hir::ExprKind::Tup([]))
             && !matches!(local.pat.kind, hir::PatKind::Tuple([], ..))
         {
-            cx.emit_span_lint(UNIT_BINDINGS, local.span, UnitBindingsDiag {
-                label: local.pat.span,
-            });
+            cx.emit_span_lint(
+                UNIT_BINDINGS,
+                local.span,
+                UnitBindingsDiag { label: local.pat.span },
+            );
         }
     }
 }
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 5696fcaed13..5a00ac005db 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -184,18 +184,22 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
         let mut op_warned = false;
 
         if let Some(must_use_op) = must_use_op {
-            cx.emit_span_lint(UNUSED_MUST_USE, expr.span, UnusedOp {
-                op: must_use_op,
-                label: expr.span,
-                suggestion: if expr_is_from_block {
-                    UnusedOpSuggestion::BlockTailExpr {
-                        before_span: expr.span.shrink_to_lo(),
-                        after_span: expr.span.shrink_to_hi(),
-                    }
-                } else {
-                    UnusedOpSuggestion::NormalExpr { span: expr.span.shrink_to_lo() }
+            cx.emit_span_lint(
+                UNUSED_MUST_USE,
+                expr.span,
+                UnusedOp {
+                    op: must_use_op,
+                    label: expr.span,
+                    suggestion: if expr_is_from_block {
+                        UnusedOpSuggestion::BlockTailExpr {
+                            before_span: expr.span.shrink_to_lo(),
+                            after_span: expr.span.shrink_to_hi(),
+                        }
+                    } else {
+                        UnusedOpSuggestion::NormalExpr { span: expr.span.shrink_to_lo() }
+                    },
                 },
-            });
+            );
             op_warned = true;
         }
 
@@ -489,35 +493,39 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                     );
                 }
                 MustUsePath::Closure(span) => {
-                    cx.emit_span_lint(UNUSED_MUST_USE, *span, UnusedClosure {
-                        count: plural_len,
-                        pre: descr_pre,
-                        post: descr_post,
-                    });
+                    cx.emit_span_lint(
+                        UNUSED_MUST_USE,
+                        *span,
+                        UnusedClosure { count: plural_len, pre: descr_pre, post: descr_post },
+                    );
                 }
                 MustUsePath::Coroutine(span) => {
-                    cx.emit_span_lint(UNUSED_MUST_USE, *span, UnusedCoroutine {
-                        count: plural_len,
-                        pre: descr_pre,
-                        post: descr_post,
-                    });
+                    cx.emit_span_lint(
+                        UNUSED_MUST_USE,
+                        *span,
+                        UnusedCoroutine { count: plural_len, pre: descr_pre, post: descr_post },
+                    );
                 }
                 MustUsePath::Def(span, def_id, reason) => {
-                    cx.emit_span_lint(UNUSED_MUST_USE, *span, UnusedDef {
-                        pre: descr_pre,
-                        post: descr_post,
-                        cx,
-                        def_id: *def_id,
-                        note: *reason,
-                        suggestion: (!is_inner).then_some(if expr_is_from_block {
-                            UnusedDefSuggestion::BlockTailExpr {
-                                before_span: span.shrink_to_lo(),
-                                after_span: span.shrink_to_hi(),
-                            }
-                        } else {
-                            UnusedDefSuggestion::NormalExpr { span: span.shrink_to_lo() }
-                        }),
-                    });
+                    cx.emit_span_lint(
+                        UNUSED_MUST_USE,
+                        *span,
+                        UnusedDef {
+                            pre: descr_pre,
+                            post: descr_post,
+                            cx,
+                            def_id: *def_id,
+                            note: *reason,
+                            suggestion: (!is_inner).then_some(if expr_is_from_block {
+                                UnusedDefSuggestion::BlockTailExpr {
+                                    before_span: span.shrink_to_lo(),
+                                    after_span: span.shrink_to_hi(),
+                                }
+                            } else {
+                                UnusedDefSuggestion::NormalExpr { span: span.shrink_to_lo() }
+                            }),
+                        },
+                    );
                 }
             }
         }
@@ -867,11 +875,11 @@ trait UnusedDelimLint {
                 end_replace: hi_replace,
             }
         });
-        cx.emit_span_lint(self.lint(), primary_span, UnusedDelim {
-            delim: Self::DELIM_STR,
-            item: msg,
-            suggestion,
-        });
+        cx.emit_span_lint(
+            self.lint(),
+            primary_span,
+            UnusedDelim { delim: Self::DELIM_STR, item: msg, suggestion },
+        );
     }
 
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
@@ -1558,9 +1566,11 @@ impl UnusedImportBraces {
                 ast::UseTreeKind::Nested { .. } => return,
             };
 
-            cx.emit_span_lint(UNUSED_IMPORT_BRACES, item.span, UnusedImportBracesDiag {
-                node: node_name,
-            });
+            cx.emit_span_lint(
+                UNUSED_IMPORT_BRACES,
+                item.span,
+                UnusedImportBracesDiag { node: node_name },
+            );
         }
     }
 }
diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml
index 7c402310436..2168a0df9ec 100644
--- a/compiler/rustc_llvm/Cargo.toml
+++ b/compiler/rustc_llvm/Cargo.toml
@@ -12,5 +12,5 @@ libc = "0.2.73"
 # tidy-alphabetical-start
 # Pinned so `cargo update` bumps don't cause breakage. Please also update the
 # pinned `cc` in `rustc_codegen_ssa` if you update `cc` here.
-cc = "=1.2.7"
+cc = "=1.2.13"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index d9d28299413..48806888b43 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -193,6 +193,10 @@ fn main() {
         cfg.define(&flag, None);
     }
 
+    if tracked_env_var_os("LLVM_ENZYME").is_some() {
+        cfg.define("ENZYME", None);
+    }
+
     if tracked_env_var_os("LLVM_RUSTLLVM").is_some() {
         cfg.define("LLVM_RUSTLLVM", None);
     }
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 6447a9362b3..a6b2384f2d7 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -688,14 +688,20 @@ struct LLVMRustSanitizerOptions {
   bool SanitizeKernelAddressRecover;
 };
 
+// This symbol won't be available or used when Enzyme is not enabled
+#ifdef ENZYME
+extern "C" void registerEnzyme(llvm::PassBuilder &PB);
+#endif
+
 extern "C" LLVMRustResult LLVMRustOptimize(
     LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef,
     LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage,
     bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR,
     bool LintIR, bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops,
     bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls,
-    bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions,
-    const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage,
+    bool EmitLifetimeMarkers, bool RunEnzyme,
+    LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath,
+    const char *PGOUsePath, bool InstrumentCoverage,
     const char *InstrProfileOutput, const char *PGOSampleUsePath,
     bool DebugInfoForProfiling, void *LlvmSelfProfiler,
     LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
@@ -1010,6 +1016,18 @@ extern "C" LLVMRustResult LLVMRustOptimize(
     MPM.addPass(NameAnonGlobalPass());
   }
 
+  // now load "-enzyme" pass:
+#ifdef ENZYME
+  if (RunEnzyme) {
+    registerEnzyme(PB);
+    if (auto Err = PB.parsePassPipeline(MPM, "enzyme")) {
+      std::string ErrMsg = toString(std::move(Err));
+      LLVMRustSetLastError(ErrMsg.c_str());
+      return LLVMRustResult::Failure;
+    }
+  }
+#endif
+
   // Upgrade all calls to old intrinsics first.
   for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
     UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs
index ce692abfb98..2c33a0ac0aa 100644
--- a/compiler/rustc_macros/src/serialize.rs
+++ b/compiler/rustc_macros/src/serialize.rs
@@ -105,11 +105,14 @@ fn decodable_body(
     };
     s.underscore_const(true);
 
-    s.bound_impl(quote!(::rustc_serialize::Decodable<#decoder_ty>), quote! {
-        fn decode(__decoder: &mut #decoder_ty) -> Self {
-            #decode_body
-        }
-    })
+    s.bound_impl(
+        quote!(::rustc_serialize::Decodable<#decoder_ty>),
+        quote! {
+            fn decode(__decoder: &mut #decoder_ty) -> Self {
+                #decode_body
+            }
+        },
+    )
 }
 
 fn decode_field(field: &syn::Field) -> proc_macro2::TokenStream {
@@ -285,13 +288,16 @@ fn encodable_body(
         quote! {}
     };
 
-    s.bound_impl(quote!(::rustc_serialize::Encodable<#encoder_ty>), quote! {
-        fn encode(
-            &self,
-            __encoder: &mut #encoder_ty,
-        ) {
-            #lints
-            #encode_body
-        }
-    })
+    s.bound_impl(
+        quote!(::rustc_serialize::Encodable<#encoder_ty>),
+        quote! {
+            fn encode(
+                &self,
+                __encoder: &mut #encoder_ty,
+            ) {
+                #lints
+                #encode_body
+            }
+        },
+    )
 }
diff --git a/compiler/rustc_macros/src/symbols/tests.rs b/compiler/rustc_macros/src/symbols/tests.rs
index b32ce60e204..9c53453df5b 100644
--- a/compiler/rustc_macros/src/symbols/tests.rs
+++ b/compiler/rustc_macros/src/symbols/tests.rs
@@ -94,8 +94,8 @@ fn check_symbol_order() {
             aardvark,
         }
     };
-    test_symbols_macro(input, &[
-        "Symbol `aardvark` must precede `zebra`",
-        "location of previous symbol `zebra`",
-    ]);
+    test_symbols_macro(
+        input,
+        &["Symbol `aardvark` must precede `zebra`", "location of previous symbol `zebra`"],
+    );
 }
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 6bad8312790..c2dda21bb72 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -1213,12 +1213,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
                 let cnum = self.resolve_crate(name, item.span, dep_kind)?;
 
                 let path_len = definitions.def_path(def_id).data.len();
-                self.cstore.update_extern_crate(cnum, ExternCrate {
-                    src: ExternCrateSource::Extern(def_id.to_def_id()),
-                    span: item.span,
-                    path_len,
-                    dependency_of: LOCAL_CRATE,
-                });
+                self.cstore.update_extern_crate(
+                    cnum,
+                    ExternCrate {
+                        src: ExternCrateSource::Extern(def_id.to_def_id()),
+                        span: item.span,
+                        path_len,
+                        dependency_of: LOCAL_CRATE,
+                    },
+                );
                 Some(cnum)
             }
             _ => bug!(),
@@ -1228,13 +1231,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
     pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
         let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?;
 
-        self.cstore.update_extern_crate(cnum, ExternCrate {
-            src: ExternCrateSource::Path,
-            span,
-            // to have the least priority in `update_extern_crate`
-            path_len: usize::MAX,
-            dependency_of: LOCAL_CRATE,
-        });
+        self.cstore.update_extern_crate(
+            cnum,
+            ExternCrate {
+                src: ExternCrateSource::Path,
+                span,
+                // to have the least priority in `update_extern_crate`
+                path_len: usize::MAX,
+                dependency_of: LOCAL_CRATE,
+            },
+        );
 
         Some(cnum)
     }
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 2c34df6ea61..de722e62043 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -7,7 +7,6 @@ edition = "2021"
 # tidy-alphabetical-start
 bitflags = "2.4.1"
 either = "1.5.0"
-field-offset = "0.3.5"
 gsgdt = "0.1.2"
 polonius-engine = "0.13.0"
 rustc-rayon-core = { version = "0.5.0" }
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 1784665bcae..311bc60c3cd 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -178,7 +178,7 @@ impl CodegenFnAttrs {
             || match self.linkage {
                 // These are private, so make sure we don't try to consider
                 // them external.
-                None | Some(Linkage::Internal | Linkage::Private) => false,
+                None | Some(Linkage::Internal) => false,
                 Some(_) => true,
             }
     }
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 46534697e1d..8c6b11a681e 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -2,8 +2,8 @@
 
 use std::fmt::{self, Debug, Formatter};
 
-use rustc_index::IndexVec;
-use rustc_index::bit_set::DenseBitSet;
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_index::{Idx, IndexVec};
 use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::Span;
 
@@ -103,23 +103,12 @@ pub enum CoverageKind {
     /// Should be erased before codegen (at some point after `InstrumentCoverage`).
     BlockMarker { id: BlockMarkerId },
 
-    /// Marks the point in MIR control flow represented by a coverage counter.
+    /// Marks its enclosing basic block with the ID of the coverage graph node
+    /// that it was part of during the `InstrumentCoverage` MIR pass.
     ///
-    /// This is eventually lowered to `llvm.instrprof.increment` in LLVM IR.
-    ///
-    /// If this statement does not survive MIR optimizations, any mappings that
-    /// refer to this counter can have those references simplified to zero.
-    CounterIncrement { id: CounterId },
-
-    /// Marks the point in MIR control-flow represented by a coverage expression.
-    ///
-    /// If this statement does not survive MIR optimizations, any mappings that
-    /// refer to this expression can have those references simplified to zero.
-    ///
-    /// (This is only inserted for expression IDs that are directly used by
-    /// mappings. Intermediate expressions with no direct mappings are
-    /// retained/zeroed based on whether they are transitively used.)
-    ExpressionUsed { id: ExpressionId },
+    /// During codegen, this might be lowered to `llvm.instrprof.increment` or
+    /// to a no-op, depending on the outcome of counter-creation.
+    VirtualCounter { bcb: BasicCoverageBlock },
 
     /// Marks the point in MIR control flow represented by a evaluated condition.
     ///
@@ -138,8 +127,7 @@ impl Debug for CoverageKind {
         match self {
             SpanMarker => write!(fmt, "SpanMarker"),
             BlockMarker { id } => write!(fmt, "BlockMarker({:?})", id.index()),
-            CounterIncrement { id } => write!(fmt, "CounterIncrement({:?})", id.index()),
-            ExpressionUsed { id } => write!(fmt, "ExpressionUsed({:?})", id.index()),
+            VirtualCounter { bcb } => write!(fmt, "VirtualCounter({bcb:?})"),
             CondBitmapUpdate { index, decision_depth } => {
                 write!(fmt, "CondBitmapUpdate(index={:?}, depth={:?})", index, decision_depth)
             }
@@ -179,34 +167,19 @@ pub struct Expression {
 #[derive(TyEncodable, TyDecodable, Hash, HashStable)]
 pub enum MappingKind {
     /// Associates a normal region of code with a counter/expression/zero.
-    Code(CovTerm),
+    Code { bcb: BasicCoverageBlock },
     /// Associates a branch region with separate counters for true and false.
-    Branch { true_term: CovTerm, false_term: CovTerm },
+    Branch { true_bcb: BasicCoverageBlock, false_bcb: BasicCoverageBlock },
     /// Associates a branch region with separate counters for true and false.
-    MCDCBranch { true_term: CovTerm, false_term: CovTerm, mcdc_params: ConditionInfo },
+    MCDCBranch {
+        true_bcb: BasicCoverageBlock,
+        false_bcb: BasicCoverageBlock,
+        mcdc_params: ConditionInfo,
+    },
     /// Associates a decision region with a bitmap and number of conditions.
     MCDCDecision(DecisionInfo),
 }
 
-impl MappingKind {
-    /// Returns a copy of this mapping kind, in which all coverage terms have
-    /// been replaced with ones returned by the given function.
-    pub fn map_terms(&self, map_fn: impl Fn(CovTerm) -> CovTerm) -> Self {
-        match *self {
-            Self::Code(term) => Self::Code(map_fn(term)),
-            Self::Branch { true_term, false_term } => {
-                Self::Branch { true_term: map_fn(true_term), false_term: map_fn(false_term) }
-            }
-            Self::MCDCBranch { true_term, false_term, mcdc_params } => Self::MCDCBranch {
-                true_term: map_fn(true_term),
-                false_term: map_fn(false_term),
-                mcdc_params,
-            },
-            Self::MCDCDecision(param) => Self::MCDCDecision(param),
-        }
-    }
-}
-
 #[derive(Clone, Debug)]
 #[derive(TyEncodable, TyDecodable, Hash, HashStable)]
 pub struct Mapping {
@@ -222,10 +195,15 @@ pub struct Mapping {
 pub struct FunctionCoverageInfo {
     pub function_source_hash: u64,
     pub body_span: Span,
-    pub num_counters: usize,
-    pub mcdc_bitmap_bits: usize,
-    pub expressions: IndexVec<ExpressionId, Expression>,
+
+    /// Used in conjunction with `priority_list` to create physical counters
+    /// and counter expressions, after MIR optimizations.
+    pub node_flow_data: NodeFlowData<BasicCoverageBlock>,
+    pub priority_list: Vec<BasicCoverageBlock>,
+
     pub mappings: Vec<Mapping>,
+
+    pub mcdc_bitmap_bits: usize,
     /// The depth of the deepest decision is used to know how many
     /// temp condbitmaps should be allocated for the function.
     pub mcdc_num_condition_bitmaps: usize,
@@ -292,40 +270,55 @@ pub struct MCDCDecisionSpan {
     pub num_conditions: usize,
 }
 
-/// Summarizes coverage IDs inserted by the `InstrumentCoverage` MIR pass
-/// (for compiler option `-Cinstrument-coverage`), after MIR optimizations
-/// have had a chance to potentially remove some of them.
+/// Contains information needed during codegen, obtained by inspecting the
+/// function's MIR after MIR optimizations.
 ///
-/// Used by the `coverage_ids_info` query.
+/// Returned by the `coverage_ids_info` query.
 #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable)]
 pub struct CoverageIdsInfo {
-    pub counters_seen: DenseBitSet<CounterId>,
-    pub zero_expressions: DenseBitSet<ExpressionId>,
+    pub num_counters: u32,
+    pub phys_counter_for_node: FxIndexMap<BasicCoverageBlock, CounterId>,
+    pub term_for_bcb: IndexVec<BasicCoverageBlock, Option<CovTerm>>,
+    pub expressions: IndexVec<ExpressionId, Expression>,
 }
 
-impl CoverageIdsInfo {
-    /// Coverage codegen needs to know how many coverage counters are ever
-    /// incremented within a function, so that it can set the `num-counters`
-    /// argument of the `llvm.instrprof.increment` intrinsic.
+rustc_index::newtype_index! {
+    /// During the `InstrumentCoverage` MIR pass, a BCB is a node in the
+    /// "coverage graph", which is a refinement of the MIR control-flow graph
+    /// that merges or omits some blocks that aren't relevant to coverage.
     ///
-    /// This may be less than the highest counter ID emitted by the
-    /// InstrumentCoverage MIR pass, if the highest-numbered counter increments
-    /// were removed by MIR optimizations.
-    pub fn num_counters_after_mir_opts(&self) -> u32 {
-        // FIXME(Zalathar): Currently this treats an unused counter as "used"
-        // if its ID is less than that of the highest counter that really is
-        // used. Fixing this would require adding a renumbering step somewhere.
-        self.counters_seen.last_set_in(..).map_or(0, |max| max.as_u32() + 1)
+    /// After that pass is complete, the coverage graph no longer exists, so a
+    /// BCB is effectively an opaque ID.
+    #[derive(HashStable)]
+    #[encodable]
+    #[orderable]
+    #[debug_format = "bcb{}"]
+    pub struct BasicCoverageBlock {
+        const START_BCB = 0;
     }
+}
 
-    /// Returns `true` if the given term is known to have a value of zero, taking
-    /// into account knowledge of which counters are unused and which expressions
-    /// are always zero.
-    pub fn is_zero_term(&self, term: CovTerm) -> bool {
-        match term {
-            CovTerm::Zero => true,
-            CovTerm::Counter(id) => !self.counters_seen.contains(id),
-            CovTerm::Expression(id) => self.zero_expressions.contains(id),
-        }
-    }
+/// Data representing a view of some underlying graph, in which each node's
+/// successors have been merged into a single "supernode".
+///
+/// The resulting supernodes have no obvious meaning on their own.
+/// However, merging successor nodes means that a node's out-edges can all
+/// be combined into a single out-edge, whose flow is the same as the flow
+/// (execution count) of its corresponding node in the original graph.
+///
+/// With all node flows now in the original graph now represented as edge flows
+/// in the merged graph, it becomes possible to analyze the original node flows
+/// using techniques for analyzing edge flows.
+#[derive(Clone, Debug)]
+#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
+pub struct NodeFlowData<Node: Idx> {
+    /// Maps each node to the supernode that contains it, indicated by some
+    /// arbitrary "root" node that is part of that supernode.
+    pub supernodes: IndexVec<Node, Node>,
+    /// For each node, stores the single supernode that all of its successors
+    /// have been merged into.
+    ///
+    /// (Note that each node in a supernode can potentially have a _different_
+    /// successor supernode from its peers.)
+    pub succ_supernodes: IndexVec<Node, Node>,
 }
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 2e4d258ffff..95bc9b71fe0 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -317,10 +317,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
         Ok(Allocation {
             bytes,
             provenance: ProvenanceMap::new(),
-            init_mask: InitMask::new(size, match init {
-                AllocInit::Uninit => false,
-                AllocInit::Zero => true,
-            }),
+            init_mask: InitMask::new(
+                size,
+                match init {
+                    AllocInit::Uninit => false,
+                    AllocInit::Zero => true,
+                },
+            ),
             align,
             mutability: Mutability::Mut,
             extra: (),
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 68d5e5f4dd2..63e20fb0d64 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1410,10 +1410,10 @@ impl<'tcx> BasicBlockData<'tcx> {
         // existing elements from before the gap to the end of the gap.
         // For now, this is safe code, emulating a gap but initializing it.
         let mut gap = self.statements.len()..self.statements.len() + extra_stmts;
-        self.statements.resize(gap.end, Statement {
-            source_info: SourceInfo::outermost(DUMMY_SP),
-            kind: StatementKind::Nop,
-        });
+        self.statements.resize(
+            gap.end,
+            Statement { source_info: SourceInfo::outermost(DUMMY_SP), kind: StatementKind::Nop },
+        );
         for (splice_start, new_stmts) in splices.into_iter().rev() {
             let splice_end = splice_start + new_stmts.size_hint().0;
             while gap.end > splice_end {
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 75931956310..d4a9aac3733 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -327,9 +327,7 @@ pub enum Linkage {
     LinkOnceODR,
     WeakAny,
     WeakODR,
-    Appending,
     Internal,
-    Private,
     ExternalWeak,
     Common,
 }
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 3007b787496..11ebbbe807d 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -619,13 +619,9 @@ fn write_function_coverage_info(
     function_coverage_info: &coverage::FunctionCoverageInfo,
     w: &mut dyn io::Write,
 ) -> io::Result<()> {
-    let coverage::FunctionCoverageInfo { body_span, expressions, mappings, .. } =
-        function_coverage_info;
+    let coverage::FunctionCoverageInfo { body_span, mappings, .. } = function_coverage_info;
 
     writeln!(w, "{INDENT}coverage body span: {body_span:?}")?;
-    for (id, expression) in expressions.iter_enumerated() {
-        writeln!(w, "{INDENT}coverage {id:?} => {expression:?};")?;
-    }
     for coverage::Mapping { kind, span } in mappings {
         writeln!(w, "{INDENT}coverage {kind:?} => {span:?};")?;
     }
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 2fe116212eb..9357e19f7c5 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -272,7 +272,7 @@ impl<O> AssertKind<O> {
                     "\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\", {required:?}, {found:?}"
                 )
             }
-            NullPointerDereference => write!(f, "\"null pointer dereference occured\""),
+            NullPointerDereference => write!(f, "\"null pointer dereference occurred\""),
             ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
                 write!(f, "\"coroutine resumed after completion\"")
             }
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 8d04bbb95bd..8ad88fbda7c 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -527,8 +527,9 @@ macro_rules! make_mir_visitor {
                         target: _,
                         unwind: _,
                         call_source: _,
-                        fn_span: _
+                        fn_span,
                     } => {
+                        self.visit_span($(& $mutability)? *fn_span);
                         self.visit_operand(func, location);
                         for arg in args {
                             self.visit_operand(&$($mutability)? arg.node, location);
@@ -543,8 +544,9 @@ macro_rules! make_mir_visitor {
                     TerminatorKind::TailCall {
                         func,
                         args,
-                        fn_span: _,
+                        fn_span,
                     } => {
+                        self.visit_span($(& $mutability)? *fn_span);
                         self.visit_operand(func, location);
                         for arg in args {
                             self.visit_operand(&$($mutability)? arg.node, location);
@@ -853,6 +855,8 @@ macro_rules! make_mir_visitor {
                     local_info: _,
                 } = local_decl;
 
+                self.visit_source_info(source_info);
+
                 self.visit_ty($(& $mutability)? *ty, TyContext::LocalDecl {
                     local,
                     source_info: *source_info,
@@ -862,7 +866,6 @@ macro_rules! make_mir_visitor {
                         self.visit_user_type_projection(user_ty);
                     }
                 }
-                self.visit_source_info(source_info);
             }
 
             fn super_var_debug_info(
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index d94efe2d7d6..478ac19d199 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -614,9 +614,16 @@ rustc_queries! {
         feedable
     }
 
-    /// Summarizes coverage IDs inserted by the `InstrumentCoverage` MIR pass
-    /// (for compiler option `-Cinstrument-coverage`), after MIR optimizations
-    /// have had a chance to potentially remove some of them.
+    /// Scans through a function's MIR after MIR optimizations, to prepare the
+    /// information needed by codegen when `-Cinstrument-coverage` is active.
+    ///
+    /// This includes the details of where to insert `llvm.instrprof.increment`
+    /// intrinsics, and the expression tables to be embedded in the function's
+    /// coverage metadata.
+    ///
+    /// FIXME(Zalathar): This query's purpose has drifted a bit and should
+    /// probably be renamed, but that can wait until after the potential
+    /// follow-ups to #136053 have settled down.
     ///
     /// Returns `None` for functions that were not instrumented.
     query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> Option<&'tcx mir::coverage::CoverageIdsInfo> {
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index 957b63584be..3247bdbf105 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -327,15 +327,18 @@ impl OnDiskCache {
 
             // Encode the file footer.
             let footer_pos = encoder.position() as u64;
-            encoder.encode_tagged(TAG_FILE_FOOTER, &Footer {
-                file_index_to_stable_id,
-                query_result_index,
-                side_effects_index,
-                interpret_alloc_index,
-                syntax_contexts,
-                expn_data,
-                foreign_expn_data,
-            });
+            encoder.encode_tagged(
+                TAG_FILE_FOOTER,
+                &Footer {
+                    file_index_to_stable_id,
+                    query_result_index,
+                    side_effects_index,
+                    interpret_alloc_index,
+                    syntax_contexts,
+                    expn_data,
+                    foreign_expn_data,
+                },
+            );
 
             // Encode the position of the footer as the last 8 bytes of the
             // file so we know where to look for it.
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 6c019b427db..690b8128b1a 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -1,6 +1,5 @@
 use std::ops::Deref;
 
-use field_offset::FieldOffset;
 use rustc_data_structures::sync::{AtomicU64, WorkerLocal};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::hir_id::OwnerId;
@@ -24,8 +23,10 @@ pub struct DynamicQuery<'tcx, C: QueryCache> {
     pub eval_always: bool,
     pub dep_kind: DepKind,
     pub handle_cycle_error: HandleCycleError,
-    pub query_state: FieldOffset<QueryStates<'tcx>, QueryState<C::Key>>,
-    pub query_cache: FieldOffset<QueryCaches<'tcx>, C>,
+    // Offset of this query's state field in the QueryStates struct
+    pub query_state: usize,
+    // Offset of this query's cache field in the QueryCaches struct
+    pub query_cache: usize,
     pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool,
     pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
     pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index c6fc5f98f56..a9b4593c13d 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -194,6 +194,14 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.variances_of(def_id)
     }
 
+    fn opt_alias_variances(
+        self,
+        kind: impl Into<ty::AliasTermKind>,
+        def_id: DefId,
+    ) -> Option<&'tcx [ty::Variance]> {
+        self.opt_alias_variances(kind, def_id)
+    }
+
     fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
         self.type_of(def_id)
     }
@@ -1086,10 +1094,13 @@ impl<'tcx> CommonLifetimes<'tcx> {
             .map(|i| {
                 (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
                     .map(|v| {
-                        mk(ty::ReBound(ty::DebruijnIndex::from(i), ty::BoundRegion {
-                            var: ty::BoundVar::from(v),
-                            kind: ty::BoundRegionKind::Anon,
-                        }))
+                        mk(ty::ReBound(
+                            ty::DebruijnIndex::from(i),
+                            ty::BoundRegion {
+                                var: ty::BoundVar::from(v),
+                                kind: ty::BoundRegionKind::Anon,
+                            },
+                        ))
                     })
                     .collect()
             })
@@ -1290,9 +1301,6 @@ pub struct TyCtxt<'tcx> {
     gcx: &'tcx GlobalCtxt<'tcx>,
 }
 
-// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution.
-unsafe impl DynSend for TyCtxt<'_> {}
-unsafe impl DynSync for TyCtxt<'_> {}
 fn _assert_tcx_fields() {
     sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
     sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
@@ -3138,12 +3146,15 @@ impl<'tcx> TyCtxt<'tcx> {
                     }
 
                     let generics = self.generics_of(new_parent);
-                    return ty::Region::new_early_param(self, ty::EarlyParamRegion {
-                        index: generics
-                            .param_def_id_to_index(self, ebv.to_def_id())
-                            .expect("early-bound var should be present in fn generics"),
-                        name: self.item_name(ebv.to_def_id()),
-                    });
+                    return ty::Region::new_early_param(
+                        self,
+                        ty::EarlyParamRegion {
+                            index: generics
+                                .param_def_id_to_index(self, ebv.to_def_id())
+                                .expect("early-bound var should be present in fn generics"),
+                            name: self.item_name(ebv.to_def_id()),
+                        },
+                    );
                 }
                 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
                     let new_parent = self.local_parent(lbv);
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 067516917ef..4ea4050ed8b 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -280,21 +280,26 @@ impl<'tcx> TyCtxt<'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars);
-        self.replace_escaping_bound_vars_uncached(value, FnMutDelegate {
-            regions: &mut |r: ty::BoundRegion| {
-                ty::Region::new_bound(self, ty::INNERMOST, ty::BoundRegion {
-                    var: shift_bv(r.var),
-                    kind: r.kind,
-                })
+        self.replace_escaping_bound_vars_uncached(
+            value,
+            FnMutDelegate {
+                regions: &mut |r: ty::BoundRegion| {
+                    ty::Region::new_bound(
+                        self,
+                        ty::INNERMOST,
+                        ty::BoundRegion { var: shift_bv(r.var), kind: r.kind },
+                    )
+                },
+                types: &mut |t: ty::BoundTy| {
+                    Ty::new_bound(
+                        self,
+                        ty::INNERMOST,
+                        ty::BoundTy { var: shift_bv(t.var), kind: t.kind },
+                    )
+                },
+                consts: &mut |c| ty::Const::new_bound(self, ty::INNERMOST, shift_bv(c)),
             },
-            types: &mut |t: ty::BoundTy| {
-                Ty::new_bound(self, ty::INNERMOST, ty::BoundTy {
-                    var: shift_bv(t.var),
-                    kind: t.kind,
-                })
-            },
-            consts: &mut |c| ty::Const::new_bound(self, ty::INNERMOST, shift_bv(c)),
-        })
+        )
     }
 
     /// Replaces any late-bound regions bound in `value` with `'erased`. Useful in codegen but also
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 3ced64b5b80..e5015ea3c3d 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1369,10 +1369,11 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
                     // `def_span` unconditionally (which may have a perf penalty).
                     let span =
                         if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) };
-                    self.handle_fn_abi_err(*err, span, FnAbiRequest::OfInstance {
-                        instance,
-                        extra_args,
-                    })
+                    self.handle_fn_abi_err(
+                        *err,
+                        span,
+                        FnAbiRequest::OfInstance { instance, extra_args },
+                    )
                 }),
         )
     }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 6fd0fb9a0a4..94bd359f6eb 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -759,10 +759,11 @@ impl<'tcx> TyCtxt<'tcx> {
                     assert_eq!(re, self.lifetimes.re_erased);
                     let var = ty::BoundVar::from_usize(vars.len());
                     vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon));
-                    ty::Region::new_bound(self, debruijn, ty::BoundRegion {
-                        var,
-                        kind: ty::BoundRegionKind::Anon,
-                    })
+                    ty::Region::new_bound(
+                        self,
+                        debruijn,
+                        ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon },
+                    )
                 });
                 ty::EarlyBinder::bind(ty::Binder::bind_with_vars(
                     ty,
@@ -948,6 +949,29 @@ impl<'tcx> TyCtxt<'tcx> {
 
         ty
     }
+
+    // Computes the variances for an alias (opaque or RPITIT) that represent
+    // its (un)captured regions.
+    pub fn opt_alias_variances(
+        self,
+        kind: impl Into<ty::AliasTermKind>,
+        def_id: DefId,
+    ) -> Option<&'tcx [ty::Variance]> {
+        match kind.into() {
+            ty::AliasTermKind::ProjectionTy => {
+                if self.is_impl_trait_in_trait(def_id) {
+                    Some(self.variances_of(def_id))
+                } else {
+                    None
+                }
+            }
+            ty::AliasTermKind::OpaqueTy => Some(self.variances_of(def_id)),
+            ty::AliasTermKind::InherentTy
+            | ty::AliasTermKind::WeakTy
+            | ty::AliasTermKind::UnevaluatedConst
+            | ty::AliasTermKind::ProjectionConst => None,
+        }
+    }
 }
 
 struct OpaqueTypeExpander<'tcx> {
diff --git a/compiler/rustc_mir_build/src/builder/cfg.rs b/compiler/rustc_mir_build/src/builder/cfg.rs
index 42212f2518b..082cdc2e2a4 100644
--- a/compiler/rustc_mir_build/src/builder/cfg.rs
+++ b/compiler/rustc_mir_build/src/builder/cfg.rs
@@ -40,10 +40,10 @@ impl<'tcx> CFG<'tcx> {
         place: Place<'tcx>,
         rvalue: Rvalue<'tcx>,
     ) {
-        self.push(block, Statement {
-            source_info,
-            kind: StatementKind::Assign(Box::new((place, rvalue))),
-        });
+        self.push(
+            block,
+            Statement { source_info, kind: StatementKind::Assign(Box::new((place, rvalue))) },
+        );
     }
 
     pub(crate) fn push_assign_constant(
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
index 482f1e3840b..308ca442b40 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
@@ -484,16 +484,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         });
 
                     let place = place_builder.to_place(this);
-                    this.cfg.push(block, Statement {
-                        source_info: ty_source_info,
-                        kind: StatementKind::AscribeUserType(
-                            Box::new((place, UserTypeProjection {
-                                base: annotation_index,
-                                projs: vec![],
-                            })),
-                            Variance::Invariant,
-                        ),
-                    });
+                    this.cfg.push(
+                        block,
+                        Statement {
+                            source_info: ty_source_info,
+                            kind: StatementKind::AscribeUserType(
+                                Box::new((
+                                    place,
+                                    UserTypeProjection { base: annotation_index, projs: vec![] },
+                                )),
+                                Variance::Invariant,
+                            ),
+                        },
+                    );
                 }
                 block.and(place_builder)
             }
@@ -510,16 +513,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             user_ty: user_ty.clone(),
                             inferred_ty: expr.ty,
                         });
-                    this.cfg.push(block, Statement {
-                        source_info: ty_source_info,
-                        kind: StatementKind::AscribeUserType(
-                            Box::new((Place::from(temp), UserTypeProjection {
-                                base: annotation_index,
-                                projs: vec![],
-                            })),
-                            Variance::Invariant,
-                        ),
-                    });
+                    this.cfg.push(
+                        block,
+                        Statement {
+                            source_info: ty_source_info,
+                            kind: StatementKind::AscribeUserType(
+                                Box::new((
+                                    Place::from(temp),
+                                    UserTypeProjection { base: annotation_index, projs: vec![] },
+                                )),
+                                Variance::Invariant,
+                            ),
+                        },
+                    );
                 }
                 block.and(PlaceBuilder::from(temp))
             }
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index e7713f0a1d6..2c9a1de7f99 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -151,19 +151,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 );
                 let storage = this.temp(Ty::new_mut_ptr(tcx, tcx.types.u8), expr_span);
                 let success = this.cfg.start_new_block();
-                this.cfg.terminate(block, source_info, TerminatorKind::Call {
-                    func: exchange_malloc,
-                    args: [Spanned { node: Operand::Move(size), span: DUMMY_SP }, Spanned {
-                        node: Operand::Move(align),
-                        span: DUMMY_SP,
-                    }]
-                    .into(),
-                    destination: storage,
-                    target: Some(success),
-                    unwind: UnwindAction::Continue,
-                    call_source: CallSource::Misc,
-                    fn_span: expr_span,
-                });
+                this.cfg.terminate(
+                    block,
+                    source_info,
+                    TerminatorKind::Call {
+                        func: exchange_malloc,
+                        args: [
+                            Spanned { node: Operand::Move(size), span: DUMMY_SP },
+                            Spanned { node: Operand::Move(align), span: DUMMY_SP },
+                        ]
+                        .into(),
+                        destination: storage,
+                        target: Some(success),
+                        unwind: UnwindAction::Continue,
+                        call_source: CallSource::Misc,
+                        fn_span: expr_span,
+                    },
+                );
                 this.diverge_from(block);
                 block = success;
 
@@ -171,10 +175,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // and therefore is not considered during coroutine auto-trait
                 // determination. See the comment about `box` at `yield_in_scope`.
                 let result = this.local_decls.push(LocalDecl::new(expr.ty, expr_span));
-                this.cfg.push(block, Statement {
-                    source_info,
-                    kind: StatementKind::StorageLive(result),
-                });
+                this.cfg.push(
+                    block,
+                    Statement { source_info, kind: StatementKind::StorageLive(result) },
+                );
                 if let Some(scope) = scope.temp_lifetime {
                     // schedule a shallow free of that memory, lest we unwind:
                     this.schedule_drop_storage_and_value(expr_span, scope, result);
@@ -272,12 +276,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             );
                             merge_place
                         };
-                        this.cfg.push(block, Statement {
-                            source_info,
-                            kind: StatementKind::Intrinsic(Box::new(
-                                NonDivergingIntrinsic::Assume(Operand::Move(assert_place)),
-                            )),
-                        });
+                        this.cfg.push(
+                            block,
+                            Statement {
+                                source_info,
+                                kind: StatementKind::Intrinsic(Box::new(
+                                    NonDivergingIntrinsic::Assume(Operand::Move(assert_place)),
+                                )),
+                            },
+                        );
                     }
 
                     (op, ty)
@@ -739,12 +746,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             );
             if let Operand::Move(to_drop) = value_operand {
                 let success = this.cfg.start_new_block();
-                this.cfg.terminate(block, outer_source_info, TerminatorKind::Drop {
-                    place: to_drop,
-                    target: success,
-                    unwind: UnwindAction::Continue,
-                    replace: false,
-                });
+                this.cfg.terminate(
+                    block,
+                    outer_source_info,
+                    TerminatorKind::Drop {
+                        place: to_drop,
+                        target: success,
+                        unwind: UnwindAction::Continue,
+                        replace: false,
+                    },
+                );
                 this.diverge_from(block);
                 block = success;
             }
diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs
index b25cd0f4426..65dd061003d 100644
--- a/compiler/rustc_mir_build/src/builder/expr/into.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/into.rs
@@ -220,10 +220,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 this.in_breakable_scope(Some(loop_block), destination, expr_span, move |this| {
                     // conduct the test, if necessary
                     let body_block = this.cfg.start_new_block();
-                    this.cfg.terminate(loop_block, source_info, TerminatorKind::FalseUnwind {
-                        real_target: body_block,
-                        unwind: UnwindAction::Continue,
-                    });
+                    this.cfg.terminate(
+                        loop_block,
+                        source_info,
+                        TerminatorKind::FalseUnwind {
+                            real_target: body_block,
+                            unwind: UnwindAction::Continue,
+                        },
+                    );
                     this.diverge_from(loop_block);
 
                     // The “return” value of the loop body must always be a unit. We therefore
@@ -254,30 +258,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                 debug!("expr_into_dest: fn_span={:?}", fn_span);
 
-                this.cfg.terminate(block, source_info, TerminatorKind::Call {
-                    func: fun,
-                    args,
-                    unwind: UnwindAction::Continue,
-                    destination,
-                    // The presence or absence of a return edge affects control-flow sensitive
-                    // MIR checks and ultimately whether code is accepted or not. We can only
-                    // omit the return edge if a return type is visibly uninhabited to a module
-                    // that makes the call.
-                    target: expr
-                        .ty
-                        .is_inhabited_from(
-                            this.tcx,
-                            this.parent_module,
-                            this.infcx.typing_env(this.param_env),
-                        )
-                        .then_some(success),
-                    call_source: if from_hir_call {
-                        CallSource::Normal
-                    } else {
-                        CallSource::OverloadedOperator
+                this.cfg.terminate(
+                    block,
+                    source_info,
+                    TerminatorKind::Call {
+                        func: fun,
+                        args,
+                        unwind: UnwindAction::Continue,
+                        destination,
+                        // The presence or absence of a return edge affects control-flow sensitive
+                        // MIR checks and ultimately whether code is accepted or not. We can only
+                        // omit the return edge if a return type is visibly uninhabited to a module
+                        // that makes the call.
+                        target: expr
+                            .ty
+                            .is_inhabited_from(
+                                this.tcx,
+                                this.parent_module,
+                                this.infcx.typing_env(this.param_env),
+                            )
+                            .then_some(success),
+                        call_source: if from_hir_call {
+                            CallSource::Normal
+                        } else {
+                            CallSource::OverloadedOperator
+                        },
+                        fn_span,
                     },
-                    fn_span,
-                });
+                );
                 this.diverge_from(block);
                 success.unit()
             }
@@ -494,9 +502,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             let tmp = this.get_unit_temp();
                             let target =
                                 this.ast_block(tmp, target, block, source_info).into_block();
-                            this.cfg.terminate(target, source_info, TerminatorKind::Goto {
-                                target: destination_block,
-                            });
+                            this.cfg.terminate(
+                                target,
+                                source_info,
+                                TerminatorKind::Goto { target: destination_block },
+                            );
 
                             mir::InlineAsmOperand::Label { target_index }
                         }
@@ -515,19 +525,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm,
                 };
 
-                this.cfg.terminate(block, source_info, TerminatorKind::InlineAsm {
-                    asm_macro,
-                    template,
-                    operands,
-                    options,
-                    line_spans,
-                    targets: targets.into_boxed_slice(),
-                    unwind: if options.contains(InlineAsmOptions::MAY_UNWIND) {
-                        UnwindAction::Continue
-                    } else {
-                        UnwindAction::Unreachable
+                this.cfg.terminate(
+                    block,
+                    source_info,
+                    TerminatorKind::InlineAsm {
+                        asm_macro,
+                        template,
+                        operands,
+                        options,
+                        line_spans,
+                        targets: targets.into_boxed_slice(),
+                        unwind: if options.contains(InlineAsmOptions::MAY_UNWIND) {
+                            UnwindAction::Continue
+                        } else {
+                            UnwindAction::Unreachable
+                        },
                     },
-                });
+                );
                 if options.contains(InlineAsmOptions::MAY_UNWIND) {
                     this.diverge_from(block);
                 }
@@ -587,12 +601,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No)
                 );
                 let resume = this.cfg.start_new_block();
-                this.cfg.terminate(block, source_info, TerminatorKind::Yield {
-                    value,
-                    resume,
-                    resume_arg: destination,
-                    drop: None,
-                });
+                this.cfg.terminate(
+                    block,
+                    source_info,
+                    TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
+                );
                 this.coroutine_drop_cleanup(block);
                 resume.unit()
             }
diff --git a/compiler/rustc_mir_build/src/builder/expr/stmt.rs b/compiler/rustc_mir_build/src/builder/expr/stmt.rs
index 4ae3536d9c2..58090d3748b 100644
--- a/compiler/rustc_mir_build/src/builder/expr/stmt.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/stmt.rs
@@ -123,11 +123,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                     unpack!(block = this.break_for_tail_call(block, &args, source_info));
 
-                    this.cfg.terminate(block, source_info, TerminatorKind::TailCall {
-                        func: fun,
-                        args,
-                        fn_span,
-                    });
+                    this.cfg.terminate(
+                        block,
+                        source_info,
+                        TerminatorKind::TailCall { func: fun, args, fn_span },
+                    );
 
                     this.cfg.start_new_block().unit()
                 })
diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
index bca57817d66..ee331713736 100644
--- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
@@ -173,10 +173,13 @@ impl<'tcx> MatchPairTree<'tcx> {
                 let ascription = place.map(|source| {
                     let span = pattern.span;
                     let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id());
-                    let args = ty::InlineConstArgs::new(cx.tcx, ty::InlineConstArgsParts {
-                        parent_args: ty::GenericArgs::identity_for_item(cx.tcx, parent_id),
-                        ty: cx.infcx.next_ty_var(span),
-                    })
+                    let args = ty::InlineConstArgs::new(
+                        cx.tcx,
+                        ty::InlineConstArgsParts {
+                            parent_args: ty::GenericArgs::identity_for_item(cx.tcx, parent_id),
+                            ty: cx.infcx.next_ty_var(span),
+                        },
+                    )
                     .args;
                     let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::new(
                         ty::UserTypeKind::TypeOf(def_id, ty::UserArgs { args, user_self_ty: None }),
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs
index a2f92a93ec5..ed577f7adeb 100644
--- a/compiler/rustc_mir_build/src/builder/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs
@@ -104,11 +104,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         variable_source_info: SourceInfo,
         declare_let_bindings: DeclareLetBindings,
     ) -> BlockAnd<()> {
-        self.then_else_break_inner(block, expr_id, ThenElseArgs {
-            temp_scope_override,
-            variable_source_info,
-            declare_let_bindings,
-        })
+        self.then_else_break_inner(
+            block,
+            expr_id,
+            ThenElseArgs { temp_scope_override, variable_source_info, declare_let_bindings },
+        )
     }
 
     fn then_else_break_inner(
@@ -134,16 +134,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let local_scope = this.local_scope();
                 let (lhs_success_block, failure_block) =
                     this.in_if_then_scope(local_scope, expr_span, |this| {
-                        this.then_else_break_inner(block, lhs, ThenElseArgs {
-                            declare_let_bindings: DeclareLetBindings::LetNotPermitted,
-                            ..args
-                        })
+                        this.then_else_break_inner(
+                            block,
+                            lhs,
+                            ThenElseArgs {
+                                declare_let_bindings: DeclareLetBindings::LetNotPermitted,
+                                ..args
+                            },
+                        )
                     });
                 let rhs_success_block = this
-                    .then_else_break_inner(failure_block, rhs, ThenElseArgs {
-                        declare_let_bindings: DeclareLetBindings::LetNotPermitted,
-                        ..args
-                    })
+                    .then_else_break_inner(
+                        failure_block,
+                        rhs,
+                        ThenElseArgs {
+                            declare_let_bindings: DeclareLetBindings::LetNotPermitted,
+                            ..args
+                        },
+                    )
                     .into_block();
 
                 // Make the LHS and RHS success arms converge to a common block.
@@ -170,10 +178,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         if this.tcx.sess.instrument_coverage() {
                             this.cfg.push_coverage_span_marker(block, this.source_info(expr_span));
                         }
-                        this.then_else_break_inner(block, arg, ThenElseArgs {
-                            declare_let_bindings: DeclareLetBindings::LetNotPermitted,
-                            ..args
-                        })
+                        this.then_else_break_inner(
+                            block,
+                            arg,
+                            ThenElseArgs {
+                                declare_let_bindings: DeclareLetBindings::LetNotPermitted,
+                                ..args
+                            },
+                        )
                     });
                 this.break_for_else(success_block, args.variable_source_info);
                 failure_block.unit()
@@ -629,27 +641,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let ty_source_info = self.source_info(annotation.span);
 
                 let base = self.canonical_user_type_annotations.push(annotation.clone());
-                self.cfg.push(block, Statement {
-                    source_info: ty_source_info,
-                    kind: StatementKind::AscribeUserType(
-                        Box::new((place, UserTypeProjection { base, projs: Vec::new() })),
-                        // We always use invariant as the variance here. This is because the
-                        // variance field from the ascription refers to the variance to use
-                        // when applying the type to the value being matched, but this
-                        // ascription applies rather to the type of the binding. e.g., in this
-                        // example:
-                        //
-                        // ```
-                        // let x: T = <expr>
-                        // ```
-                        //
-                        // We are creating an ascription that defines the type of `x` to be
-                        // exactly `T` (i.e., with invariance). The variance field, in
-                        // contrast, is intended to be used to relate `T` to the type of
-                        // `<expr>`.
-                        ty::Invariant,
-                    ),
-                });
+                self.cfg.push(
+                    block,
+                    Statement {
+                        source_info: ty_source_info,
+                        kind: StatementKind::AscribeUserType(
+                            Box::new((place, UserTypeProjection { base, projs: Vec::new() })),
+                            // We always use invariant as the variance here. This is because the
+                            // variance field from the ascription refers to the variance to use
+                            // when applying the type to the value being matched, but this
+                            // ascription applies rather to the type of the binding. e.g., in this
+                            // example:
+                            //
+                            // ```
+                            // let x: T = <expr>
+                            // ```
+                            //
+                            // We are creating an ascription that defines the type of `x` to be
+                            // exactly `T` (i.e., with invariance). The variance field, in
+                            // contrast, is intended to be used to relate `T` to the type of
+                            // `<expr>`.
+                            ty::Invariant,
+                        ),
+                    },
+                );
 
                 self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard);
                 block.unit()
@@ -2549,13 +2564,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let source_info = self.source_info(ascription.annotation.span);
 
             let base = self.canonical_user_type_annotations.push(ascription.annotation);
-            self.cfg.push(block, Statement {
-                source_info,
-                kind: StatementKind::AscribeUserType(
-                    Box::new((ascription.source, UserTypeProjection { base, projs: Vec::new() })),
-                    ascription.variance,
-                ),
-            });
+            self.cfg.push(
+                block,
+                Statement {
+                    source_info,
+                    kind: StatementKind::AscribeUserType(
+                        Box::new((
+                            ascription.source,
+                            UserTypeProjection { base, projs: Vec::new() },
+                        )),
+                        ascription.variance,
+                    ),
+                },
+            );
         }
     }
 
diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs
index 834f8be0d00..a7a028bff97 100644
--- a/compiler/rustc_mir_build/src/builder/matches/test.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/test.rs
@@ -327,15 +327,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         );
         // `let temp = <Ty as Deref>::deref(ref_src);`
         // or `let temp = <Ty as DerefMut>::deref_mut(ref_src);`
-        self.cfg.terminate(block, source_info, TerminatorKind::Call {
-            func: Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_: method })),
-            args: [Spanned { node: Operand::Move(ref_src), span }].into(),
-            destination: temp,
-            target: Some(target_block),
-            unwind: UnwindAction::Continue,
-            call_source: CallSource::Misc,
-            fn_span: source_info.span,
-        });
+        self.cfg.terminate(
+            block,
+            source_info,
+            TerminatorKind::Call {
+                func: Operand::Constant(Box::new(ConstOperand {
+                    span,
+                    user_ty: None,
+                    const_: method,
+                })),
+                args: [Spanned { node: Operand::Move(ref_src), span }].into(),
+                destination: temp,
+                target: Some(target_block),
+                unwind: UnwindAction::Continue,
+                call_source: CallSource::Misc,
+                fn_span: source_info.span,
+            },
+        );
     }
 
     /// Compare using the provided built-in comparison operator
@@ -463,26 +471,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let bool_ty = self.tcx.types.bool;
         let eq_result = self.temp(bool_ty, source_info.span);
         let eq_block = self.cfg.start_new_block();
-        self.cfg.terminate(block, source_info, TerminatorKind::Call {
-            func: Operand::Constant(Box::new(ConstOperand {
-                span: source_info.span,
-
-                // FIXME(#54571): This constant comes from user input (a
-                // constant in a pattern). Are there forms where users can add
-                // type annotations here?  For example, an associated constant?
-                // Need to experiment.
-                user_ty: None,
-
-                const_: method,
-            })),
-            args: [Spanned { node: val, span: DUMMY_SP }, Spanned { node: expect, span: DUMMY_SP }]
+        self.cfg.terminate(
+            block,
+            source_info,
+            TerminatorKind::Call {
+                func: Operand::Constant(Box::new(ConstOperand {
+                    span: source_info.span,
+
+                    // FIXME(#54571): This constant comes from user input (a
+                    // constant in a pattern). Are there forms where users can add
+                    // type annotations here?  For example, an associated constant?
+                    // Need to experiment.
+                    user_ty: None,
+
+                    const_: method,
+                })),
+                args: [
+                    Spanned { node: val, span: DUMMY_SP },
+                    Spanned { node: expect, span: DUMMY_SP },
+                ]
                 .into(),
-            destination: eq_result,
-            target: Some(eq_block),
-            unwind: UnwindAction::Continue,
-            call_source: CallSource::MatchCmp,
-            fn_span: source_info.span,
-        });
+                destination: eq_result,
+                target: Some(eq_block),
+                unwind: UnwindAction::Continue,
+                call_source: CallSource::MatchCmp,
+                fn_span: source_info.span,
+            },
+        );
         self.diverge_from(block);
 
         // check the result
diff --git a/compiler/rustc_mir_build/src/builder/matches/util.rs b/compiler/rustc_mir_build/src/builder/matches/util.rs
index 83e79572b2a..589e350a03f 100644
--- a/compiler/rustc_mir_build/src/builder/matches/util.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/util.rs
@@ -20,10 +20,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         source_info: SourceInfo,
     ) {
         if imaginary_target != real_target {
-            self.cfg.terminate(from_block, source_info, TerminatorKind::FalseEdge {
-                real_target,
-                imaginary_target,
-            });
+            self.cfg.terminate(
+                from_block,
+                source_info,
+                TerminatorKind::FalseEdge { real_target, imaginary_target },
+            );
         } else {
             self.cfg.goto(from_block, source_info, real_target)
         }
diff --git a/compiler/rustc_mir_build/src/builder/misc.rs b/compiler/rustc_mir_build/src/builder/misc.rs
index 9ea56a9574f..6e8e74fd4fc 100644
--- a/compiler/rustc_mir_build/src/builder/misc.rs
+++ b/compiler/rustc_mir_build/src/builder/misc.rs
@@ -45,11 +45,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ) -> Place<'tcx> {
         let usize_ty = self.tcx.types.usize;
         let temp = self.temp(usize_ty, source_info.span);
-        self.cfg.push_assign_constant(block, source_info, temp, ConstOperand {
-            span: source_info.span,
-            user_ty: None,
-            const_: Const::from_usize(self.tcx, value),
-        });
+        self.cfg.push_assign_constant(
+            block,
+            source_info,
+            temp,
+            ConstOperand {
+                span: source_info.span,
+                user_ty: None,
+                const_: Const::from_usize(self.tcx, value),
+            },
+        );
         temp
     }
 
diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs
index 945f02821d9..d3551ea3a97 100644
--- a/compiler/rustc_mir_build/src/builder/scope.rs
+++ b/compiler/rustc_mir_build/src/builder/scope.rs
@@ -532,12 +532,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             (Some(normal_block), Some(exit_block)) => {
                 let target = self.cfg.start_new_block();
                 let source_info = self.source_info(span);
-                self.cfg.terminate(normal_block.into_block(), source_info, TerminatorKind::Goto {
-                    target,
-                });
-                self.cfg.terminate(exit_block.into_block(), source_info, TerminatorKind::Goto {
-                    target,
-                });
+                self.cfg.terminate(
+                    normal_block.into_block(),
+                    source_info,
+                    TerminatorKind::Goto { target },
+                );
+                self.cfg.terminate(
+                    exit_block.into_block(),
+                    source_info,
+                    TerminatorKind::Goto { target },
+                );
                 target.unit()
             }
         }
@@ -833,30 +837,37 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         unwind_drops.add_entry_point(block, unwind_entry_point);
 
                         let next = self.cfg.start_new_block();
-                        self.cfg.terminate(block, source_info, TerminatorKind::Drop {
-                            place: local.into(),
-                            target: next,
-                            unwind: UnwindAction::Continue,
-                            replace: false,
-                        });
+                        self.cfg.terminate(
+                            block,
+                            source_info,
+                            TerminatorKind::Drop {
+                                place: local.into(),
+                                target: next,
+                                unwind: UnwindAction::Continue,
+                                replace: false,
+                            },
+                        );
                         block = next;
                     }
                     DropKind::ForLint => {
-                        self.cfg.push(block, Statement {
-                            source_info,
-                            kind: StatementKind::BackwardIncompatibleDropHint {
-                                place: Box::new(local.into()),
-                                reason: BackwardIncompatibleDropReason::Edition2024,
+                        self.cfg.push(
+                            block,
+                            Statement {
+                                source_info,
+                                kind: StatementKind::BackwardIncompatibleDropHint {
+                                    place: Box::new(local.into()),
+                                    reason: BackwardIncompatibleDropReason::Edition2024,
+                                },
                             },
-                        });
+                        );
                     }
                     DropKind::Storage => {
                         // Only temps and vars need their storage dead.
                         assert!(local.index() > self.arg_count);
-                        self.cfg.push(block, Statement {
-                            source_info,
-                            kind: StatementKind::StorageDead(local),
-                        });
+                        self.cfg.push(
+                            block,
+                            Statement { source_info, kind: StatementKind::StorageDead(local) },
+                        );
                     }
                 }
             }
@@ -1350,12 +1361,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let assign_unwind = self.cfg.start_new_cleanup_block();
         self.cfg.push_assign(assign_unwind, source_info, place, value.clone());
 
-        self.cfg.terminate(block, source_info, TerminatorKind::Drop {
-            place,
-            target: assign,
-            unwind: UnwindAction::Cleanup(assign_unwind),
-            replace: true,
-        });
+        self.cfg.terminate(
+            block,
+            source_info,
+            TerminatorKind::Drop {
+                place,
+                target: assign,
+                unwind: UnwindAction::Cleanup(assign_unwind),
+                replace: true,
+            },
+        );
         self.diverge_from(block);
 
         assign.unit()
@@ -1375,13 +1390,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let source_info = self.source_info(span);
         let success_block = self.cfg.start_new_block();
 
-        self.cfg.terminate(block, source_info, TerminatorKind::Assert {
-            cond,
-            expected,
-            msg: Box::new(msg),
-            target: success_block,
-            unwind: UnwindAction::Continue,
-        });
+        self.cfg.terminate(
+            block,
+            source_info,
+            TerminatorKind::Assert {
+                cond,
+                expected,
+                msg: Box::new(msg),
+                target: success_block,
+                unwind: UnwindAction::Continue,
+            },
+        );
         self.diverge_from(block);
 
         success_block
@@ -1481,12 +1500,16 @@ fn build_scope_drops<'tcx>(
 
                 unwind_drops.add_entry_point(block, unwind_to);
                 let next = cfg.start_new_block();
-                cfg.terminate(block, source_info, TerminatorKind::Drop {
-                    place: local.into(),
-                    target: next,
-                    unwind: UnwindAction::Continue,
-                    replace: false,
-                });
+                cfg.terminate(
+                    block,
+                    source_info,
+                    TerminatorKind::Drop {
+                        place: local.into(),
+                        target: next,
+                        unwind: UnwindAction::Continue,
+                        replace: false,
+                    },
+                );
                 block = next;
             }
             DropKind::ForLint => {
@@ -1509,13 +1532,16 @@ fn build_scope_drops<'tcx>(
                     continue;
                 }
 
-                cfg.push(block, Statement {
-                    source_info,
-                    kind: StatementKind::BackwardIncompatibleDropHint {
-                        place: Box::new(local.into()),
-                        reason: BackwardIncompatibleDropReason::Edition2024,
+                cfg.push(
+                    block,
+                    Statement {
+                        source_info,
+                        kind: StatementKind::BackwardIncompatibleDropHint {
+                            place: Box::new(local.into()),
+                            reason: BackwardIncompatibleDropReason::Edition2024,
+                        },
                     },
-                });
+                );
             }
             DropKind::Storage => {
                 // Ordinarily, storage-dead nodes are not emitted on unwind, so we don't
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index b6494173b0f..2b9b948763f 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -525,11 +525,10 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                             .copied()
                             .filter(|feature| missing.contains(feature))
                             .collect();
-                        self.requires_unsafe(expr.span, CallToFunctionWith {
-                            function: func_did,
-                            missing,
-                            build_enabled,
-                        });
+                        self.requires_unsafe(
+                            expr.span,
+                            CallToFunctionWith { function: func_did, missing, build_enabled },
+                        );
                     }
                 }
             }
@@ -1186,9 +1185,11 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
     warnings.sort_by_key(|w| w.block_span);
     for UnusedUnsafeWarning { hir_id, block_span, enclosing_unsafe } in warnings {
         let block_span = tcx.sess.source_map().guess_head_span(block_span);
-        tcx.emit_node_span_lint(UNUSED_UNSAFE, hir_id, block_span, UnusedUnsafe {
-            span: block_span,
-            enclosing: enclosing_unsafe,
-        });
+        tcx.emit_node_span_lint(
+            UNUSED_UNSAFE,
+            hir_id,
+            block_span,
+            UnusedUnsafe { span: block_span, enclosing: enclosing_unsafe },
+        );
     }
 }
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 9d114e67559..a01609012b8 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -186,11 +186,9 @@ impl<'tcx> ThirBuildCx<'tcx> {
             let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() {
                 let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span));
 
-                self.tcx.type_of(va_list_did).instantiate(self.tcx, &[self
-                    .tcx
-                    .lifetimes
-                    .re_erased
-                    .into()])
+                self.tcx
+                    .type_of(va_list_did)
+                    .instantiate(self.tcx, &[self.tcx.lifetimes.re_erased.into()])
             } else {
                 fn_sig.inputs()[index]
             };
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 74b0e84068c..c1c47ecccf3 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -233,12 +233,15 @@ where
                     .patch_terminator(bb, TerminatorKind::Goto { target: self.succ });
             }
             DropStyle::Static => {
-                self.elaborator.patch().patch_terminator(bb, TerminatorKind::Drop {
-                    place: self.place,
-                    target: self.succ,
-                    unwind: self.unwind.into_action(),
-                    replace: false,
-                });
+                self.elaborator.patch().patch_terminator(
+                    bb,
+                    TerminatorKind::Drop {
+                        place: self.place,
+                        target: self.succ,
+                        unwind: self.unwind.into_action(),
+                        replace: false,
+                    },
+                );
             }
             DropStyle::Conditional => {
                 let drop_bb = self.complete_drop(self.succ, self.unwind);
@@ -729,12 +732,15 @@ where
         };
         let loop_block = self.elaborator.patch().new_block(loop_block);
 
-        self.elaborator.patch().patch_terminator(drop_block, TerminatorKind::Drop {
-            place: tcx.mk_place_deref(ptr),
-            target: loop_block,
-            unwind: unwind.into_action(),
-            replace: false,
-        });
+        self.elaborator.patch().patch_terminator(
+            drop_block,
+            TerminatorKind::Drop {
+                place: tcx.mk_place_deref(ptr),
+                target: loop_block,
+                unwind: unwind.into_action(),
+                replace: false,
+            },
+        );
 
         loop_block
     }
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 6427fd0fd29..07517d7edab 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -305,10 +305,11 @@ impl Direction for Forward {
                     // `exit_state`, so pass it directly to `apply_switch_int_edge_effect` to save
                     // a clone of the dataflow state.
                     let otherwise = targets.otherwise();
-                    analysis.apply_switch_int_edge_effect(&mut data, exit_state, SwitchIntTarget {
-                        value: None,
-                        target: otherwise,
-                    });
+                    analysis.apply_switch_int_edge_effect(
+                        &mut data,
+                        exit_state,
+                        SwitchIntTarget { value: None, target: otherwise },
+                    );
                     propagate(otherwise, exit_state);
                 } else {
                     for target in targets.all_targets() {
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index 9ccabb46c63..448fad2dc3e 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -670,10 +670,10 @@ where
                 r#"<td colspan="{colspan}" {fmt} align="left">{state}</td>"#,
                 colspan = this.style.num_state_columns(),
                 fmt = fmt,
-                state = dot::escape_html(&format!("{:?}", DebugWithAdapter {
-                    this: state,
-                    ctxt: analysis
-                })),
+                state = dot::escape_html(&format!(
+                    "{:?}",
+                    DebugWithAdapter { this: state, ctxt: analysis }
+                )),
             )
         })
     }
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index 5b3a9ccba69..ae0f1179e6f 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -30,26 +30,32 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
 
     block(4, mir::TerminatorKind::Return);
     block(1, mir::TerminatorKind::Return);
-    block(2, mir::TerminatorKind::Call {
-        func: mir::Operand::Copy(dummy_place.clone()),
-        args: [].into(),
-        destination: dummy_place.clone(),
-        target: Some(mir::START_BLOCK),
-        unwind: mir::UnwindAction::Continue,
-        call_source: mir::CallSource::Misc,
-        fn_span: DUMMY_SP,
-    });
+    block(
+        2,
+        mir::TerminatorKind::Call {
+            func: mir::Operand::Copy(dummy_place.clone()),
+            args: [].into(),
+            destination: dummy_place.clone(),
+            target: Some(mir::START_BLOCK),
+            unwind: mir::UnwindAction::Continue,
+            call_source: mir::CallSource::Misc,
+            fn_span: DUMMY_SP,
+        },
+    );
     block(3, mir::TerminatorKind::Return);
     block(0, mir::TerminatorKind::Return);
-    block(4, mir::TerminatorKind::Call {
-        func: mir::Operand::Copy(dummy_place.clone()),
-        args: [].into(),
-        destination: dummy_place.clone(),
-        target: Some(mir::START_BLOCK),
-        unwind: mir::UnwindAction::Continue,
-        call_source: mir::CallSource::Misc,
-        fn_span: DUMMY_SP,
-    });
+    block(
+        4,
+        mir::TerminatorKind::Call {
+            func: mir::Operand::Copy(dummy_place.clone()),
+            args: [].into(),
+            destination: dummy_place.clone(),
+            target: Some(mir::START_BLOCK),
+            unwind: mir::UnwindAction::Continue,
+            call_source: mir::CallSource::Misc,
+            fn_span: DUMMY_SP,
+        },
+    );
 
     mir::Body::new_cfg_only(blocks)
 }
diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
index 87ae2b71654..8716fd1c098 100644
--- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
+++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
@@ -99,10 +99,13 @@ fn add_move_for_packed_drop<'tcx>(
 
     patch.add_statement(loc, StatementKind::StorageLive(temp));
     patch.add_assign(loc, Place::from(temp), Rvalue::Use(Operand::Move(*place)));
-    patch.patch_terminator(loc.block, TerminatorKind::Drop {
-        place: Place::from(temp),
-        target: storage_dead_block,
-        unwind,
-        replace,
-    });
+    patch.patch_terminator(
+        loc.block,
+        TerminatorKind::Drop {
+            place: Place::from(temp),
+            target: storage_dead_block,
+            unwind,
+            replace,
+        },
+    );
 }
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index 1fc788a2dad..e5a28d1b66c 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -111,10 +111,13 @@ impl<'tcx> crate::MirPass<'tcx> for AddRetag {
             .collect::<Vec<_>>();
         // Now we go over the returns we collected to retag the return values.
         for (source_info, dest_place, dest_block) in returns {
-            basic_blocks[dest_block].statements.insert(0, Statement {
-                source_info,
-                kind: StatementKind::Retag(RetagKind::Default, Box::new(dest_place)),
-            });
+            basic_blocks[dest_block].statements.insert(
+                0,
+                Statement {
+                    source_info,
+                    kind: StatementKind::Retag(RetagKind::Default, Box::new(dest_place)),
+                },
+            );
         }
 
         // PART 3
@@ -169,10 +172,13 @@ impl<'tcx> crate::MirPass<'tcx> for AddRetag {
                 };
                 // Insert a retag after the statement.
                 let source_info = block_data.statements[i].source_info;
-                block_data.statements.insert(i + 1, Statement {
-                    source_info,
-                    kind: StatementKind::Retag(retag_kind, Box::new(place)),
-                });
+                block_data.statements.insert(
+                    i + 1,
+                    Statement {
+                        source_info,
+                        kind: StatementKind::Retag(retag_kind, Box::new(place)),
+                    },
+                );
             }
         }
     }
diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs
index ca5564e447a..b70cca14840 100644
--- a/compiler/rustc_mir_transform/src/check_alignment.rs
+++ b/compiler/rustc_mir_transform/src/check_alignment.rs
@@ -1,5 +1,6 @@
 use rustc_index::IndexVec;
 use rustc_middle::mir::interpret::Scalar;
+use rustc_middle::mir::visit::PlaceContext;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_session::Session;
@@ -44,6 +45,7 @@ fn insert_alignment_check<'tcx>(
     tcx: TyCtxt<'tcx>,
     pointer: Place<'tcx>,
     pointee_ty: Ty<'tcx>,
+    _context: PlaceContext,
     local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>,
     stmts: &mut Vec<Statement<'tcx>>,
     source_info: SourceInfo,
diff --git a/compiler/rustc_mir_transform/src/check_call_recursion.rs b/compiler/rustc_mir_transform/src/check_call_recursion.rs
index 51fd3c6512e..e49723a6c39 100644
--- a/compiler/rustc_mir_transform/src/check_call_recursion.rs
+++ b/compiler/rustc_mir_transform/src/check_call_recursion.rs
@@ -83,10 +83,12 @@ fn check_recursion<'tcx>(
 
         let sp = tcx.def_span(def_id);
         let hir_id = tcx.local_def_id_to_hir_id(def_id);
-        tcx.emit_node_span_lint(UNCONDITIONAL_RECURSION, hir_id, sp, UnconditionalRecursion {
-            span: sp,
-            call_sites: vis.reachable_recursive_calls,
-        });
+        tcx.emit_node_span_lint(
+            UNCONDITIONAL_RECURSION,
+            hir_id,
+            sp,
+            UnconditionalRecursion { span: sp, call_sites: vis.reachable_recursive_calls },
+        );
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/check_null.rs b/compiler/rustc_mir_transform/src/check_null.rs
index 0b6c0ceaac1..543e1845e65 100644
--- a/compiler/rustc_mir_transform/src/check_null.rs
+++ b/compiler/rustc_mir_transform/src/check_null.rs
@@ -1,5 +1,5 @@
 use rustc_index::IndexVec;
-use rustc_middle::mir::interpret::Scalar;
+use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext};
 use rustc_middle::mir::*;
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_session::Session;
@@ -26,6 +26,7 @@ fn insert_null_check<'tcx>(
     tcx: TyCtxt<'tcx>,
     pointer: Place<'tcx>,
     pointee_ty: Ty<'tcx>,
+    context: PlaceContext,
     local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>,
     stmts: &mut Vec<Statement<'tcx>>,
     source_info: SourceInfo,
@@ -42,30 +43,51 @@ fn insert_null_check<'tcx>(
     let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
     stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new((addr, rvalue))) });
 
-    // Get size of the pointee (zero-sized reads and writes are allowed).
-    let rvalue = Rvalue::NullaryOp(NullOp::SizeOf, pointee_ty);
-    let sizeof_pointee =
-        local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
-    stmts.push(Statement {
-        source_info,
-        kind: StatementKind::Assign(Box::new((sizeof_pointee, rvalue))),
-    });
-
-    // Check that the pointee is not a ZST.
     let zero = Operand::Constant(Box::new(ConstOperand {
         span: source_info.span,
         user_ty: None,
-        const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)), tcx.types.usize),
+        const_: Const::Val(ConstValue::from_target_usize(0, &tcx), tcx.types.usize),
     }));
-    let is_pointee_no_zst =
-        local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
-    stmts.push(Statement {
-        source_info,
-        kind: StatementKind::Assign(Box::new((
-            is_pointee_no_zst,
-            Rvalue::BinaryOp(BinOp::Ne, Box::new((Operand::Copy(sizeof_pointee), zero.clone()))),
-        ))),
-    });
+
+    let pointee_should_be_checked = match context {
+        // Borrows pointing to "null" are UB even if the pointee is a ZST.
+        PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
+        | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
+            // Pointer should be checked unconditionally.
+            Operand::Constant(Box::new(ConstOperand {
+                span: source_info.span,
+                user_ty: None,
+                const_: Const::Val(ConstValue::from_bool(true), tcx.types.bool),
+            }))
+        }
+        // Other usages of null pointers only are UB if the pointee is not a ZST.
+        _ => {
+            let rvalue = Rvalue::NullaryOp(NullOp::SizeOf, pointee_ty);
+            let sizeof_pointee =
+                local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
+            stmts.push(Statement {
+                source_info,
+                kind: StatementKind::Assign(Box::new((sizeof_pointee, rvalue))),
+            });
+
+            // Check that the pointee is not a ZST.
+            let is_pointee_not_zst =
+                local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
+            stmts.push(Statement {
+                source_info,
+                kind: StatementKind::Assign(Box::new((
+                    is_pointee_not_zst,
+                    Rvalue::BinaryOp(
+                        BinOp::Ne,
+                        Box::new((Operand::Copy(sizeof_pointee), zero.clone())),
+                    ),
+                ))),
+            });
+
+            // Pointer needs to be checked only if pointee is not a ZST.
+            Operand::Copy(is_pointee_not_zst)
+        }
+    };
 
     // Check whether the pointer is null.
     let is_null = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
@@ -77,7 +99,8 @@ fn insert_null_check<'tcx>(
         ))),
     });
 
-    // We want to throw an exception if the pointer is null and doesn't point to a ZST.
+    // We want to throw an exception if the pointer is null and the pointee is not unconditionally
+    // allowed (which for all non-borrow place uses, is when the pointee is ZST).
     let should_throw_exception =
         local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
     stmts.push(Statement {
@@ -86,7 +109,7 @@ fn insert_null_check<'tcx>(
             should_throw_exception,
             Rvalue::BinaryOp(
                 BinOp::BitAnd,
-                Box::new((Operand::Copy(is_null), Operand::Copy(is_pointee_no_zst))),
+                Box::new((Operand::Copy(is_null), pointee_should_be_checked)),
             ),
         ))),
     });
diff --git a/compiler/rustc_mir_transform/src/check_pointers.rs b/compiler/rustc_mir_transform/src/check_pointers.rs
index 72460542f87..ccaa83fd9e2 100644
--- a/compiler/rustc_mir_transform/src/check_pointers.rs
+++ b/compiler/rustc_mir_transform/src/check_pointers.rs
@@ -40,10 +40,10 @@ pub(crate) enum BorrowCheckMode {
 ///   success and fail the check otherwise.
 /// This utility will insert a terminator block that asserts on the condition
 /// and panics on failure.
-pub(crate) fn check_pointers<'a, 'tcx, F>(
+pub(crate) fn check_pointers<'tcx, F>(
     tcx: TyCtxt<'tcx>,
     body: &mut Body<'tcx>,
-    excluded_pointees: &'a [Ty<'tcx>],
+    excluded_pointees: &[Ty<'tcx>],
     on_finding: F,
     borrow_check_mode: BorrowCheckMode,
 ) where
@@ -51,6 +51,7 @@ pub(crate) fn check_pointers<'a, 'tcx, F>(
         /* tcx: */ TyCtxt<'tcx>,
         /* pointer: */ Place<'tcx>,
         /* pointee_ty: */ Ty<'tcx>,
+        /* context: */ PlaceContext,
         /* local_decls: */ &mut IndexVec<Local, LocalDecl<'tcx>>,
         /* stmts: */ &mut Vec<Statement<'tcx>>,
         /* source_info: */ SourceInfo,
@@ -86,7 +87,7 @@ pub(crate) fn check_pointers<'a, 'tcx, F>(
             );
             finder.visit_statement(statement, location);
 
-            for (local, ty) in finder.into_found_pointers() {
+            for (local, ty, context) in finder.into_found_pointers() {
                 debug!("Inserting check for {:?}", ty);
                 let new_block = split_block(basic_blocks, location);
 
@@ -98,6 +99,7 @@ pub(crate) fn check_pointers<'a, 'tcx, F>(
                     tcx,
                     local,
                     ty,
+                    context,
                     local_decls,
                     &mut block_data.statements,
                     source_info,
@@ -125,7 +127,7 @@ struct PointerFinder<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     local_decls: &'a mut LocalDecls<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
-    pointers: Vec<(Place<'tcx>, Ty<'tcx>)>,
+    pointers: Vec<(Place<'tcx>, Ty<'tcx>, PlaceContext)>,
     excluded_pointees: &'a [Ty<'tcx>],
     borrow_check_mode: BorrowCheckMode,
 }
@@ -148,7 +150,7 @@ impl<'a, 'tcx> PointerFinder<'a, 'tcx> {
         }
     }
 
-    fn into_found_pointers(self) -> Vec<(Place<'tcx>, Ty<'tcx>)> {
+    fn into_found_pointers(self) -> Vec<(Place<'tcx>, Ty<'tcx>, PlaceContext)> {
         self.pointers
     }
 
@@ -211,7 +213,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> {
             return;
         }
 
-        self.pointers.push((pointer, pointee_ty));
+        self.pointers.push((pointer, pointee_ty, context));
 
         self.super_place(place, context, location);
     }
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 3b75be58e43..a9bdbeb9cb8 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -1044,11 +1044,14 @@ fn insert_switch<'tcx>(
     let switch = TerminatorKind::SwitchInt { discr: Operand::Move(discr), targets: switch_targets };
 
     let source_info = SourceInfo::outermost(body.span);
-    body.basic_blocks_mut().raw.insert(0, BasicBlockData {
-        statements: vec![assign],
-        terminator: Some(Terminator { source_info, kind: switch }),
-        is_cleanup: false,
-    });
+    body.basic_blocks_mut().raw.insert(
+        0,
+        BasicBlockData {
+            statements: vec![assign],
+            terminator: Some(Terminator { source_info, kind: switch }),
+            is_cleanup: false,
+        },
+    );
 
     let blocks = body.basic_blocks_mut().iter_mut();
 
@@ -1594,13 +1597,16 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
         // (which is now a generator interior).
         let source_info = SourceInfo::outermost(body.span);
         let stmts = &mut body.basic_blocks_mut()[START_BLOCK].statements;
-        stmts.insert(0, Statement {
-            source_info,
-            kind: StatementKind::Assign(Box::new((
-                old_resume_local.into(),
-                Rvalue::Use(Operand::Move(resume_local.into())),
-            ))),
-        });
+        stmts.insert(
+            0,
+            Statement {
+                source_info,
+                kind: StatementKind::Assign(Box::new((
+                    old_resume_local.into(),
+                    Rvalue::Use(Operand::Move(resume_local.into())),
+                ))),
+            },
+        );
 
         let always_live_locals = always_storage_live_locals(body);
 
@@ -1839,12 +1845,17 @@ fn check_suspend_tys<'tcx>(tcx: TyCtxt<'tcx>, layout: &CoroutineLayout<'tcx>, bo
                     continue;
                 };
 
-                check_must_not_suspend_ty(tcx, decl.ty, hir_id, SuspendCheckData {
-                    source_span: decl.source_info.span,
-                    yield_span: yield_source_info.span,
-                    plural_len: 1,
-                    ..Default::default()
-                });
+                check_must_not_suspend_ty(
+                    tcx,
+                    decl.ty,
+                    hir_id,
+                    SuspendCheckData {
+                        source_span: decl.source_info.span,
+                        yield_span: yield_source_info.span,
+                        plural_len: 1,
+                        ..Default::default()
+                    },
+                );
             }
         }
     }
@@ -1883,13 +1894,17 @@ fn check_must_not_suspend_ty<'tcx>(
         ty::Adt(_, args) if ty.is_box() => {
             let boxed_ty = args.type_at(0);
             let allocator_ty = args.type_at(1);
-            check_must_not_suspend_ty(tcx, boxed_ty, hir_id, SuspendCheckData {
-                descr_pre: &format!("{}boxed ", data.descr_pre),
-                ..data
-            }) || check_must_not_suspend_ty(tcx, allocator_ty, hir_id, SuspendCheckData {
-                descr_pre: &format!("{}allocator ", data.descr_pre),
-                ..data
-            })
+            check_must_not_suspend_ty(
+                tcx,
+                boxed_ty,
+                hir_id,
+                SuspendCheckData { descr_pre: &format!("{}boxed ", data.descr_pre), ..data },
+            ) || check_must_not_suspend_ty(
+                tcx,
+                allocator_ty,
+                hir_id,
+                SuspendCheckData { descr_pre: &format!("{}allocator ", data.descr_pre), ..data },
+            )
         }
         ty::Adt(def, _) => check_must_not_suspend_def(tcx, def.did(), hir_id, data),
         // FIXME: support adding the attribute to TAITs
@@ -1902,10 +1917,12 @@ fn check_must_not_suspend_ty<'tcx>(
                 {
                     let def_id = poly_trait_predicate.trait_ref.def_id;
                     let descr_pre = &format!("{}implementer{} of ", data.descr_pre, plural_suffix);
-                    if check_must_not_suspend_def(tcx, def_id, hir_id, SuspendCheckData {
-                        descr_pre,
-                        ..data
-                    }) {
+                    if check_must_not_suspend_def(
+                        tcx,
+                        def_id,
+                        hir_id,
+                        SuspendCheckData { descr_pre, ..data },
+                    ) {
                         has_emitted = true;
                         break;
                     }
@@ -1919,10 +1936,12 @@ fn check_must_not_suspend_ty<'tcx>(
                 if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
                     let def_id = trait_ref.def_id;
                     let descr_post = &format!(" trait object{}{}", plural_suffix, data.descr_post);
-                    if check_must_not_suspend_def(tcx, def_id, hir_id, SuspendCheckData {
-                        descr_post,
-                        ..data
-                    }) {
+                    if check_must_not_suspend_def(
+                        tcx,
+                        def_id,
+                        hir_id,
+                        SuspendCheckData { descr_post, ..data },
+                    ) {
                         has_emitted = true;
                         break;
                     }
@@ -1934,10 +1953,12 @@ fn check_must_not_suspend_ty<'tcx>(
             let mut has_emitted = false;
             for (i, ty) in fields.iter().enumerate() {
                 let descr_post = &format!(" in tuple element {i}");
-                if check_must_not_suspend_ty(tcx, ty, hir_id, SuspendCheckData {
-                    descr_post,
-                    ..data
-                }) {
+                if check_must_not_suspend_ty(
+                    tcx,
+                    ty,
+                    hir_id,
+                    SuspendCheckData { descr_post, ..data },
+                ) {
                     has_emitted = true;
                 }
             }
@@ -1945,12 +1966,17 @@ fn check_must_not_suspend_ty<'tcx>(
         }
         ty::Array(ty, len) => {
             let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix);
-            check_must_not_suspend_ty(tcx, ty, hir_id, SuspendCheckData {
-                descr_pre,
-                // FIXME(must_not_suspend): This is wrong. We should handle printing unevaluated consts.
-                plural_len: len.try_to_target_usize(tcx).unwrap_or(0) as usize + 1,
-                ..data
-            })
+            check_must_not_suspend_ty(
+                tcx,
+                ty,
+                hir_id,
+                SuspendCheckData {
+                    descr_pre,
+                    // FIXME(must_not_suspend): This is wrong. We should handle printing unevaluated consts.
+                    plural_len: len.try_to_target_usize(tcx).unwrap_or(0) as usize + 1,
+                    ..data
+                },
+            )
         }
         // If drop tracking is enabled, we want to look through references, since the referent
         // may not be considered live across the await point.
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 9f5bb015fa3..0f5fcb0d8eb 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -138,10 +138,10 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
             // If the parent capture is by-ref, then we need to apply an additional
             // deref before applying any further projections to this place.
             if parent_capture.is_by_ref() {
-                child_precise_captures.insert(0, Projection {
-                    ty: parent_capture.place.ty(),
-                    kind: ProjectionKind::Deref,
-                });
+                child_precise_captures.insert(
+                    0,
+                    Projection { ty: parent_capture.place.ty(), kind: ProjectionKind::Deref },
+                );
             }
             // If the child capture is by-ref, then we need to apply a "ref"
             // projection (i.e. `&`) at the end. But wait! We don't have that
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index adb99a75a9e..6f9984d5d0a 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -2,7 +2,6 @@ use std::cmp::Ordering;
 
 use either::Either;
 use itertools::Itertools;
-use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_data_structures::graph::DirectedGraph;
 use rustc_index::IndexVec;
@@ -11,31 +10,35 @@ use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId,
 
 use crate::coverage::counters::balanced_flow::BalancedFlowGraph;
 use crate::coverage::counters::node_flow::{
-    CounterTerm, NodeCounters, make_node_counters, node_flow_data_for_balanced_graph,
+    CounterTerm, NodeCounters, NodeFlowData, node_flow_data_for_balanced_graph,
 };
 use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
 
 mod balanced_flow;
-mod node_flow;
+pub(crate) mod node_flow;
 mod union_find;
 
-/// Ensures that each BCB node needing a counter has one, by creating physical
-/// counters or counter expressions for nodes as required.
-pub(super) fn make_bcb_counters(
-    graph: &CoverageGraph,
-    bcb_needs_counter: &DenseBitSet<BasicCoverageBlock>,
-) -> CoverageCounters {
+/// Struct containing the results of [`prepare_bcb_counters_data`].
+pub(crate) struct BcbCountersData {
+    pub(crate) node_flow_data: NodeFlowData<BasicCoverageBlock>,
+    pub(crate) priority_list: Vec<BasicCoverageBlock>,
+}
+
+/// Analyzes the coverage graph to create intermediate data structures that
+/// will later be used (during codegen) to create physical counters or counter
+/// expressions for each BCB node that needs one.
+pub(crate) fn prepare_bcb_counters_data(graph: &CoverageGraph) -> BcbCountersData {
     // Create the derived graphs that are necessary for subsequent steps.
     let balanced_graph = BalancedFlowGraph::for_graph(graph, |n| !graph[n].is_out_summable);
     let node_flow_data = node_flow_data_for_balanced_graph(&balanced_graph);
 
-    // Use those graphs to determine which nodes get physical counters, and how
-    // to compute the execution counts of other nodes from those counters.
+    // Also create a "priority list" of coverage graph nodes, to help determine
+    // which ones get physical counters or counter expressions. This needs to
+    // be done now, because the later parts of the counter-creation process
+    // won't have access to the original coverage graph.
     let priority_list = make_node_flow_priority_list(graph, balanced_graph);
-    let node_counters = make_node_counters(&node_flow_data, &priority_list);
 
-    // Convert the counters into a form suitable for embedding into MIR.
-    transcribe_counters(&node_counters, bcb_needs_counter)
+    BcbCountersData { node_flow_data, priority_list }
 }
 
 /// Arranges the nodes in `balanced_graph` into a list, such that earlier nodes
@@ -74,31 +77,33 @@ fn make_node_flow_priority_list(
 }
 
 // Converts node counters into a form suitable for embedding into MIR.
-fn transcribe_counters(
+pub(crate) fn transcribe_counters(
     old: &NodeCounters<BasicCoverageBlock>,
     bcb_needs_counter: &DenseBitSet<BasicCoverageBlock>,
+    bcbs_seen: &DenseBitSet<BasicCoverageBlock>,
 ) -> CoverageCounters {
     let mut new = CoverageCounters::with_num_bcbs(bcb_needs_counter.domain_size());
 
     for bcb in bcb_needs_counter.iter() {
+        if !bcbs_seen.contains(bcb) {
+            // This BCB's code was removed by MIR opts, so its counter is always zero.
+            new.set_node_counter(bcb, CovTerm::Zero);
+            continue;
+        }
+
         // Our counter-creation algorithm doesn't guarantee that a node's list
         // of terms starts or ends with a positive term, so partition the
         // counters into "positive" and "negative" lists for easier handling.
-        let (mut pos, mut neg): (Vec<_>, Vec<_>) =
-            old.counter_terms[bcb].iter().partition_map(|&CounterTerm { node, op }| match op {
+        let (mut pos, mut neg): (Vec<_>, Vec<_>) = old.counter_terms[bcb]
+            .iter()
+            // Filter out any BCBs that were removed by MIR opts;
+            // this treats them as having an execution count of 0.
+            .filter(|term| bcbs_seen.contains(term.node))
+            .partition_map(|&CounterTerm { node, op }| match op {
                 Op::Add => Either::Left(node),
                 Op::Subtract => Either::Right(node),
             });
 
-        if pos.is_empty() {
-            // If we somehow end up with no positive terms, fall back to
-            // creating a physical counter. There's no known way for this
-            // to happen, but we can avoid an ICE if it does.
-            debug_assert!(false, "{bcb:?} has no positive counter terms");
-            pos = vec![bcb];
-            neg = vec![];
-        }
-
         // These intermediate sorts are not strictly necessary, but were helpful
         // in reducing churn when switching to the current counter-creation scheme.
         // They also help to slightly decrease the overall size of the expression
@@ -116,7 +121,7 @@ fn transcribe_counters(
         pos.sort();
         neg.sort();
 
-        let pos_counter = new.make_sum(&pos).expect("`pos` should not be empty");
+        let pos_counter = new.make_sum(&pos).unwrap_or(CovTerm::Zero);
         let new_counter = new.make_subtracted_sum(pos_counter, &neg);
         new.set_node_counter(bcb, new_counter);
     }
@@ -129,15 +134,15 @@ fn transcribe_counters(
 pub(super) struct CoverageCounters {
     /// List of places where a counter-increment statement should be injected
     /// into MIR, each with its corresponding counter ID.
-    phys_counter_for_node: FxIndexMap<BasicCoverageBlock, CounterId>,
-    next_counter_id: CounterId,
+    pub(crate) phys_counter_for_node: FxIndexMap<BasicCoverageBlock, CounterId>,
+    pub(crate) next_counter_id: CounterId,
 
     /// Coverage counters/expressions that are associated with individual BCBs.
-    node_counters: IndexVec<BasicCoverageBlock, Option<CovTerm>>,
+    pub(crate) node_counters: IndexVec<BasicCoverageBlock, Option<CovTerm>>,
 
     /// Table of expression data, associating each expression ID with its
     /// corresponding operator (+ or -) and its LHS/RHS operands.
-    expressions: IndexVec<ExpressionId, Expression>,
+    pub(crate) expressions: IndexVec<ExpressionId, Expression>,
     /// Remember expressions that have already been created (or simplified),
     /// so that we don't create unnecessary duplicates.
     expressions_memo: FxHashMap<Expression, CovTerm>,
@@ -188,12 +193,6 @@ impl CoverageCounters {
         self.make_expression(lhs, Op::Subtract, rhs_sum)
     }
 
-    pub(super) fn num_counters(&self) -> usize {
-        let num_counters = self.phys_counter_for_node.len();
-        assert_eq!(num_counters, self.next_counter_id.as_usize());
-        num_counters
-    }
-
     fn set_node_counter(&mut self, bcb: BasicCoverageBlock, counter: CovTerm) -> CovTerm {
         let existing = self.node_counters[bcb].replace(counter);
         assert!(
@@ -202,34 +201,4 @@ impl CoverageCounters {
         );
         counter
     }
-
-    pub(super) fn term_for_bcb(&self, bcb: BasicCoverageBlock) -> Option<CovTerm> {
-        self.node_counters[bcb]
-    }
-
-    /// Returns an iterator over all the nodes in the coverage graph that
-    /// should have a counter-increment statement injected into MIR, along with
-    /// each site's corresponding counter ID.
-    pub(super) fn counter_increment_sites(
-        &self,
-    ) -> impl Iterator<Item = (CounterId, BasicCoverageBlock)> + Captures<'_> {
-        self.phys_counter_for_node.iter().map(|(&site, &id)| (id, site))
-    }
-
-    /// Returns an iterator over the subset of BCB nodes that have been associated
-    /// with a counter *expression*, along with the ID of that expression.
-    pub(super) fn bcb_nodes_with_coverage_expressions(
-        &self,
-    ) -> impl Iterator<Item = (BasicCoverageBlock, ExpressionId)> + Captures<'_> {
-        self.node_counters.iter_enumerated().filter_map(|(bcb, &counter)| match counter {
-            // Yield the BCB along with its associated expression ID.
-            Some(CovTerm::Expression(id)) => Some((bcb, id)),
-            // This BCB is associated with a counter or nothing, so skip it.
-            Some(CovTerm::Counter { .. } | CovTerm::Zero) | None => None,
-        })
-    }
-
-    pub(super) fn into_expressions(self) -> IndexVec<ExpressionId, Expression> {
-        self.expressions
-    }
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs b/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs
index 9d80b3af42d..91ed54b8b59 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs
@@ -9,6 +9,7 @@
 use rustc_data_structures::graph;
 use rustc_index::bit_set::DenseBitSet;
 use rustc_index::{Idx, IndexSlice, IndexVec};
+pub(crate) use rustc_middle::mir::coverage::NodeFlowData;
 use rustc_middle::mir::coverage::Op;
 
 use crate::coverage::counters::union_find::UnionFind;
@@ -16,30 +17,6 @@ use crate::coverage::counters::union_find::UnionFind;
 #[cfg(test)]
 mod tests;
 
-/// Data representing a view of some underlying graph, in which each node's
-/// successors have been merged into a single "supernode".
-///
-/// The resulting supernodes have no obvious meaning on their own.
-/// However, merging successor nodes means that a node's out-edges can all
-/// be combined into a single out-edge, whose flow is the same as the flow
-/// (execution count) of its corresponding node in the original graph.
-///
-/// With all node flows now in the original graph now represented as edge flows
-/// in the merged graph, it becomes possible to analyze the original node flows
-/// using techniques for analyzing edge flows.
-#[derive(Debug)]
-pub(crate) struct NodeFlowData<Node: Idx> {
-    /// Maps each node to the supernode that contains it, indicated by some
-    /// arbitrary "root" node that is part of that supernode.
-    supernodes: IndexVec<Node, Node>,
-    /// For each node, stores the single supernode that all of its successors
-    /// have been merged into.
-    ///
-    /// (Note that each node in a supernode can potentially have a _different_
-    /// successor supernode from its peers.)
-    succ_supernodes: IndexVec<Node, Node>,
-}
-
 /// Creates a "merged" view of an underlying graph.
 ///
 /// The given graph is assumed to have [“balanced flow”](balanced-flow),
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs b/compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs
index b509a14514b..46c46c743c2 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs
@@ -20,29 +20,25 @@ fn make_graph<Node: Idx + Ord>(num_nodes: usize, edge_pairs: Vec<(Node, Node)>)
 /// (Knuth & Stevenson, 1973), but with 0-based node IDs.
 #[test]
 fn example_driver() {
-    let graph = make_graph::<u32>(5, vec![
-        (0, 1),
-        (0, 3),
-        (1, 0),
-        (1, 2),
-        (2, 1),
-        (2, 4),
-        (3, 3),
-        (3, 4),
-        (4, 0),
-    ]);
+    let graph = make_graph::<u32>(
+        5,
+        vec![(0, 1), (0, 3), (1, 0), (1, 2), (2, 1), (2, 4), (3, 3), (3, 4), (4, 0)],
+    );
 
     let node_flow_data = node_flow_data(&graph);
     let counters = make_node_counters(&node_flow_data, &[3, 1, 2, 0, 4]);
 
-    assert_eq!(format_counter_expressions(&counters), &[
-        // (comment to force vertical formatting for clarity)
-        "[0]: +c0",
-        "[1]: +c0 +c2 -c4",
-        "[2]: +c2",
-        "[3]: +c3",
-        "[4]: +c4",
-    ]);
+    assert_eq!(
+        format_counter_expressions(&counters),
+        &[
+            // (comment to force vertical formatting for clarity)
+            "[0]: +c0",
+            "[1]: +c0 +c2 -c4",
+            "[2]: +c2",
+            "[3]: +c3",
+            "[4]: +c4",
+        ]
+    );
 }
 
 fn format_counter_expressions<Node: Idx>(counters: &NodeCounters<Node>) -> Vec<String> {
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 392b54c8d81..6d84248ddfb 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -8,6 +8,7 @@ use rustc_data_structures::graph::dominators::Dominators;
 use rustc_data_structures::graph::{self, DirectedGraph, StartNode};
 use rustc_index::IndexVec;
 use rustc_index::bit_set::DenseBitSet;
+pub(crate) use rustc_middle::mir::coverage::{BasicCoverageBlock, START_BCB};
 use rustc_middle::mir::{self, BasicBlock, Terminator, TerminatorKind};
 use tracing::debug;
 
@@ -269,15 +270,6 @@ impl graph::Predecessors for CoverageGraph {
     }
 }
 
-rustc_index::newtype_index! {
-    /// A node in the control-flow graph of CoverageGraph.
-    #[orderable]
-    #[debug_format = "bcb{}"]
-    pub(crate) struct BasicCoverageBlock {
-        const START_BCB = 0;
-    }
-}
-
 /// `BasicCoverageBlockData` holds the data indexed by a `BasicCoverageBlock`.
 ///
 /// A `BasicCoverageBlock` (BCB) represents the maximal-length sequence of MIR `BasicBlock`s without
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
index 8d0d92dc367..d83c0d40a7e 100644
--- a/compiler/rustc_mir_transform/src/coverage/mappings.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -1,9 +1,7 @@
 use std::collections::BTreeSet;
 
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::graph::DirectedGraph;
 use rustc_index::IndexVec;
-use rustc_index::bit_set::DenseBitSet;
 use rustc_middle::mir::coverage::{
     BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageInfoHi, CoverageKind,
 };
@@ -63,10 +61,6 @@ const MCDC_MAX_BITMAP_SIZE: usize = i32::MAX as usize;
 
 #[derive(Default)]
 pub(super) struct ExtractedMappings {
-    /// Store our own copy of [`CoverageGraph::num_nodes`], so that we don't
-    /// need access to the whole graph when allocating per-BCB data. This is
-    /// only public so that other code can still use exhaustive destructuring.
-    pub(super) num_bcbs: usize,
     pub(super) code_mappings: Vec<CodeMapping>,
     pub(super) branch_pairs: Vec<BranchPair>,
     pub(super) mcdc_bitmap_bits: usize,
@@ -118,7 +112,6 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
     );
 
     ExtractedMappings {
-        num_bcbs: graph.num_nodes(),
         code_mappings,
         branch_pairs,
         mcdc_bitmap_bits,
@@ -127,60 +120,6 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
     }
 }
 
-impl ExtractedMappings {
-    pub(super) fn all_bcbs_with_counter_mappings(&self) -> DenseBitSet<BasicCoverageBlock> {
-        // Fully destructure self to make sure we don't miss any fields that have mappings.
-        let Self {
-            num_bcbs,
-            code_mappings,
-            branch_pairs,
-            mcdc_bitmap_bits: _,
-            mcdc_degraded_branches,
-            mcdc_mappings,
-        } = self;
-
-        // Identify which BCBs have one or more mappings.
-        let mut bcbs_with_counter_mappings = DenseBitSet::new_empty(*num_bcbs);
-        let mut insert = |bcb| {
-            bcbs_with_counter_mappings.insert(bcb);
-        };
-
-        for &CodeMapping { span: _, bcb } in code_mappings {
-            insert(bcb);
-        }
-        for &BranchPair { true_bcb, false_bcb, .. } in branch_pairs {
-            insert(true_bcb);
-            insert(false_bcb);
-        }
-        for &MCDCBranch { true_bcb, false_bcb, .. } in mcdc_degraded_branches
-            .iter()
-            .chain(mcdc_mappings.iter().map(|(_, branches)| branches.into_iter()).flatten())
-        {
-            insert(true_bcb);
-            insert(false_bcb);
-        }
-
-        // MC/DC decisions refer to BCBs, but don't require those BCBs to have counters.
-        if bcbs_with_counter_mappings.is_empty() {
-            debug_assert!(
-                mcdc_mappings.is_empty(),
-                "A function with no counter mappings shouldn't have any decisions: {mcdc_mappings:?}",
-            );
-        }
-
-        bcbs_with_counter_mappings
-    }
-
-    /// Returns the set of BCBs that have one or more `Code` mappings.
-    pub(super) fn bcbs_with_ordinary_code_mappings(&self) -> DenseBitSet<BasicCoverageBlock> {
-        let mut bcbs = DenseBitSet::new_empty(self.num_bcbs);
-        for &CodeMapping { span: _, bcb } in &self.code_mappings {
-            bcbs.insert(bcb);
-        }
-        bcbs
-    }
-}
-
 fn resolve_block_markers(
     coverage_info_hi: &CoverageInfoHi,
     mir_body: &mir::Body<'_>,
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 15487d05a30..e195681bc92 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -21,7 +21,7 @@ use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use tracing::{debug, debug_span, trace};
 
-use crate::coverage::counters::CoverageCounters;
+use crate::coverage::counters::BcbCountersData;
 use crate::coverage::graph::CoverageGraph;
 use crate::coverage::mappings::ExtractedMappings;
 
@@ -82,28 +82,21 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
     let extracted_mappings =
         mappings::extract_all_mapping_info_from_mir(tcx, mir_body, &hir_info, &graph);
 
-    ////////////////////////////////////////////////////
-    // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
-    // every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
-    // and all `Expression` dependencies (operands) are also generated, for any other
-    // `BasicCoverageBlock`s not already associated with a coverage span.
-    let bcbs_with_counter_mappings = extracted_mappings.all_bcbs_with_counter_mappings();
-    if bcbs_with_counter_mappings.is_empty() {
-        // No relevant spans were found in MIR, so skip instrumenting this function.
-        return;
-    }
-
-    let coverage_counters = counters::make_bcb_counters(&graph, &bcbs_with_counter_mappings);
-
-    let mappings = create_mappings(&extracted_mappings, &coverage_counters);
+    let mappings = create_mappings(&extracted_mappings);
     if mappings.is_empty() {
         // No spans could be converted into valid mappings, so skip this function.
         debug!("no spans could be converted into valid mappings; skipping");
         return;
     }
 
-    inject_coverage_statements(mir_body, &graph, &extracted_mappings, &coverage_counters);
+    // Use the coverage graph to prepare intermediate data that will eventually
+    // be used to assign physical counters and counter expressions to points in
+    // the control-flow graph
+    let BcbCountersData { node_flow_data, priority_list } =
+        counters::prepare_bcb_counters_data(&graph);
 
+    // Inject coverage statements into MIR.
+    inject_coverage_statements(mir_body, &graph);
     inject_mcdc_statements(mir_body, &graph, &extracted_mappings);
 
     let mcdc_num_condition_bitmaps = extracted_mappings
@@ -116,29 +109,25 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
     mir_body.function_coverage_info = Some(Box::new(FunctionCoverageInfo {
         function_source_hash: hir_info.function_source_hash,
         body_span: hir_info.body_span,
-        num_counters: coverage_counters.num_counters(),
-        mcdc_bitmap_bits: extracted_mappings.mcdc_bitmap_bits,
-        expressions: coverage_counters.into_expressions(),
+
+        node_flow_data,
+        priority_list,
+
         mappings,
+
+        mcdc_bitmap_bits: extracted_mappings.mcdc_bitmap_bits,
         mcdc_num_condition_bitmaps,
     }));
 }
 
-/// For each coverage span extracted from MIR, create a corresponding
-/// mapping.
+/// For each coverage span extracted from MIR, create a corresponding mapping.
 ///
-/// Precondition: All BCBs corresponding to those spans have been given
-/// coverage counters.
-fn create_mappings(
-    extracted_mappings: &ExtractedMappings,
-    coverage_counters: &CoverageCounters,
-) -> Vec<Mapping> {
-    let term_for_bcb =
-        |bcb| coverage_counters.term_for_bcb(bcb).expect("all BCBs with spans were given counters");
-
+/// FIXME(Zalathar): This used to be where BCBs in the extracted mappings were
+/// resolved to a `CovTerm`. But that is now handled elsewhere, so this
+/// function can potentially be simplified even further.
+fn create_mappings(extracted_mappings: &ExtractedMappings) -> Vec<Mapping> {
     // Fully destructure the mappings struct to make sure we don't miss any kinds.
     let ExtractedMappings {
-        num_bcbs: _,
         code_mappings,
         branch_pairs,
         mcdc_bitmap_bits: _,
@@ -150,23 +139,18 @@ fn create_mappings(
     mappings.extend(code_mappings.iter().map(
         // Ordinary code mappings are the simplest kind.
         |&mappings::CodeMapping { span, bcb }| {
-            let kind = MappingKind::Code(term_for_bcb(bcb));
+            let kind = MappingKind::Code { bcb };
             Mapping { kind, span }
         },
     ));
 
     mappings.extend(branch_pairs.iter().map(
         |&mappings::BranchPair { span, true_bcb, false_bcb }| {
-            let true_term = term_for_bcb(true_bcb);
-            let false_term = term_for_bcb(false_bcb);
-            let kind = MappingKind::Branch { true_term, false_term };
+            let kind = MappingKind::Branch { true_bcb, false_bcb };
             Mapping { kind, span }
         },
     ));
 
-    let term_for_bcb =
-        |bcb| coverage_counters.term_for_bcb(bcb).expect("all BCBs with spans were given counters");
-
     // MCDC branch mappings are appended with their decisions in case decisions were ignored.
     mappings.extend(mcdc_degraded_branches.iter().map(
         |&mappings::MCDCBranch {
@@ -176,11 +160,7 @@ fn create_mappings(
              condition_info: _,
              true_index: _,
              false_index: _,
-         }| {
-            let true_term = term_for_bcb(true_bcb);
-            let false_term = term_for_bcb(false_bcb);
-            Mapping { kind: MappingKind::Branch { true_term, false_term }, span }
-        },
+         }| { Mapping { kind: MappingKind::Branch { true_bcb, false_bcb }, span } },
     ));
 
     for (decision, branches) in mcdc_mappings {
@@ -201,12 +181,10 @@ fn create_mappings(
                      true_index: _,
                      false_index: _,
                  }| {
-                    let true_term = term_for_bcb(true_bcb);
-                    let false_term = term_for_bcb(false_bcb);
                     Mapping {
                         kind: MappingKind::MCDCBranch {
-                            true_term,
-                            false_term,
+                            true_bcb,
+                            false_bcb,
                             mcdc_params: condition_info,
                         },
                         span,
@@ -227,41 +205,11 @@ fn create_mappings(
     mappings
 }
 
-/// For each BCB node or BCB edge that has an associated coverage counter,
-/// inject any necessary coverage statements into MIR.
-fn inject_coverage_statements<'tcx>(
-    mir_body: &mut mir::Body<'tcx>,
-    graph: &CoverageGraph,
-    extracted_mappings: &ExtractedMappings,
-    coverage_counters: &CoverageCounters,
-) {
-    // Inject counter-increment statements into MIR.
-    for (id, bcb) in coverage_counters.counter_increment_sites() {
-        let target_bb = graph[bcb].leader_bb();
-        inject_statement(mir_body, CoverageKind::CounterIncrement { id }, target_bb);
-    }
-
-    // For each counter expression that is directly associated with at least one
-    // span, we inject an "expression-used" statement, so that coverage codegen
-    // can check whether the injected statement survived MIR optimization.
-    // (BCB edges can't have spans, so we only need to process BCB nodes here.)
-    //
-    // We only do this for ordinary `Code` mappings, because branch and MC/DC
-    // mappings might have expressions that don't correspond to any single
-    // point in the control-flow graph.
-    //
-    // See the code in `rustc_codegen_llvm::coverageinfo::map_data` that deals
-    // with "expressions seen" and "zero terms".
-    let eligible_bcbs = extracted_mappings.bcbs_with_ordinary_code_mappings();
-    for (bcb, expression_id) in coverage_counters
-        .bcb_nodes_with_coverage_expressions()
-        .filter(|&(bcb, _)| eligible_bcbs.contains(bcb))
-    {
-        inject_statement(
-            mir_body,
-            CoverageKind::ExpressionUsed { id: expression_id },
-            graph[bcb].leader_bb(),
-        );
+/// Inject any necessary coverage statements into MIR, so that they influence codegen.
+fn inject_coverage_statements<'tcx>(mir_body: &mut mir::Body<'tcx>, graph: &CoverageGraph) {
+    for (bcb, data) in graph.iter_enumerated() {
+        let target_bb = data.leader_bb();
+        inject_statement(mir_body, CoverageKind::VirtualCounter { bcb }, target_bb);
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index a849ed4c3e2..cd89fbe772d 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -1,10 +1,7 @@
 use rustc_data_structures::captures::Captures;
 use rustc_index::bit_set::DenseBitSet;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc_middle::mir::coverage::{
-    CounterId, CovTerm, CoverageIdsInfo, CoverageKind, Expression, ExpressionId,
-    FunctionCoverageInfo, MappingKind, Op,
-};
+use rustc_middle::mir::coverage::{BasicCoverageBlock, CoverageIdsInfo, CoverageKind, MappingKind};
 use rustc_middle::mir::{Body, Statement, StatementKind};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::util::Providers;
@@ -12,6 +9,9 @@ use rustc_span::def_id::LocalDefId;
 use rustc_span::sym;
 use tracing::trace;
 
+use crate::coverage::counters::node_flow::make_node_counters;
+use crate::coverage::counters::{CoverageCounters, transcribe_counters};
+
 /// Registers query/hook implementations related to coverage.
 pub(crate) fn provide(providers: &mut Providers) {
     providers.hooks.is_eligible_for_coverage = is_eligible_for_coverage;
@@ -89,39 +89,57 @@ fn coverage_ids_info<'tcx>(
     let mir_body = tcx.instance_mir(instance_def);
     let fn_cov_info = mir_body.function_coverage_info.as_deref()?;
 
-    let mut counters_seen = DenseBitSet::new_empty(fn_cov_info.num_counters);
-    let mut expressions_seen = DenseBitSet::new_filled(fn_cov_info.expressions.len());
-
-    // For each expression ID that is directly used by one or more mappings,
-    // mark it as not-yet-seen. This indicates that we expect to see a
-    // corresponding `ExpressionUsed` statement during MIR traversal.
-    for mapping in fn_cov_info.mappings.iter() {
-        // Currently we only worry about ordinary code mappings.
-        // For branch and MC/DC mappings, expressions might not correspond
-        // to any particular point in the control-flow graph.
-        // (Keep this in sync with the injection of `ExpressionUsed`
-        // statements in the `InstrumentCoverage` MIR pass.)
-        if let MappingKind::Code(CovTerm::Expression(id)) = mapping.kind {
-            expressions_seen.remove(id);
-        }
-    }
-
+    // Scan through the final MIR to see which BCBs survived MIR opts.
+    // Any BCB not in this set was optimized away.
+    let mut bcbs_seen = DenseBitSet::new_empty(fn_cov_info.priority_list.len());
     for kind in all_coverage_in_mir_body(mir_body) {
         match *kind {
-            CoverageKind::CounterIncrement { id } => {
-                counters_seen.insert(id);
-            }
-            CoverageKind::ExpressionUsed { id } => {
-                expressions_seen.insert(id);
+            CoverageKind::VirtualCounter { bcb } => {
+                bcbs_seen.insert(bcb);
             }
             _ => {}
         }
     }
 
-    let zero_expressions =
-        identify_zero_expressions(fn_cov_info, &counters_seen, &expressions_seen);
+    // Determine the set of BCBs that are referred to by mappings, and therefore
+    // need a counter. Any node not in this set will only get a counter if it
+    // is part of the counter expression for a node that is in the set.
+    let mut bcb_needs_counter =
+        DenseBitSet::<BasicCoverageBlock>::new_empty(fn_cov_info.priority_list.len());
+    for mapping in &fn_cov_info.mappings {
+        match mapping.kind {
+            MappingKind::Code { bcb } => {
+                bcb_needs_counter.insert(bcb);
+            }
+            MappingKind::Branch { true_bcb, false_bcb } => {
+                bcb_needs_counter.insert(true_bcb);
+                bcb_needs_counter.insert(false_bcb);
+            }
+            MappingKind::MCDCBranch { true_bcb, false_bcb, mcdc_params: _ } => {
+                bcb_needs_counter.insert(true_bcb);
+                bcb_needs_counter.insert(false_bcb);
+            }
+            MappingKind::MCDCDecision(_) => {}
+        }
+    }
 
-    Some(CoverageIdsInfo { counters_seen, zero_expressions })
+    // FIXME(Zalathar): It should be possible to sort `priority_list[1..]` by
+    // `!bcbs_seen.contains(bcb)` to simplify the mappings even further, at the
+    // expense of some churn in the tests. When doing so, also consider removing
+    // the sorts in `transcribe_counters`.
+    let node_counters = make_node_counters(&fn_cov_info.node_flow_data, &fn_cov_info.priority_list);
+    let coverage_counters = transcribe_counters(&node_counters, &bcb_needs_counter, &bcbs_seen);
+
+    let CoverageCounters {
+        phys_counter_for_node, next_counter_id, node_counters, expressions, ..
+    } = coverage_counters;
+
+    Some(CoverageIdsInfo {
+        num_counters: next_counter_id.as_u32(),
+        phys_counter_for_node,
+        term_for_bcb: node_counters,
+        expressions,
+    })
 }
 
 fn all_coverage_in_mir_body<'a, 'tcx>(
@@ -139,94 +157,3 @@ fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool {
     let scope_data = &body.source_scopes[statement.source_info.scope];
     scope_data.inlined.is_some() || scope_data.inlined_parent_scope.is_some()
 }
-
-/// Identify expressions that will always have a value of zero, and note their
-/// IDs in a `DenseBitSet`. Mappings that refer to a zero expression can instead
-/// become mappings to a constant zero value.
-///
-/// This function mainly exists to preserve the simplifications that were
-/// already being performed by the Rust-side expression renumbering, so that
-/// the resulting coverage mappings don't get worse.
-fn identify_zero_expressions(
-    fn_cov_info: &FunctionCoverageInfo,
-    counters_seen: &DenseBitSet<CounterId>,
-    expressions_seen: &DenseBitSet<ExpressionId>,
-) -> DenseBitSet<ExpressionId> {
-    // The set of expressions that either were optimized out entirely, or
-    // have zero as both of their operands, and will therefore always have
-    // a value of zero. Other expressions that refer to these as operands
-    // can have those operands replaced with `CovTerm::Zero`.
-    let mut zero_expressions = DenseBitSet::new_empty(fn_cov_info.expressions.len());
-
-    // Simplify a copy of each expression based on lower-numbered expressions,
-    // and then update the set of always-zero expressions if necessary.
-    // (By construction, expressions can only refer to other expressions
-    // that have lower IDs, so one pass is sufficient.)
-    for (id, expression) in fn_cov_info.expressions.iter_enumerated() {
-        if !expressions_seen.contains(id) {
-            // If an expression was not seen, it must have been optimized away,
-            // so any operand that refers to it can be replaced with zero.
-            zero_expressions.insert(id);
-            continue;
-        }
-
-        // We don't need to simplify the actual expression data in the
-        // expressions list; we can just simplify a temporary copy and then
-        // use that to update the set of always-zero expressions.
-        let Expression { mut lhs, op, mut rhs } = *expression;
-
-        // If an expression has an operand that is also an expression, the
-        // operand's ID must be strictly lower. This is what lets us find
-        // all zero expressions in one pass.
-        let assert_operand_expression_is_lower = |operand_id: ExpressionId| {
-            assert!(
-                operand_id < id,
-                "Operand {operand_id:?} should be less than {id:?} in {expression:?}",
-            )
-        };
-
-        // If an operand refers to a counter or expression that is always
-        // zero, then that operand can be replaced with `CovTerm::Zero`.
-        let maybe_set_operand_to_zero = |operand: &mut CovTerm| {
-            if let CovTerm::Expression(id) = *operand {
-                assert_operand_expression_is_lower(id);
-            }
-
-            if is_zero_term(&counters_seen, &zero_expressions, *operand) {
-                *operand = CovTerm::Zero;
-            }
-        };
-        maybe_set_operand_to_zero(&mut lhs);
-        maybe_set_operand_to_zero(&mut rhs);
-
-        // Coverage counter values cannot be negative, so if an expression
-        // involves subtraction from zero, assume that its RHS must also be zero.
-        // (Do this after simplifications that could set the LHS to zero.)
-        if lhs == CovTerm::Zero && op == Op::Subtract {
-            rhs = CovTerm::Zero;
-        }
-
-        // After the above simplifications, if both operands are zero, then
-        // we know that this expression is always zero too.
-        if lhs == CovTerm::Zero && rhs == CovTerm::Zero {
-            zero_expressions.insert(id);
-        }
-    }
-
-    zero_expressions
-}
-
-/// Returns `true` if the given term is known to have a value of zero, taking
-/// into account knowledge of which counters are unused and which expressions
-/// are always zero.
-fn is_zero_term(
-    counters_seen: &DenseBitSet<CounterId>,
-    zero_expressions: &DenseBitSet<ExpressionId>,
-    term: CovTerm,
-) -> bool {
-    match term {
-        CovTerm::Zero => true,
-        CovTerm::Counter(id) => !counters_seen.contains(id),
-        CovTerm::Expression(id) => zero_expressions.contains(id),
-    }
-}
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 26ce743be36..73b68d7155c 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -137,8 +137,7 @@ fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span> {
 
         // These coverage statements should not exist prior to coverage instrumentation.
         StatementKind::Coverage(
-            CoverageKind::CounterIncrement { .. }
-            | CoverageKind::ExpressionUsed { .. }
+            CoverageKind::VirtualCounter { .. }
             | CoverageKind::CondBitmapUpdate { .. }
             | CoverageKind::TestVectorBitmapUpdate { .. },
         ) => bug!(
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index b2ee50de50a..3c0053c610d 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -129,15 +129,18 @@ impl<'tcx> MockBlocks<'tcx> {
     }
 
     fn call(&mut self, some_from_block: Option<BasicBlock>) -> BasicBlock {
-        self.add_block_from(some_from_block, TerminatorKind::Call {
-            func: Operand::Copy(self.dummy_place.clone()),
-            args: [].into(),
-            destination: self.dummy_place.clone(),
-            target: Some(TEMP_BLOCK),
-            unwind: UnwindAction::Continue,
-            call_source: CallSource::Misc,
-            fn_span: DUMMY_SP,
-        })
+        self.add_block_from(
+            some_from_block,
+            TerminatorKind::Call {
+                func: Operand::Copy(self.dummy_place.clone()),
+                args: [].into(),
+                destination: self.dummy_place.clone(),
+                target: Some(TEMP_BLOCK),
+                unwind: UnwindAction::Continue,
+                call_source: CallSource::Misc,
+                fn_span: DUMMY_SP,
+            },
+        )
     }
 
     fn goto(&mut self, some_from_block: Option<BasicBlock>) -> BasicBlock {
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 3d560bdf75c..9a6a153c7ba 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -90,10 +90,12 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
             let span = terminator.source_info.span;
 
             let foreign = fn_def_id.is_some();
-            tcx.emit_node_span_lint(FFI_UNWIND_CALLS, lint_root, span, errors::FfiUnwindCall {
+            tcx.emit_node_span_lint(
+                FFI_UNWIND_CALLS,
+                lint_root,
                 span,
-                foreign,
-            });
+                errors::FfiUnwindCall { span, foreign },
+            );
 
             tainted = true;
         }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index f8b0688dfdc..ab617e2ce6f 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -1111,10 +1111,13 @@ fn new_call_temp<'tcx>(
     });
 
     if let Some(block) = return_block {
-        caller_body[block].statements.insert(0, Statement {
-            source_info: callsite.source_info,
-            kind: StatementKind::StorageDead(local),
-        });
+        caller_body[block].statements.insert(
+            0,
+            Statement {
+                source_info: callsite.source_info,
+                kind: StatementKind::StorageDead(local),
+            },
+        );
     }
 
     local
@@ -1254,6 +1257,8 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
         // replaced down below anyways).
         if !matches!(terminator.kind, TerminatorKind::Return) {
             self.super_terminator(terminator, loc);
+        } else {
+            self.visit_source_info(&mut terminator.source_info);
         }
 
         match terminator.kind {
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index e43254ba089..59de6ca84a7 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -296,11 +296,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         let source_info = self.body.source_info(location);
         if let Some(lint_root) = self.lint_root(*source_info) {
             let span = source_info.span;
-            self.tcx.emit_node_span_lint(lint_kind.lint(), lint_root, span, AssertLint {
+            self.tcx.emit_node_span_lint(
+                lint_kind.lint(),
+                lint_root,
                 span,
-                assert_kind,
-                lint_kind,
-            });
+                AssertLint { span, assert_kind, lint_kind },
+            );
         }
     }
 
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 4dbbcae1756..c8d8dc147e9 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -920,19 +920,23 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
             self.extra_statements.push((loc, promoted_ref_statement));
 
             (
-                Rvalue::Ref(tcx.lifetimes.re_erased, *borrow_kind, Place {
-                    local: mem::replace(&mut place.local, promoted_ref),
-                    projection: List::empty(),
-                }),
+                Rvalue::Ref(
+                    tcx.lifetimes.re_erased,
+                    *borrow_kind,
+                    Place {
+                        local: mem::replace(&mut place.local, promoted_ref),
+                        projection: List::empty(),
+                    },
+                ),
                 promoted_operand,
             )
         };
 
         assert_eq!(self.new_block(), START_BLOCK);
-        self.visit_rvalue(&mut rvalue, Location {
-            block: START_BLOCK,
-            statement_index: usize::MAX,
-        });
+        self.visit_rvalue(
+            &mut rvalue,
+            Location { block: START_BLOCK, statement_index: usize::MAX },
+        );
 
         let span = self.promoted.span;
         self.assign(RETURN_PLACE, rvalue, span);
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 1d53440cf0b..94b1b4b1855 100644
--- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
+++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
@@ -447,17 +447,19 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
     }
 
     fn combine_sync_surface(&mut self) -> Ty<'tcx> {
-        self.apply_combinator(1, LangItem::AsyncDropSurfaceDropInPlace, &[self
-            .self_ty
-            .unwrap()
-            .into()])
+        self.apply_combinator(
+            1,
+            LangItem::AsyncDropSurfaceDropInPlace,
+            &[self.self_ty.unwrap().into()],
+        )
     }
 
     fn combine_deferred_drop_in_place(&mut self) -> Ty<'tcx> {
-        self.apply_combinator(1, LangItem::AsyncDropDeferredDropInPlace, &[self
-            .self_ty
-            .unwrap()
-            .into()])
+        self.apply_combinator(
+            1,
+            LangItem::AsyncDropDeferredDropInPlace,
+            &[self.self_ty.unwrap().into()],
+        )
     }
 
     fn combine_fuse(&mut self, inner_future_ty: Ty<'tcx>) -> Ty<'tcx> {
@@ -477,11 +479,11 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
     }
 
     fn combine_either(&mut self, other: Ty<'tcx>, matched: Ty<'tcx>) -> Ty<'tcx> {
-        self.apply_combinator(4, LangItem::AsyncDropEither, &[
-            other.into(),
-            matched.into(),
-            self.self_ty.unwrap().into(),
-        ])
+        self.apply_combinator(
+            4,
+            LangItem::AsyncDropEither,
+            &[other.into(), matched.into(), self.self_ty.unwrap().into()],
+        )
     }
 
     fn return_(mut self) -> Body<'tcx> {
diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
index c0f25c7ecfe..21bc51ecca1 100644
--- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
@@ -113,10 +113,13 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
                 // if we have StorageDeads to remove then make sure to insert them at the top of
                 // each target
                 for bb_idx in new_targets.all_targets() {
-                    storage_deads_to_insert.push((*bb_idx, Statement {
-                        source_info: terminator.source_info,
-                        kind: StatementKind::StorageDead(opt.to_switch_on.local),
-                    }));
+                    storage_deads_to_insert.push((
+                        *bb_idx,
+                        Statement {
+                            source_info: terminator.source_info,
+                            kind: StatementKind::StorageDead(opt.to_switch_on.local),
+                        },
+                    ));
                 }
             }
 
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index a24b3b2e80f..9f769077e77 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -159,10 +159,11 @@ impl SsaLocals {
     ) {
         for &local in &self.assignment_order {
             match self.assignments[local] {
-                Set1::One(DefLocation::Argument) => f(local, AssignedValue::Arg, Location {
-                    block: START_BLOCK,
-                    statement_index: 0,
-                }),
+                Set1::One(DefLocation::Argument) => f(
+                    local,
+                    AssignedValue::Arg,
+                    Location { block: START_BLOCK, statement_index: 0 },
+                ),
                 Set1::One(DefLocation::Assignment(loc)) => {
                     let bb = &mut basic_blocks[loc.block];
                     // `loc` must point to a direct assignment to `local`.
diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
index 30e634d8252..a0be7f11d70 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
@@ -1,5 +1,6 @@
 //! This module ensures that if a function's ABI requires a particular target feature,
 //! that target feature is enabled both on the callee and all callers.
+use rustc_abi::{BackendRepr, RegKind};
 use rustc_hir::CRATE_HIR_ID;
 use rustc_middle::mir::{self, traversal};
 use rustc_middle::ty::inherent::*;
@@ -7,8 +8,7 @@ use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt};
 use rustc_session::lint::builtin::ABI_UNSUPPORTED_VECTOR_TYPES;
 use rustc_span::def_id::DefId;
 use rustc_span::{DUMMY_SP, Span, Symbol};
-use rustc_target::abi::call::{FnAbi, PassMode};
-use rustc_target::abi::{BackendRepr, RegKind};
+use rustc_target::callconv::{FnAbi, PassMode};
 
 use crate::errors::{
     AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef,
diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
index 02b9397f9a9..838bfdab1ea 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
@@ -162,11 +162,12 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
             // but correct span? This would make the lint at least accept crate-level lint attributes.
             return;
         };
-        self.tcx.emit_node_span_lint(LARGE_ASSIGNMENTS, lint_root, span, LargeAssignmentsLint {
+        self.tcx.emit_node_span_lint(
+            LARGE_ASSIGNMENTS,
+            lint_root,
             span,
-            size: too_large_size.bytes(),
-            limit: limit as u64,
-        });
+            LargeAssignmentsLint { span, size: too_large_size.bytes(), limit: limit as u64 },
+        );
         self.move_size_spans.push(span);
     }
 }
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 3ef061195da..d826d03918e 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -268,12 +268,8 @@ where
         }
         let size_estimate = mono_item.size_estimate(cx.tcx);
 
-        cgu.items_mut().insert(mono_item, MonoItemData {
-            inlined: false,
-            linkage,
-            visibility,
-            size_estimate,
-        });
+        cgu.items_mut()
+            .insert(mono_item, MonoItemData { inlined: false, linkage, visibility, size_estimate });
 
         // Get all inlined items that are reachable from `mono_item` without
         // going via another root item. This includes drop-glue, functions from
@@ -1238,9 +1234,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
                         Linkage::LinkOnceODR => "OnceODR",
                         Linkage::WeakAny => "WeakAny",
                         Linkage::WeakODR => "WeakODR",
-                        Linkage::Appending => "Appending",
                         Linkage::Internal => "Internal",
-                        Linkage::Private => "Private",
                         Linkage::ExternalWeak => "ExternalWeak",
                         Linkage::Common => "Common",
                     };
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index 3c5d9b95e77..082c356cc5f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -514,10 +514,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
                 // will project to the right upvars for the generator, appending the inputs and
                 // coroutine upvars respecting the closure kind.
                 nested.push(
-                    ty::TraitRef::new(cx, async_fn_kind_trait_def_id, [
-                        kind_ty,
-                        Ty::from_closure_kind(cx, goal_kind),
-                    ])
+                    ty::TraitRef::new(
+                        cx,
+                        async_fn_kind_trait_def_id,
+                        [kind_ty, Ty::from_closure_kind(cx, goal_kind)],
+                    )
                     .upcast(cx),
                 );
             }
@@ -624,14 +625,18 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
     sig: ty::CoroutineClosureSignature<I>,
 ) -> I::Ty {
     let upvars_projection_def_id = cx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars);
-    let tupled_upvars_ty = Ty::new_projection(cx, upvars_projection_def_id, [
-        I::GenericArg::from(args.kind_ty()),
-        Ty::from_closure_kind(cx, goal_kind).into(),
-        goal_region.into(),
-        sig.tupled_inputs_ty.into(),
-        args.tupled_upvars_ty().into(),
-        args.coroutine_captures_by_ref_ty().into(),
-    ]);
+    let tupled_upvars_ty = Ty::new_projection(
+        cx,
+        upvars_projection_def_id,
+        [
+            I::GenericArg::from(args.kind_ty()),
+            Ty::from_closure_kind(cx, goal_kind).into(),
+            goal_region.into(),
+            sig.tupled_inputs_ty.into(),
+            args.tupled_upvars_ty().into(),
+            args.coroutine_captures_by_ref_ty().into(),
+        ],
+    );
     sig.to_coroutine(
         cx,
         args.parent_args(),
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 7669a305d58..fb53e778e60 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -248,10 +248,11 @@ where
 
         let pred = inputs_and_output
             .map_bound(|(inputs, _)| {
-                ty::TraitRef::new(cx, goal.predicate.def_id(), [
-                    goal.predicate.self_ty(),
-                    Ty::new_tup(cx, inputs.as_slice()),
-                ])
+                ty::TraitRef::new(
+                    cx,
+                    goal.predicate.def_id(),
+                    [goal.predicate.self_ty(), Ty::new_tup(cx, inputs.as_slice())],
+                )
             })
             .to_host_effect_clause(cx, goal.predicate.constness);
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index 0bfd72c6848..2491f09a0e2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -60,13 +60,16 @@ where
             (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate));
 
         let mut orig_values = Default::default();
-        let canonical =
-            Canonicalizer::canonicalize_input(self.delegate, &mut orig_values, QueryInput {
+        let canonical = Canonicalizer::canonicalize_input(
+            self.delegate,
+            &mut orig_values,
+            QueryInput {
                 goal,
                 predefined_opaques_in_body: self
                     .cx()
                     .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
-            });
+            },
+        );
         let query_input = ty::CanonicalQueryInput { canonical, typing_mode: self.typing_mode() };
         (orig_values, query_input)
     }
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 48a05488148..b0a34b9ce75 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -548,10 +548,10 @@ where
             // Replace the goal with an unconstrained infer var, so the
             // RHS does not affect projection candidate assembly.
             let unconstrained_rhs = self.next_term_infer_of_kind(goal.predicate.term);
-            let unconstrained_goal = goal.with(cx, ty::NormalizesTo {
-                alias: goal.predicate.alias,
-                term: unconstrained_rhs,
-            });
+            let unconstrained_goal = goal.with(
+                cx,
+                ty::NormalizesTo { alias: goal.predicate.alias, term: unconstrained_rhs },
+            );
 
             let (NestedNormalizationGoals(nested_goals), _, certainty) = self.evaluate_goal_raw(
                 GoalEvaluationKind::Nested,
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 76cbe5758b2..c8ea0b119ff 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -398,10 +398,11 @@ where
 
         let pred = tupled_inputs_and_output
             .map_bound(|(inputs, output)| ty::ProjectionPredicate {
-                projection_term: ty::AliasTerm::new(cx, goal.predicate.def_id(), [
-                    goal.predicate.self_ty(),
-                    inputs,
-                ]),
+                projection_term: ty::AliasTerm::new(
+                    cx,
+                    goal.predicate.def_id(),
+                    [goal.predicate.self_ty(), inputs],
+                ),
                 term: output.into(),
             })
             .upcast(cx);
@@ -454,21 +455,26 @@ where
                         .is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CallOnceFuture)
                     {
                         (
-                            ty::AliasTerm::new(cx, goal.predicate.def_id(), [
-                                goal.predicate.self_ty(),
-                                tupled_inputs_ty,
-                            ]),
+                            ty::AliasTerm::new(
+                                cx,
+                                goal.predicate.def_id(),
+                                [goal.predicate.self_ty(), tupled_inputs_ty],
+                            ),
                             output_coroutine_ty.into(),
                         )
                     } else if cx
                         .is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CallRefFuture)
                     {
                         (
-                            ty::AliasTerm::new(cx, goal.predicate.def_id(), [
-                                I::GenericArg::from(goal.predicate.self_ty()),
-                                tupled_inputs_ty.into(),
-                                env_region.into(),
-                            ]),
+                            ty::AliasTerm::new(
+                                cx,
+                                goal.predicate.def_id(),
+                                [
+                                    I::GenericArg::from(goal.predicate.self_ty()),
+                                    tupled_inputs_ty.into(),
+                                    env_region.into(),
+                                ],
+                            ),
                             output_coroutine_ty.into(),
                         )
                     } else if cx.is_lang_item(
@@ -476,10 +482,14 @@ where
                         TraitSolverLangItem::AsyncFnOnceOutput,
                     ) {
                         (
-                            ty::AliasTerm::new(cx, goal.predicate.def_id(), [
-                                I::GenericArg::from(goal.predicate.self_ty()),
-                                tupled_inputs_ty.into(),
-                            ]),
+                            ty::AliasTerm::new(
+                                cx,
+                                goal.predicate.def_id(),
+                                [
+                                    I::GenericArg::from(goal.predicate.self_ty()),
+                                    tupled_inputs_ty.into(),
+                                ],
+                            ),
                             coroutine_return_ty.into(),
                         )
                     } else {
@@ -603,10 +613,11 @@ where
                     // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
                     // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
                     // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
-                    let sized_predicate =
-                        ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [
-                            I::GenericArg::from(goal.predicate.self_ty()),
-                        ]);
+                    let sized_predicate = ty::TraitRef::new(
+                        cx,
+                        cx.require_lang_item(TraitSolverLangItem::Sized),
+                        [I::GenericArg::from(goal.predicate.self_ty())],
+                    );
                     // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
                     ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate));
                     Ty::new_unit(cx)
@@ -782,10 +793,11 @@ where
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::ProjectionPredicate {
-                projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.def_id(), [
-                    self_ty,
-                    coroutine.resume_ty(),
-                ]),
+                projection_term: ty::AliasTerm::new(
+                    ecx.cx(),
+                    goal.predicate.def_id(),
+                    [self_ty, coroutine.resume_ty()],
+                ),
                 term,
             }
             .upcast(cx),
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 513fc9355c8..46fae5c6fa4 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -342,18 +342,21 @@ where
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
         let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
             |AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
-                ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [
-                    output_coroutine_ty,
-                ])
+                ty::TraitRef::new(
+                    cx,
+                    cx.require_lang_item(TraitSolverLangItem::Sized),
+                    [output_coroutine_ty],
+                )
             },
         );
 
         let pred = tupled_inputs_and_output_and_coroutine
             .map_bound(|AsyncCallableRelevantTypes { tupled_inputs_ty, .. }| {
-                ty::TraitRef::new(cx, goal.predicate.def_id(), [
-                    goal.predicate.self_ty(),
-                    tupled_inputs_ty,
-                ])
+                ty::TraitRef::new(
+                    cx,
+                    goal.predicate.def_id(),
+                    [goal.predicate.self_ty(), tupled_inputs_ty],
+                )
             })
             .upcast(cx);
         Self::probe_and_consider_implied_clause(
@@ -975,9 +978,11 @@ where
             GoalSource::ImplWhereBound,
             goal.with(
                 cx,
-                ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Unsize), [
-                    a_tail_ty, b_tail_ty,
-                ]),
+                ty::TraitRef::new(
+                    cx,
+                    cx.require_lang_item(TraitSolverLangItem::Unsize),
+                    [a_tail_ty, b_tail_ty],
+                ),
             ),
         );
         self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
@@ -1015,9 +1020,11 @@ where
             GoalSource::ImplWhereBound,
             goal.with(
                 cx,
-                ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Unsize), [
-                    a_last_ty, b_last_ty,
-                ]),
+                ty::TraitRef::new(
+                    cx,
+                    cx.require_lang_item(TraitSolverLangItem::Unsize),
+                    [a_last_ty, b_last_ty],
+                ),
             ),
         );
         self.probe_builtin_trait_candidate(BuiltinImplSource::TupleUnsizing)
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 2373ab67d42..8f0e29c2769 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1121,23 +1121,29 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier {
         let token_descr = TokenDescription::from_token(&self.token);
 
         let mut add_token = true;
-        let mut diag = Diag::new(dcx, level, match token_descr {
-            Some(TokenDescription::ReservedIdentifier) => {
-                fluent::parse_expected_identifier_found_reserved_identifier_str
-            }
-            Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str,
-            Some(TokenDescription::ReservedKeyword) => {
-                fluent::parse_expected_identifier_found_reserved_keyword_str
-            }
-            Some(TokenDescription::DocComment) => {
-                fluent::parse_expected_identifier_found_doc_comment_str
-            }
-            Some(TokenDescription::MetaVar(_)) => {
-                add_token = false;
-                fluent::parse_expected_identifier_found_metavar_str
-            }
-            None => fluent::parse_expected_identifier_found_str,
-        });
+        let mut diag = Diag::new(
+            dcx,
+            level,
+            match token_descr {
+                Some(TokenDescription::ReservedIdentifier) => {
+                    fluent::parse_expected_identifier_found_reserved_identifier_str
+                }
+                Some(TokenDescription::Keyword) => {
+                    fluent::parse_expected_identifier_found_keyword_str
+                }
+                Some(TokenDescription::ReservedKeyword) => {
+                    fluent::parse_expected_identifier_found_reserved_keyword_str
+                }
+                Some(TokenDescription::DocComment) => {
+                    fluent::parse_expected_identifier_found_doc_comment_str
+                }
+                Some(TokenDescription::MetaVar(_)) => {
+                    add_token = false;
+                    fluent::parse_expected_identifier_found_metavar_str
+                }
+                None => fluent::parse_expected_identifier_found_str,
+            },
+        );
         diag.span(self.span);
         if add_token {
             diag.arg("token", self.token);
@@ -1182,21 +1188,27 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi {
         let token_descr = TokenDescription::from_token(&self.token);
 
         let mut add_token = true;
-        let mut diag = Diag::new(dcx, level, match token_descr {
-            Some(TokenDescription::ReservedIdentifier) => {
-                fluent::parse_expected_semi_found_reserved_identifier_str
-            }
-            Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
-            Some(TokenDescription::ReservedKeyword) => {
-                fluent::parse_expected_semi_found_reserved_keyword_str
-            }
-            Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
-            Some(TokenDescription::MetaVar(_)) => {
-                add_token = false;
-                fluent::parse_expected_semi_found_metavar_str
-            }
-            None => fluent::parse_expected_semi_found_str,
-        });
+        let mut diag = Diag::new(
+            dcx,
+            level,
+            match token_descr {
+                Some(TokenDescription::ReservedIdentifier) => {
+                    fluent::parse_expected_semi_found_reserved_identifier_str
+                }
+                Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
+                Some(TokenDescription::ReservedKeyword) => {
+                    fluent::parse_expected_semi_found_reserved_keyword_str
+                }
+                Some(TokenDescription::DocComment) => {
+                    fluent::parse_expected_semi_found_doc_comment_str
+                }
+                Some(TokenDescription::MetaVar(_)) => {
+                    add_token = false;
+                    fluent::parse_expected_semi_found_metavar_str
+                }
+                None => fluent::parse_expected_semi_found_str,
+            },
+        );
         diag.span(self.span);
         if add_token {
             diag.arg("token", self.token);
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 434f71beac2..cff998fa137 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -502,10 +502,10 @@ fn make_attr_token_stream(
     for flat_token in iter {
         match flat_token {
             FlatToken::Token((Token { kind: TokenKind::OpenDelim(delim), span }, spacing)) => {
-                stack_rest.push(mem::replace(&mut stack_top, FrameData {
-                    open_delim_sp: Some((delim, span, spacing)),
-                    inner: vec![],
-                }));
+                stack_rest.push(mem::replace(
+                    &mut stack_top,
+                    FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] },
+                ));
             }
             FlatToken::Token((Token { kind: TokenKind::CloseDelim(delim), span }, spacing)) => {
                 let frame_data = mem::replace(&mut stack_top, stack_rest.pop().unwrap());
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 47bf80a0783..72aebb5d121 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -684,12 +684,15 @@ impl<'a> Parser<'a> {
             let span = self.token.span.with_lo(pos).with_hi(pos);
             err.span_suggestion_verbose(
                 span,
-                format!("add a space before {} to write a regular comment", match (kind, style) {
-                    (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`",
-                    (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`",
-                    (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`",
-                    (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`",
-                },),
+                format!(
+                    "add a space before {} to write a regular comment",
+                    match (kind, style) {
+                        (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`",
+                        (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`",
+                        (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`",
+                        (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`",
+                    },
+                ),
                 " ".to_string(),
                 Applicability::MachineApplicable,
             );
@@ -1894,13 +1897,14 @@ impl<'a> Parser<'a> {
             (token::Eof, None) => (self.prev_token.span, self.token.span),
             _ => (self.prev_token.span.shrink_to_hi(), self.token.span),
         };
-        let msg = format!("expected `{}`, found {}", token_str, match (
-            &self.token.kind,
-            self.subparser_name
-        ) {
-            (token::Eof, Some(origin)) => format!("end of {origin}"),
-            _ => this_token_str,
-        },);
+        let msg = format!(
+            "expected `{}`, found {}",
+            token_str,
+            match (&self.token.kind, self.subparser_name) {
+                (token::Eof, Some(origin)) => format!("end of {origin}"),
+                _ => this_token_str,
+            },
+        );
         let mut err = self.dcx().struct_span_err(sp, msg);
         let label_exp = format!("expected `{token_str}`");
         let sm = self.psess.source_map();
@@ -2826,25 +2830,27 @@ impl<'a> Parser<'a> {
                             PatKind::Ident(BindingMode::NONE, ident, None) => {
                                 match &first_pat.kind {
                                     PatKind::Ident(_, old_ident, _) => {
-                                        let path = PatKind::Path(None, Path {
-                                            span: new_span,
-                                            segments: thin_vec![
-                                                PathSegment::from_ident(*old_ident),
-                                                PathSegment::from_ident(*ident),
-                                            ],
-                                            tokens: None,
-                                        });
+                                        let path = PatKind::Path(
+                                            None,
+                                            Path {
+                                                span: new_span,
+                                                segments: thin_vec![
+                                                    PathSegment::from_ident(*old_ident),
+                                                    PathSegment::from_ident(*ident),
+                                                ],
+                                                tokens: None,
+                                            },
+                                        );
                                         first_pat = self.mk_pat(new_span, path);
                                         show_sugg = true;
                                     }
                                     PatKind::Path(old_qself, old_path) => {
                                         let mut segments = old_path.segments.clone();
                                         segments.push(PathSegment::from_ident(*ident));
-                                        let path = PatKind::Path(old_qself.clone(), Path {
-                                            span: new_span,
-                                            segments,
-                                            tokens: None,
-                                        });
+                                        let path = PatKind::Path(
+                                            old_qself.clone(),
+                                            Path { span: new_span, segments, tokens: None },
+                                        );
                                         first_pat = self.mk_pat(new_span, path);
                                         show_sugg = true;
                                     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ffd46f20767..e0e6c2177da 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -807,17 +807,20 @@ impl<'a> Parser<'a> {
         // Check if an illegal postfix operator has been added after the cast.
         // If the resulting expression is not a cast, it is an illegal postfix operator.
         if !matches!(with_postfix.kind, ExprKind::Cast(_, _)) {
-            let msg = format!("cast cannot be followed by {}", match with_postfix.kind {
-                ExprKind::Index(..) => "indexing",
-                ExprKind::Try(_) => "`?`",
-                ExprKind::Field(_, _) => "a field access",
-                ExprKind::MethodCall(_) => "a method call",
-                ExprKind::Call(_, _) => "a function call",
-                ExprKind::Await(_, _) => "`.await`",
-                ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match",
-                ExprKind::Err(_) => return Ok(with_postfix),
-                _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
-            });
+            let msg = format!(
+                "cast cannot be followed by {}",
+                match with_postfix.kind {
+                    ExprKind::Index(..) => "indexing",
+                    ExprKind::Try(_) => "`?`",
+                    ExprKind::Field(_, _) => "a field access",
+                    ExprKind::MethodCall(_) => "a method call",
+                    ExprKind::Call(_, _) => "a function call",
+                    ExprKind::Await(_, _) => "`.await`",
+                    ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match",
+                    ExprKind::Err(_) => return Ok(with_postfix),
+                    _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
+                }
+            );
             let mut err = self.dcx().struct_span_err(span, msg);
 
             let suggest_parens = |err: &mut Diag<'_>| {
@@ -2862,13 +2865,10 @@ impl<'a> Parser<'a> {
                 .emit_err(errors::MissingExpressionInForLoop { span: expr.span.shrink_to_lo() });
             let err_expr = self.mk_expr(expr.span, ExprKind::Err(guar));
             let block = self.mk_block(thin_vec![], BlockCheckMode::Default, self.prev_token.span);
-            return Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::ForLoop {
-                pat,
-                iter: err_expr,
-                body: block,
-                label: opt_label,
-                kind,
-            }));
+            return Ok(self.mk_expr(
+                lo.to(self.prev_token.span),
+                ExprKind::ForLoop { pat, iter: err_expr, body: block, label: opt_label, kind },
+            ));
         }
 
         let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index dbdc31f06a2..637ed2774a2 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1954,10 +1954,10 @@ impl<'a> Parser<'a> {
                 // Try to recover extra trailing angle brackets
                 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind {
                     if let Some(last_segment) = segments.last() {
-                        let guar = self.check_trailing_angle_brackets(last_segment, &[
-                            exp!(Comma),
-                            exp!(CloseBrace),
-                        ]);
+                        let guar = self.check_trailing_angle_brackets(
+                            last_segment,
+                            &[exp!(Comma), exp!(CloseBrace)],
+                        );
                         if let Some(_guar) = guar {
                             // Handle a case like `Vec<u8>>,` where we can continue parsing fields
                             // after the comma
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 39737b9e137..576711e6677 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -106,11 +106,10 @@ impl<'a> Parser<'a> {
             self.parse_path_segments(&mut path.segments, style, None)?;
         }
 
-        Ok((qself, Path {
-            segments: path.segments,
-            span: lo.to(self.prev_token.span),
-            tokens: None,
-        }))
+        Ok((
+            qself,
+            Path { segments: path.segments, span: lo.to(self.prev_token.span), tokens: None },
+        ))
     }
 
     /// Recover from an invalid single colon, when the user likely meant a qualified path.
@@ -485,13 +484,16 @@ impl<'a> Parser<'a> {
 
         error.span_suggestion_verbose(
             prev_token_before_parsing.span,
-            format!("consider removing the `::` here to {}", match style {
-                PathStyle::Expr => "call the expression",
-                PathStyle::Pat => "turn this into a tuple struct pattern",
-                _ => {
-                    return;
+            format!(
+                "consider removing the `::` here to {}",
+                match style {
+                    PathStyle::Expr => "call the expression",
+                    PathStyle::Pat => "turn this into a tuple struct pattern",
+                    _ => {
+                        return;
+                    }
                 }
-            }),
+            ),
             "",
             Applicability::MaybeIncorrect,
         );
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 1ddb5fc0a11..a2699b077fc 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -417,14 +417,20 @@ impl<'a> Parser<'a> {
     fn check_let_else_init_trailing_brace(&self, init: &ast::Expr) {
         if let Some(trailing) = classify::expr_trailing_brace(init) {
             let (span, sugg) = match trailing {
-                TrailingBrace::MacCall(mac) => (mac.span(), errors::WrapInParentheses::MacroArgs {
-                    left: mac.args.dspan.open,
-                    right: mac.args.dspan.close,
-                }),
-                TrailingBrace::Expr(expr) => (expr.span, errors::WrapInParentheses::Expression {
-                    left: expr.span.shrink_to_lo(),
-                    right: expr.span.shrink_to_hi(),
-                }),
+                TrailingBrace::MacCall(mac) => (
+                    mac.span(),
+                    errors::WrapInParentheses::MacroArgs {
+                        left: mac.args.dspan.open,
+                        right: mac.args.dspan.close,
+                    },
+                ),
+                TrailingBrace::Expr(expr) => (
+                    expr.span,
+                    errors::WrapInParentheses::Expression {
+                        left: expr.span.shrink_to_lo(),
+                        right: expr.span.shrink_to_hi(),
+                    },
+                ),
             };
             self.dcx().emit_err(errors::InvalidCurlyInLetElse {
                 span: span.with_lo(span.hi() - BytePos(1)),
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index d021ea107ed..3b985621b57 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -863,28 +863,34 @@ impl<'a> Parser<'a> {
         if let (Some(pos), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
             let word = self.word();
             let pos = self.to_span_index(pos);
-            self.errors.insert(0, ParseError {
-                description: "expected format parameter to occur after `:`".to_owned(),
-                note: Some(format!("`?` comes after `:`, try `{}:{}` instead", word, "?")),
-                label: "expected `?` to occur after `:`".to_owned(),
-                span: pos.to(pos),
-                secondary_label: None,
-                suggestion: Suggestion::None,
-            });
+            self.errors.insert(
+                0,
+                ParseError {
+                    description: "expected format parameter to occur after `:`".to_owned(),
+                    note: Some(format!("`?` comes after `:`, try `{}:{}` instead", word, "?")),
+                    label: "expected `?` to occur after `:`".to_owned(),
+                    span: pos.to(pos),
+                    secondary_label: None,
+                    suggestion: Suggestion::None,
+                },
+            );
         }
     }
 
     fn suggest_format_align(&mut self, alignment: char) {
         if let Some(pos) = self.consume_pos(alignment) {
             let pos = self.to_span_index(pos);
-            self.errors.insert(0, ParseError {
-                description: "expected format parameter to occur after `:`".to_owned(),
-                note: None,
-                label: format!("expected `{}` to occur after `:`", alignment),
-                span: pos.to(pos),
-                secondary_label: None,
-                suggestion: Suggestion::None,
-            });
+            self.errors.insert(
+                0,
+                ParseError {
+                    description: "expected format parameter to occur after `:`".to_owned(),
+                    note: None,
+                    label: format!("expected `{}` to occur after `:`", alignment),
+                    span: pos.to(pos),
+                    secondary_label: None,
+                    suggestion: Suggestion::None,
+                },
+            );
         }
     }
 
@@ -901,24 +907,36 @@ impl<'a> Parser<'a> {
             if let ArgumentNamed(_) = arg.position {
                 match field.position {
                     ArgumentNamed(_) => {
-                        self.errors.insert(0, ParseError {
-                            description: "field access isn't supported".to_string(),
-                            note: None,
-                            label: "not supported".to_string(),
-                            span: InnerSpan::new(arg.position_span.start, field.position_span.end),
-                            secondary_label: None,
-                            suggestion: Suggestion::UsePositional,
-                        });
+                        self.errors.insert(
+                            0,
+                            ParseError {
+                                description: "field access isn't supported".to_string(),
+                                note: None,
+                                label: "not supported".to_string(),
+                                span: InnerSpan::new(
+                                    arg.position_span.start,
+                                    field.position_span.end,
+                                ),
+                                secondary_label: None,
+                                suggestion: Suggestion::UsePositional,
+                            },
+                        );
                     }
                     ArgumentIs(_) => {
-                        self.errors.insert(0, ParseError {
-                            description: "tuple index access isn't supported".to_string(),
-                            note: None,
-                            label: "not supported".to_string(),
-                            span: InnerSpan::new(arg.position_span.start, field.position_span.end),
-                            secondary_label: None,
-                            suggestion: Suggestion::UsePositional,
-                        });
+                        self.errors.insert(
+                            0,
+                            ParseError {
+                                description: "tuple index access isn't supported".to_string(),
+                                note: None,
+                                label: "not supported".to_string(),
+                                span: InnerSpan::new(
+                                    arg.position_span.start,
+                                    field.position_span.end,
+                                ),
+                                secondary_label: None,
+                                suggestion: Suggestion::UsePositional,
+                            },
+                        );
                     }
                     _ => {}
                 };
@@ -940,14 +958,17 @@ impl<'a> Parser<'a> {
         let span = self.span(pos - 1, pos + 1);
         let pos = self.to_span_index(pos);
 
-        self.errors.insert(0, ParseError {
-            description: format!("expected `}}`, found `{c}`"),
-            note: None,
-            label: "expected `'}'`".into(),
-            span: pos.to(pos),
-            secondary_label: None,
-            suggestion: Suggestion::ReorderFormatParameter(span, format!("{replacement}")),
-        })
+        self.errors.insert(
+            0,
+            ParseError {
+                description: format!("expected `}}`, found `{c}`"),
+                note: None,
+                label: "expected `'}'`".into(),
+                span: pos.to(pos),
+                secondary_label: None,
+                suggestion: Suggestion::ReorderFormatParameter(span, format!("{replacement}")),
+            },
+        )
     }
 }
 
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index fbb217b16fc..cc8a0069c4e 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -80,307 +80,311 @@ fn invalid_precision() {
 
 #[test]
 fn format_nothing() {
-    same("{}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: fmtdflt(),
-    }))]);
+    same(
+        "{}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: fmtdflt(),
+        }))],
+    );
 }
 #[test]
 fn format_position() {
-    same("{3}", &[NextArgument(Box::new(Argument {
-        position: ArgumentIs(3),
-        position_span: InnerSpan { start: 2, end: 3 },
-        format: fmtdflt(),
-    }))]);
+    same(
+        "{3}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: fmtdflt(),
+        }))],
+    );
 }
 #[test]
 fn format_position_nothing_else() {
-    same("{3:}", &[NextArgument(Box::new(Argument {
-        position: ArgumentIs(3),
-        position_span: InnerSpan { start: 2, end: 3 },
-        format: fmtdflt(),
-    }))]);
+    same(
+        "{3:}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: fmtdflt(),
+        }))],
+    );
 }
 #[test]
 fn format_named() {
-    same("{name}", &[NextArgument(Box::new(Argument {
-        position: ArgumentNamed("name"),
-        position_span: InnerSpan { start: 2, end: 6 },
-        format: fmtdflt(),
-    }))])
+    same(
+        "{name}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentNamed("name"),
+            position_span: InnerSpan { start: 2, end: 6 },
+            format: fmtdflt(),
+        }))],
+    )
 }
 #[test]
 fn format_type() {
-    same("{3:x}", &[NextArgument(Box::new(Argument {
-        position: ArgumentIs(3),
-        position_span: InnerSpan { start: 2, end: 3 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountImplied,
-            width: CountImplied,
-            precision_span: None,
-            width_span: None,
-            ty: "x",
-            ty_span: None,
-        },
-    }))]);
+    same(
+        "{3:x}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountImplied,
+                width: CountImplied,
+                precision_span: None,
+                width_span: None,
+                ty: "x",
+                ty_span: None,
+            },
+        }))],
+    );
 }
 #[test]
 fn format_align_fill() {
-    same("{3:>}", &[NextArgument(Box::new(Argument {
-        position: ArgumentIs(3),
-        position_span: InnerSpan { start: 2, end: 3 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignRight,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountImplied,
-            width: CountImplied,
-            precision_span: None,
-            width_span: None,
-            ty: "",
-            ty_span: None,
-        },
-    }))]);
-    same("{3:0<}", &[NextArgument(Box::new(Argument {
-        position: ArgumentIs(3),
-        position_span: InnerSpan { start: 2, end: 3 },
-        format: FormatSpec {
-            fill: Some('0'),
-            fill_span: Some(InnerSpan::new(4, 5)),
-            align: AlignLeft,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountImplied,
-            width: CountImplied,
-            precision_span: None,
-            width_span: None,
-            ty: "",
-            ty_span: None,
-        },
-    }))]);
-    same("{3:*<abcd}", &[NextArgument(Box::new(Argument {
-        position: ArgumentIs(3),
-        position_span: InnerSpan { start: 2, end: 3 },
-        format: FormatSpec {
-            fill: Some('*'),
-            fill_span: Some(InnerSpan::new(4, 5)),
-            align: AlignLeft,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountImplied,
-            width: CountImplied,
-            precision_span: None,
-            width_span: None,
-            ty: "abcd",
-            ty_span: Some(InnerSpan::new(6, 10)),
-        },
-    }))]);
+    same(
+        "{3:>}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignRight,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountImplied,
+                width: CountImplied,
+                precision_span: None,
+                width_span: None,
+                ty: "",
+                ty_span: None,
+            },
+        }))],
+    );
+    same(
+        "{3:0<}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: FormatSpec {
+                fill: Some('0'),
+                fill_span: Some(InnerSpan::new(4, 5)),
+                align: AlignLeft,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountImplied,
+                width: CountImplied,
+                precision_span: None,
+                width_span: None,
+                ty: "",
+                ty_span: None,
+            },
+        }))],
+    );
+    same(
+        "{3:*<abcd}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: FormatSpec {
+                fill: Some('*'),
+                fill_span: Some(InnerSpan::new(4, 5)),
+                align: AlignLeft,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountImplied,
+                width: CountImplied,
+                precision_span: None,
+                width_span: None,
+                ty: "abcd",
+                ty_span: Some(InnerSpan::new(6, 10)),
+            },
+        }))],
+    );
 }
 #[test]
 fn format_counts() {
-    same("{:10x}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountImplied,
-            precision_span: None,
-            width: CountIs(10),
-            width_span: Some(InnerSpan { start: 3, end: 5 }),
-            ty: "x",
-            ty_span: None,
-        },
-    }))]);
-    same("{:10$.10x}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountIs(10),
-            precision_span: Some(InnerSpan { start: 6, end: 9 }),
-            width: CountIsParam(10),
-            width_span: Some(InnerSpan { start: 3, end: 6 }),
-            ty: "x",
-            ty_span: None,
-        },
-    }))]);
-    same("{1:0$.10x}", &[NextArgument(Box::new(Argument {
-        position: ArgumentIs(1),
-        position_span: InnerSpan { start: 2, end: 3 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountIs(10),
-            precision_span: Some(InnerSpan { start: 6, end: 9 }),
-            width: CountIsParam(0),
-            width_span: Some(InnerSpan { start: 4, end: 6 }),
-            ty: "x",
-            ty_span: None,
-        },
-    }))]);
-    same("{:.*x}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(1),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountIsStar(0),
-            precision_span: Some(InnerSpan { start: 3, end: 5 }),
-            width: CountImplied,
-            width_span: None,
-            ty: "x",
-            ty_span: None,
-        },
-    }))]);
-    same("{:.10$x}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountIsParam(10),
-            width: CountImplied,
-            precision_span: Some(InnerSpan::new(3, 7)),
-            width_span: None,
-            ty: "x",
-            ty_span: None,
-        },
-    }))]);
-    same("{:a$.b$?}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountIsName("b", InnerSpan { start: 6, end: 7 }),
-            precision_span: Some(InnerSpan { start: 5, end: 8 }),
-            width: CountIsName("a", InnerSpan { start: 3, end: 4 }),
-            width_span: Some(InnerSpan { start: 3, end: 5 }),
-            ty: "?",
-            ty_span: None,
-        },
-    }))]);
-    same("{:.4}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: None,
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountIs(4),
-            precision_span: Some(InnerSpan { start: 3, end: 5 }),
-            width: CountImplied,
-            width_span: None,
-            ty: "",
-            ty_span: None,
-        },
-    }))])
+    same(
+        "{:10x}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountImplied,
+                precision_span: None,
+                width: CountIs(10),
+                width_span: Some(InnerSpan { start: 3, end: 5 }),
+                ty: "x",
+                ty_span: None,
+            },
+        }))],
+    );
+    same(
+        "{:10$.10x}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountIs(10),
+                precision_span: Some(InnerSpan { start: 6, end: 9 }),
+                width: CountIsParam(10),
+                width_span: Some(InnerSpan { start: 3, end: 6 }),
+                ty: "x",
+                ty_span: None,
+            },
+        }))],
+    );
+    same(
+        "{1:0$.10x}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentIs(1),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountIs(10),
+                precision_span: Some(InnerSpan { start: 6, end: 9 }),
+                width: CountIsParam(0),
+                width_span: Some(InnerSpan { start: 4, end: 6 }),
+                ty: "x",
+                ty_span: None,
+            },
+        }))],
+    );
+    same(
+        "{:.*x}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(1),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountIsStar(0),
+                precision_span: Some(InnerSpan { start: 3, end: 5 }),
+                width: CountImplied,
+                width_span: None,
+                ty: "x",
+                ty_span: None,
+            },
+        }))],
+    );
+    same(
+        "{:.10$x}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountIsParam(10),
+                width: CountImplied,
+                precision_span: Some(InnerSpan::new(3, 7)),
+                width_span: None,
+                ty: "x",
+                ty_span: None,
+            },
+        }))],
+    );
+    same(
+        "{:a$.b$?}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountIsName("b", InnerSpan { start: 6, end: 7 }),
+                precision_span: Some(InnerSpan { start: 5, end: 8 }),
+                width: CountIsName("a", InnerSpan { start: 3, end: 4 }),
+                width_span: Some(InnerSpan { start: 3, end: 5 }),
+                ty: "?",
+                ty_span: None,
+            },
+        }))],
+    );
+    same(
+        "{:.4}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: None,
+                alternate: false,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountIs(4),
+                precision_span: Some(InnerSpan { start: 3, end: 5 }),
+                width: CountImplied,
+                width_span: None,
+                ty: "",
+                ty_span: None,
+            },
+        }))],
+    )
 }
 #[test]
 fn format_flags() {
-    same("{:-}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: Some(Sign::Minus),
-            alternate: false,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountImplied,
-            width: CountImplied,
-            precision_span: None,
-            width_span: None,
-            ty: "",
-            ty_span: None,
-        },
-    }))]);
-    same("{:+#}", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 2 },
-        format: FormatSpec {
-            fill: None,
-            fill_span: None,
-            align: AlignUnknown,
-            sign: Some(Sign::Plus),
-            alternate: true,
-            zero_pad: false,
-            debug_hex: None,
-            precision: CountImplied,
-            width: CountImplied,
-            precision_span: None,
-            width_span: None,
-            ty: "",
-            ty_span: None,
-        },
-    }))]);
-}
-#[test]
-fn format_mixture() {
-    same("abcd {3:x} efg", &[
-        Lit("abcd "),
-        NextArgument(Box::new(Argument {
-            position: ArgumentIs(3),
-            position_span: InnerSpan { start: 7, end: 8 },
+    same(
+        "{:-}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
                 align: AlignUnknown,
-                sign: None,
+                sign: Some(Sign::Minus),
                 alternate: false,
                 zero_pad: false,
                 debug_hex: None,
@@ -388,23 +392,79 @@ fn format_mixture() {
                 width: CountImplied,
                 precision_span: None,
                 width_span: None,
-                ty: "x",
+                ty: "",
                 ty_span: None,
             },
-        })),
-        Lit(" efg"),
-    ]);
+        }))],
+    );
+    same(
+        "{:+#}",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: FormatSpec {
+                fill: None,
+                fill_span: None,
+                align: AlignUnknown,
+                sign: Some(Sign::Plus),
+                alternate: true,
+                zero_pad: false,
+                debug_hex: None,
+                precision: CountImplied,
+                width: CountImplied,
+                precision_span: None,
+                width_span: None,
+                ty: "",
+                ty_span: None,
+            },
+        }))],
+    );
+}
+#[test]
+fn format_mixture() {
+    same(
+        "abcd {3:x} efg",
+        &[
+            Lit("abcd "),
+            NextArgument(Box::new(Argument {
+                position: ArgumentIs(3),
+                position_span: InnerSpan { start: 7, end: 8 },
+                format: FormatSpec {
+                    fill: None,
+                    fill_span: None,
+                    align: AlignUnknown,
+                    sign: None,
+                    alternate: false,
+                    zero_pad: false,
+                    debug_hex: None,
+                    precision: CountImplied,
+                    width: CountImplied,
+                    precision_span: None,
+                    width_span: None,
+                    ty: "x",
+                    ty_span: None,
+                },
+            })),
+            Lit(" efg"),
+        ],
+    );
 }
 #[test]
 fn format_whitespace() {
-    same("{ }", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 3 },
-        format: fmtdflt(),
-    }))]);
-    same("{  }", &[NextArgument(Box::new(Argument {
-        position: ArgumentImplicitlyIs(0),
-        position_span: InnerSpan { start: 2, end: 4 },
-        format: fmtdflt(),
-    }))]);
+    same(
+        "{ }",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: fmtdflt(),
+        }))],
+    );
+    same(
+        "{  }",
+        &[NextArgument(Box::new(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 4 },
+            format: fmtdflt(),
+        }))],
+    );
 }
diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs
index 75a1bb39a74..4601bb87b76 100644
--- a/compiler/rustc_passes/src/abi_test.rs
+++ b/compiler/rustc_passes/src/abi_test.rs
@@ -6,7 +6,7 @@ use rustc_middle::ty::layout::{FnAbiError, LayoutError};
 use rustc_middle::ty::{self, GenericArgs, Instance, Ty, TyCtxt};
 use rustc_span::source_map::Spanned;
 use rustc_span::sym;
-use rustc_target::abi::call::FnAbi;
+use rustc_target::callconv::FnAbi;
 
 use super::layout_test::ensure_wf;
 use crate::errors::{AbiInvalidAttribute, AbiNe, AbiOf, UnrecognizedField};
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 4c683c82b6c..f578708b40c 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -7,6 +7,7 @@
 use std::cell::Cell;
 use std::collections::hash_map::Entry;
 
+use rustc_abi::{ExternAbi, Size};
 use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, MetaItemLit, ast};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey};
@@ -32,8 +33,6 @@ use rustc_session::lint::builtin::{
 };
 use rustc_session::parse::feature_err;
 use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, kw, sym};
-use rustc_target::abi::Size;
-use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
 use rustc_trait_selection::traits::ObligationCtxt;
@@ -345,8 +344,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     }
 
     fn inline_attr_str_error_without_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) {
-        self.tcx
-            .emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::IgnoredAttr { sym });
+        self.tcx.emit_node_span_lint(
+            UNUSED_ATTRIBUTES,
+            hir_id,
+            attr.span,
+            errors::IgnoredAttr { sym },
+        );
     }
 
     /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl.
@@ -1506,10 +1509,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             _ => {
                 // FIXME: #[cold] was previously allowed on non-functions and some crates used
                 // this, so only emit a warning.
-                self.tcx.emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::Cold {
-                    span,
-                    on_crate: hir_id == CRATE_HIR_ID,
-                });
+                self.tcx.emit_node_span_lint(
+                    UNUSED_ATTRIBUTES,
+                    hir_id,
+                    attr.span,
+                    errors::Cold { span, on_crate: hir_id == CRATE_HIR_ID },
+                );
             }
         }
     }
@@ -1519,14 +1524,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         if target == Target::ForeignMod
             && let hir::Node::Item(item) = self.tcx.hir_node(hir_id)
             && let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item
-            && !matches!(abi, Abi::Rust | Abi::RustIntrinsic)
+            && !matches!(abi, ExternAbi::Rust | ExternAbi::RustIntrinsic)
         {
             return;
         }
 
-        self.tcx.emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::Link {
-            span: (target != Target::ForeignMod).then_some(span),
-        });
+        self.tcx.emit_node_span_lint(
+            UNUSED_ATTRIBUTES,
+            hir_id,
+            attr.span,
+            errors::Link { span: (target != Target::ForeignMod).then_some(span) },
+        );
     }
 
     /// Checks if `#[link_name]` is applied to an item other than a foreign function or static.
@@ -2393,10 +2401,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             return;
         };
 
-        self.tcx.emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::Unused {
-            attr_span: attr.span,
-            note,
-        });
+        self.tcx.emit_node_span_lint(
+            UNUSED_ATTRIBUTES,
+            hir_id,
+            attr.span,
+            errors::Unused { attr_span: attr.span, note },
+        );
     }
 
     /// A best effort attempt to create an error for a mismatching proc macro signature.
@@ -2445,7 +2455,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             token_stream,
             false,
             Safety::Safe,
-            Abi::Rust,
+            ExternAbi::Rust,
         );
 
         if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 0aa50ad19ff..9bcdd238547 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1394,11 +1394,15 @@ pub(crate) struct DuplicateLangItem {
 impl<G: EmissionGuarantee> Diagnostic<'_, G> for DuplicateLangItem {
     #[track_caller]
     fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
-        let mut diag = Diag::new(dcx, level, match self.duplicate {
-            Duplicate::Plain => fluent::passes_duplicate_lang_item,
-            Duplicate::Crate => fluent::passes_duplicate_lang_item_crate,
-            Duplicate::CrateDepends => fluent::passes_duplicate_lang_item_crate_depends,
-        });
+        let mut diag = Diag::new(
+            dcx,
+            level,
+            match self.duplicate {
+                Duplicate::Plain => fluent::passes_duplicate_lang_item,
+                Duplicate::Crate => fluent::passes_duplicate_lang_item_crate,
+                Duplicate::CrateDepends => fluent::passes_duplicate_lang_item_crate_depends,
+            },
+        );
         diag.code(E0152);
         diag.arg("lang_item_name", self.lang_item_name);
         diag.arg("crate_name", self.crate_name);
diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs
index 6d9c70177a4..f7cae89852e 100644
--- a/compiler/rustc_passes/src/input_stats.rs
+++ b/compiler/rustc_passes/src/input_stats.rs
@@ -230,24 +230,27 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_item(&mut self, i: &'v hir::Item<'v>) {
-        record_variants!((self, i, i.kind, Some(i.hir_id()), hir, Item, ItemKind), [
-            ExternCrate,
-            Use,
-            Static,
-            Const,
-            Fn,
-            Macro,
-            Mod,
-            ForeignMod,
-            GlobalAsm,
-            TyAlias,
-            Enum,
-            Struct,
-            Union,
-            Trait,
-            TraitAlias,
-            Impl
-        ]);
+        record_variants!(
+            (self, i, i.kind, Some(i.hir_id()), hir, Item, ItemKind),
+            [
+                ExternCrate,
+                Use,
+                Static,
+                Const,
+                Fn,
+                Macro,
+                Mod,
+                ForeignMod,
+                GlobalAsm,
+                TyAlias,
+                Enum,
+                Struct,
+                Union,
+                Trait,
+                TraitAlias,
+                Impl
+            ]
+        );
         hir_visit::walk_item(self, i)
     }
 
@@ -262,9 +265,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_foreign_item(&mut self, i: &'v hir::ForeignItem<'v>) {
-        record_variants!((self, i, i.kind, Some(i.hir_id()), hir, ForeignItem, ForeignItemKind), [
-            Fn, Static, Type
-        ]);
+        record_variants!(
+            (self, i, i.kind, Some(i.hir_id()), hir, ForeignItem, ForeignItemKind),
+            [Fn, Static, Type]
+        );
         hir_visit::walk_foreign_item(self, i)
     }
 
@@ -279,9 +283,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) {
-        record_variants!((self, s, s.kind, Some(s.hir_id), hir, Stmt, StmtKind), [
-            Let, Item, Expr, Semi
-        ]);
+        record_variants!(
+            (self, s, s.kind, Some(s.hir_id), hir, Stmt, StmtKind),
+            [Let, Item, Expr, Semi]
+        );
         hir_visit::walk_stmt(self, s)
     }
 
@@ -291,23 +296,26 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_pat(&mut self, p: &'v hir::Pat<'v>) {
-        record_variants!((self, p, p.kind, Some(p.hir_id), hir, Pat, PatKind), [
-            Wild,
-            Binding,
-            Struct,
-            TupleStruct,
-            Or,
-            Never,
-            Tuple,
-            Box,
-            Deref,
-            Ref,
-            Expr,
-            Guard,
-            Range,
-            Slice,
-            Err
-        ]);
+        record_variants!(
+            (self, p, p.kind, Some(p.hir_id), hir, Pat, PatKind),
+            [
+                Wild,
+                Binding,
+                Struct,
+                TupleStruct,
+                Or,
+                Never,
+                Tuple,
+                Box,
+                Deref,
+                Ref,
+                Expr,
+                Guard,
+                Range,
+                Slice,
+                Err
+            ]
+        );
         hir_visit::walk_pat(self, p)
     }
 
@@ -317,42 +325,45 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_expr(&mut self, e: &'v hir::Expr<'v>) {
-        record_variants!((self, e, e.kind, Some(e.hir_id), hir, Expr, ExprKind), [
-            ConstBlock,
-            Array,
-            Call,
-            MethodCall,
-            Tup,
-            Binary,
-            Unary,
-            Lit,
-            Cast,
-            Type,
-            DropTemps,
-            Let,
-            If,
-            Loop,
-            Match,
-            Closure,
-            Block,
-            Assign,
-            AssignOp,
-            Field,
-            Index,
-            Path,
-            AddrOf,
-            Break,
-            Continue,
-            Ret,
-            Become,
-            InlineAsm,
-            OffsetOf,
-            Struct,
-            Repeat,
-            Yield,
-            UnsafeBinderCast,
-            Err
-        ]);
+        record_variants!(
+            (self, e, e.kind, Some(e.hir_id), hir, Expr, ExprKind),
+            [
+                ConstBlock,
+                Array,
+                Call,
+                MethodCall,
+                Tup,
+                Binary,
+                Unary,
+                Lit,
+                Cast,
+                Type,
+                DropTemps,
+                Let,
+                If,
+                Loop,
+                Match,
+                Closure,
+                Block,
+                Assign,
+                AssignOp,
+                Field,
+                Index,
+                Path,
+                AddrOf,
+                Break,
+                Continue,
+                Ret,
+                Become,
+                InlineAsm,
+                OffsetOf,
+                Struct,
+                Repeat,
+                Yield,
+                UnsafeBinderCast,
+                Err
+            ]
+        );
         hir_visit::walk_expr(self, e)
     }
 
@@ -362,25 +373,28 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_ty(&mut self, t: &'v hir::Ty<'v, AmbigArg>) {
-        record_variants!((self, t, t.kind, Some(t.hir_id), hir, Ty, TyKind), [
-            InferDelegation,
-            Slice,
-            Array,
-            Ptr,
-            Ref,
-            BareFn,
-            UnsafeBinder,
-            Never,
-            Tup,
-            Path,
-            OpaqueDef,
-            TraitAscription,
-            TraitObject,
-            Typeof,
-            Infer,
-            Pat,
-            Err
-        ]);
+        record_variants!(
+            (self, t, t.kind, Some(t.hir_id), hir, Ty, TyKind),
+            [
+                InferDelegation,
+                Slice,
+                Array,
+                Ptr,
+                Ref,
+                BareFn,
+                UnsafeBinder,
+                Never,
+                Tup,
+                Path,
+                OpaqueDef,
+                TraitAscription,
+                TraitObject,
+                Typeof,
+                Infer,
+                Pat,
+                Err
+            ]
+        );
         hir_visit::walk_ty(self, t)
     }
 
@@ -421,9 +435,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_trait_item(&mut self, ti: &'v hir::TraitItem<'v>) {
-        record_variants!((self, ti, ti.kind, Some(ti.hir_id()), hir, TraitItem, TraitItemKind), [
-            Const, Fn, Type
-        ]);
+        record_variants!(
+            (self, ti, ti.kind, Some(ti.hir_id()), hir, TraitItem, TraitItemKind),
+            [Const, Fn, Type]
+        );
         hir_visit::walk_trait_item(self, ti)
     }
 
@@ -433,9 +448,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_impl_item(&mut self, ii: &'v hir::ImplItem<'v>) {
-        record_variants!((self, ii, ii.kind, Some(ii.hir_id()), hir, ImplItem, ImplItemKind), [
-            Const, Fn, Type
-        ]);
+        record_variants!(
+            (self, ii, ii.kind, Some(ii.hir_id()), hir, ImplItem, ImplItemKind),
+            [Const, Fn, Type]
+        );
         hir_visit::walk_impl_item(self, ii)
     }
 
@@ -450,9 +466,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) {
-        record_variants!((self, b, b, None, hir, GenericBound, GenericBound), [
-            Trait, Outlives, Use
-        ]);
+        record_variants!(
+            (self, b, b, None, hir, GenericBound, GenericBound),
+            [Trait, Outlives, Use]
+        );
         hir_visit::walk_param_bound(self, b)
     }
 
@@ -467,9 +484,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_generic_arg(&mut self, ga: &'v hir::GenericArg<'v>) {
-        record_variants!((self, ga, ga, Some(ga.hir_id()), hir, GenericArg, GenericArg), [
-            Lifetime, Type, Const, Infer
-        ]);
+        record_variants!(
+            (self, ga, ga, Some(ga.hir_id()), hir, GenericArg, GenericArg),
+            [Lifetime, Type, Const, Infer]
+        );
         match ga {
             hir::GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
             hir::GenericArg::Type(ty) => self.visit_ty(ty),
@@ -515,34 +533,38 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
 
 impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
     fn visit_foreign_item(&mut self, i: &'v ast::ForeignItem) {
-        record_variants!((self, i, i.kind, None, ast, ForeignItem, ForeignItemKind), [
-            Static, Fn, TyAlias, MacCall
-        ]);
+        record_variants!(
+            (self, i, i.kind, None, ast, ForeignItem, ForeignItemKind),
+            [Static, Fn, TyAlias, MacCall]
+        );
         ast_visit::walk_item(self, i)
     }
 
     fn visit_item(&mut self, i: &'v ast::Item) {
-        record_variants!((self, i, i.kind, None, ast, Item, ItemKind), [
-            ExternCrate,
-            Use,
-            Static,
-            Const,
-            Fn,
-            Mod,
-            ForeignMod,
-            GlobalAsm,
-            TyAlias,
-            Enum,
-            Struct,
-            Union,
-            Trait,
-            TraitAlias,
-            Impl,
-            MacCall,
-            MacroDef,
-            Delegation,
-            DelegationMac
-        ]);
+        record_variants!(
+            (self, i, i.kind, None, ast, Item, ItemKind),
+            [
+                ExternCrate,
+                Use,
+                Static,
+                Const,
+                Fn,
+                Mod,
+                ForeignMod,
+                GlobalAsm,
+                TyAlias,
+                Enum,
+                Struct,
+                Union,
+                Trait,
+                TraitAlias,
+                Impl,
+                MacCall,
+                MacroDef,
+                Delegation,
+                DelegationMac
+            ]
+        );
         ast_visit::walk_item(self, i)
     }
 
@@ -557,9 +579,10 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_stmt(&mut self, s: &'v ast::Stmt) {
-        record_variants!((self, s, s.kind, None, ast, Stmt, StmtKind), [
-            Let, Item, Expr, Semi, Empty, MacCall
-        ]);
+        record_variants!(
+            (self, s, s.kind, None, ast, Stmt, StmtKind),
+            [Let, Item, Expr, Semi, Empty, MacCall]
+        );
         ast_visit::walk_stmt(self, s)
     }
 
@@ -574,27 +597,30 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_pat(&mut self, p: &'v ast::Pat) {
-        record_variants!((self, p, p.kind, None, ast, Pat, PatKind), [
-            Wild,
-            Ident,
-            Struct,
-            TupleStruct,
-            Or,
-            Path,
-            Tuple,
-            Box,
-            Deref,
-            Ref,
-            Expr,
-            Range,
-            Slice,
-            Rest,
-            Never,
-            Guard,
-            Paren,
-            MacCall,
-            Err
-        ]);
+        record_variants!(
+            (self, p, p.kind, None, ast, Pat, PatKind),
+            [
+                Wild,
+                Ident,
+                Struct,
+                TupleStruct,
+                Or,
+                Path,
+                Tuple,
+                Box,
+                Deref,
+                Ref,
+                Expr,
+                Range,
+                Slice,
+                Rest,
+                Never,
+                Guard,
+                Paren,
+                MacCall,
+                Err
+            ]
+        );
         ast_visit::walk_pat(self, p)
     }
 
@@ -614,29 +640,32 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_ty(&mut self, t: &'v ast::Ty) {
-        record_variants!((self, t, t.kind, None, ast, Ty, TyKind), [
-            Slice,
-            Array,
-            Ptr,
-            Ref,
-            PinnedRef,
-            BareFn,
-            UnsafeBinder,
-            Never,
-            Tup,
-            Path,
-            Pat,
-            TraitObject,
-            ImplTrait,
-            Paren,
-            Typeof,
-            Infer,
-            ImplicitSelf,
-            MacCall,
-            CVarArgs,
-            Dummy,
-            Err
-        ]);
+        record_variants!(
+            (self, t, t.kind, None, ast, Ty, TyKind),
+            [
+                Slice,
+                Array,
+                Ptr,
+                Ref,
+                PinnedRef,
+                BareFn,
+                UnsafeBinder,
+                Never,
+                Tup,
+                Path,
+                Pat,
+                TraitObject,
+                ImplTrait,
+                Paren,
+                Typeof,
+                Infer,
+                ImplicitSelf,
+                MacCall,
+                CVarArgs,
+                Dummy,
+                Err
+            ]
+        );
 
         ast_visit::walk_ty(self, t)
     }
@@ -647,11 +676,10 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) {
-        record_variants!((self, p, &p.kind, None, ast, WherePredicate, WherePredicateKind), [
-            BoundPredicate,
-            RegionPredicate,
-            EqPredicate
-        ]);
+        record_variants!(
+            (self, p, &p.kind, None, ast, WherePredicate, WherePredicateKind),
+            [BoundPredicate, RegionPredicate, EqPredicate]
+        );
         ast_visit::walk_where_predicate(self, p)
     }
 
@@ -661,21 +689,18 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_assoc_item(&mut self, i: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
-        record_variants!((self, i, i.kind, None, ast, AssocItem, AssocItemKind), [
-            Const,
-            Fn,
-            Type,
-            MacCall,
-            Delegation,
-            DelegationMac
-        ]);
+        record_variants!(
+            (self, i, i.kind, None, ast, AssocItem, AssocItemKind),
+            [Const, Fn, Type, MacCall, Delegation, DelegationMac]
+        );
         ast_visit::walk_assoc_item(self, i, ctxt);
     }
 
     fn visit_param_bound(&mut self, b: &'v ast::GenericBound, _ctxt: BoundKind) {
-        record_variants!((self, b, b, None, ast, GenericBound, GenericBound), [
-            Trait, Outlives, Use
-        ]);
+        record_variants!(
+            (self, b, b, None, ast, GenericBound, GenericBound),
+            [Trait, Outlives, Use]
+        );
         ast_visit::walk_param_bound(self, b)
     }
 
@@ -708,18 +733,18 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
     // common, so we implement `visit_generic_args` and tolerate the double
     // counting in the former case.
     fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) {
-        record_variants!((self, g, g, None, ast, GenericArgs, GenericArgs), [
-            AngleBracketed,
-            Parenthesized,
-            ParenthesizedElided
-        ]);
+        record_variants!(
+            (self, g, g, None, ast, GenericArgs, GenericArgs),
+            [AngleBracketed, Parenthesized, ParenthesizedElided]
+        );
         ast_visit::walk_generic_args(self, g)
     }
 
     fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
-        record_variants!((self, attr, attr.kind, None, ast, Attribute, AttrKind), [
-            Normal, DocComment
-        ]);
+        record_variants!(
+            (self, attr, attr.kind, None, ast, Attribute, AttrKind),
+            [Normal, DocComment]
+        );
         ast_visit::walk_attribute(self, attr)
     }
 
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index 6e8fd32610b..8b0cc9d726b 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-field-offset = "0.3.5"
 measureme = "11"
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index bbc83cca99d..73c205fdb17 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -11,7 +11,6 @@
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
-use field_offset::offset_of;
 use rustc_data_structures::stable_hasher::HashStable;
 use rustc_data_structures::sync::AtomicU64;
 use rustc_middle::arena::Arena;
@@ -89,7 +88,13 @@ where
     where
         QueryCtxt<'tcx>: 'a,
     {
-        self.dynamic.query_state.apply(&qcx.tcx.query_system.states)
+        // Safety:
+        // This is just manually doing the subfield referencing through pointer math.
+        unsafe {
+            &*(&qcx.tcx.query_system.states as *const QueryStates<'tcx>)
+                .byte_add(self.dynamic.query_state)
+                .cast::<QueryState<Self::Key>>()
+        }
     }
 
     #[inline(always)]
@@ -97,7 +102,13 @@ where
     where
         'tcx: 'a,
     {
-        self.dynamic.query_cache.apply(&qcx.tcx.query_system.caches)
+        // Safety:
+        // This is just manually doing the subfield referencing through pointer math.
+        unsafe {
+            &*(&qcx.tcx.query_system.caches as *const QueryCaches<'tcx>)
+                .byte_add(self.dynamic.query_cache)
+                .cast::<Self::Cache>()
+        }
     }
 
     #[inline(always)]
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 46ec538735a..e95c186f6b6 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -605,8 +605,8 @@ macro_rules! define_queries {
                     eval_always: is_eval_always!([$($modifiers)*]),
                     dep_kind: dep_graph::dep_kinds::$name,
                     handle_cycle_error: handle_cycle_error!([$($modifiers)*]),
-                    query_state: offset_of!(QueryStates<'tcx> => $name),
-                    query_cache: offset_of!(QueryCaches<'tcx> => $name),
+                    query_state: std::mem::offset_of!(QueryStates<'tcx>, $name),
+                    query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name),
                     cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key),
                     execute_query: |tcx, key| erase(tcx.$name(key)),
                     compute: |tcx, key| {
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index ca7064a36a1..c6781ecc566 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -567,10 +567,13 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                             Some(rename) => source.ident.span.to(rename.span),
                             None => source.ident.span,
                         };
-                        self.r.report_error(span, ResolutionError::SelfImportsOnlyAllowedWithin {
-                            root: parent.is_none(),
-                            span_with_rename,
-                        });
+                        self.r.report_error(
+                            span,
+                            ResolutionError::SelfImportsOnlyAllowedWithin {
+                                root: parent.is_none(),
+                                span_with_rename,
+                            },
+                        );
 
                         // Error recovery: replace `use foo::self;` with `use foo;`
                         if let Some(parent) = module_path.pop() {
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index db607dbb419..5eb8e420fa4 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -95,11 +95,14 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
 
     fn visit_macro_invoc(&mut self, id: NodeId) {
         let id = id.placeholder_to_expn_id();
-        let old_parent = self.resolver.invocation_parents.insert(id, InvocationParent {
-            parent_def: self.parent_def,
-            impl_trait_context: self.impl_trait_context,
-            in_attr: self.in_attr,
-        });
+        let old_parent = self.resolver.invocation_parents.insert(
+            id,
+            InvocationParent {
+                parent_def: self.parent_def,
+                impl_trait_context: self.impl_trait_context,
+                in_attr: self.in_attr,
+            },
+        );
         assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation");
     }
 }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 8dc752c2cb3..8d42b478647 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -990,14 +990,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             VisResolutionError::AncestorOnly(span) => {
                 self.dcx().create_err(errs::AncestorOnly(span))
             }
-            VisResolutionError::FailedToResolve(span, label, suggestion) => {
-                self.into_struct_error(span, ResolutionError::FailedToResolve {
-                    segment: None,
-                    label,
-                    suggestion,
-                    module: None,
-                })
-            }
+            VisResolutionError::FailedToResolve(span, label, suggestion) => self.into_struct_error(
+                span,
+                ResolutionError::FailedToResolve { segment: None, label, suggestion, module: None },
+            ),
             VisResolutionError::ExpectedFound(span, path_str, res) => {
                 self.dcx().create_err(errs::ExpectedModuleFound { span, res, path_str })
             }
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index a3d3e87ade0..499b9bca4d2 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1181,21 +1181,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                                             }
                                             Some(_) => None,
                                         };
-                                        (rib_ident.span, AttemptToUseNonConstantValueInConstant {
-                                            ident: original_rib_ident_def,
-                                            suggestion: "const",
-                                            current: "let",
-                                            type_span,
-                                        })
+                                        (
+                                            rib_ident.span,
+                                            AttemptToUseNonConstantValueInConstant {
+                                                ident: original_rib_ident_def,
+                                                suggestion: "const",
+                                                current: "let",
+                                                type_span,
+                                            },
+                                        )
                                     }
-                                    Some((ident, kind)) => {
-                                        (span, AttemptToUseNonConstantValueInConstant {
+                                    Some((ident, kind)) => (
+                                        span,
+                                        AttemptToUseNonConstantValueInConstant {
                                             ident,
                                             suggestion: "let",
                                             current: kind.as_str(),
                                             type_span: None,
-                                        })
-                                    }
+                                        },
+                                    ),
                                 };
                                 self.report_error(span, resolution_error);
                             }
@@ -1203,10 +1207,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         }
                         RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
-                                self.report_error(span, ParamInTyOfConstParam {
-                                    name: rib_ident.name,
-                                    param_kind: None,
-                                });
+                                self.report_error(
+                                    span,
+                                    ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: None,
+                                    },
+                                );
                             }
                             return Res::Err;
                         }
@@ -1287,10 +1294,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         }
                         RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
-                                self.report_error(span, ResolutionError::ParamInTyOfConstParam {
-                                    name: rib_ident.name,
-                                    param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
-                                });
+                                self.report_error(
+                                    span,
+                                    ResolutionError::ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
+                                    },
+                                );
                             }
                             return Res::Err;
                         }
@@ -1353,10 +1363,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         }
                         RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
-                                self.report_error(span, ResolutionError::ParamInTyOfConstParam {
-                                    name: rib_ident.name,
-                                    param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
-                                });
+                                self.report_error(
+                                    span,
+                                    ResolutionError::ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
+                                    },
+                                );
                             }
                             return Res::Err;
                         }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index d555c938770..b1b234eb757 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -914,12 +914,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             } => {
                 if no_ambiguity {
                     assert!(import.imported_module.get().is_none());
-                    self.report_error(span, ResolutionError::FailedToResolve {
-                        segment: Some(segment_name),
-                        label,
-                        suggestion,
-                        module,
-                    });
+                    self.report_error(
+                        span,
+                        ResolutionError::FailedToResolve {
+                            segment: Some(segment_name),
+                            label,
+                            suggestion,
+                            module,
+                        },
+                    );
                 }
                 return None;
             }
@@ -1500,7 +1503,7 @@ fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Sp
     let global = !names.is_empty() && names[0].name == kw::PathRoot;
     if let Some(pos) = pos {
         let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
-        names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>())
+        names_to_string(names.iter().map(|ident| ident.name))
     } else {
         let names = if global { &names[1..] } else { names };
         if names.is_empty() {
@@ -1508,7 +1511,7 @@ fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Sp
         } else {
             format!(
                 "{}::{}",
-                names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>()),
+                names_to_string(names.iter().map(|ident| ident.name)),
                 import_kind_to_string(import_kind),
             )
         }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index e37e7e98ee7..508bd831ccb 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1823,9 +1823,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                             && Some(true) == self.diag_metadata.in_non_gat_assoc_type
                             && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind
                         {
-                            if def_id_matches_path(self.r.tcx, trait_id, &[
-                                "core", "iter", "traits", "iterator", "Iterator",
-                            ]) {
+                            if def_id_matches_path(
+                                self.r.tcx,
+                                trait_id,
+                                &["core", "iter", "traits", "iterator", "Iterator"],
+                            ) {
                                 self.r.dcx().emit_err(errors::LendingIteratorReportError {
                                     lifetime: lifetime.ident.span,
                                     ty: ty.span,
@@ -3425,11 +3427,14 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
 
         match seen_trait_items.entry(id_in_trait) {
             Entry::Occupied(entry) => {
-                self.report_error(span, ResolutionError::TraitImplDuplicate {
-                    name: ident,
-                    old_span: *entry.get(),
-                    trait_item_span: binding.span,
-                });
+                self.report_error(
+                    span,
+                    ResolutionError::TraitImplDuplicate {
+                        name: ident,
+                        old_span: *entry.get(),
+                        trait_item_span: binding.span,
+                    },
+                );
                 return;
             }
             Entry::Vacant(entry) => {
@@ -3460,13 +3465,16 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             }
         };
         let trait_path = path_names_to_string(path);
-        self.report_error(span, ResolutionError::TraitImplMismatch {
-            name: ident,
-            kind,
-            code,
-            trait_path,
-            trait_item_span: binding.span,
-        });
+        self.report_error(
+            span,
+            ResolutionError::TraitImplMismatch {
+                name: ident,
+                kind,
+                code,
+                trait_path,
+                trait_item_span: binding.span,
+            },
+        );
     }
 
     fn resolve_const_body(&mut self, expr: &'ast Expr, item: Option<(Ident, ConstantItemKind)>) {
@@ -3845,10 +3853,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         .patterns_with_skipped_bindings
                         .entry(def_id)
                         .or_default()
-                        .push((pat.span, match rest {
-                            ast::PatFieldsRest::Recovered(guar) => Err(*guar),
-                            _ => Ok(()),
-                        }));
+                        .push((
+                            pat.span,
+                            match rest {
+                                ast::PatFieldsRest::Recovered(guar) => Err(*guar),
+                                _ => Ok(()),
+                            },
+                        ));
                 }
             }
             ast::PatFieldsRest::None => {}
@@ -4485,12 +4496,15 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 segment_name,
                 error_implied_by_parse_error: _,
             } => {
-                return Err(respan(span, ResolutionError::FailedToResolve {
-                    segment: Some(segment_name),
-                    label,
-                    suggestion,
-                    module,
-                }));
+                return Err(respan(
+                    span,
+                    ResolutionError::FailedToResolve {
+                        segment: Some(segment_name),
+                        label,
+                        suggestion,
+                        module,
+                    },
+                ));
             }
             PathResult::Module(..) | PathResult::Failed { .. } => return Ok(None),
             PathResult::Indeterminate => bug!("indeterminate path result in resolve_qpath"),
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 57679d595da..a80b68d9773 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1048,12 +1048,15 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
 
         debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
         err.code(E0424);
-        err.span_label(span, match source {
-            PathSource::Pat => {
-                "`self` value is a keyword and may not be bound to variables or shadowed"
-            }
-            _ => "`self` value is a keyword only available in methods with a `self` parameter",
-        });
+        err.span_label(
+            span,
+            match source {
+                PathSource::Pat => {
+                    "`self` value is a keyword and may not be bound to variables or shadowed"
+                }
+                _ => "`self` value is a keyword only available in methods with a `self` parameter",
+            },
+        );
         let is_assoc_fn = self.self_type_is_available();
         let self_from_macro = "a `self` parameter, but a macro invocation can only \
                                access identifiers it receives from parameters";
@@ -2399,15 +2402,18 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     if module_def_id == def_id {
                         let path =
                             Path { span: name_binding.span, segments: path_segments, tokens: None };
-                        result = Some((module, ImportSuggestion {
-                            did: Some(def_id),
-                            descr: "module",
-                            path,
-                            accessible: true,
-                            doc_visible,
-                            note: None,
-                            via_import: false,
-                        }));
+                        result = Some((
+                            module,
+                            ImportSuggestion {
+                                did: Some(def_id),
+                                descr: "module",
+                                path,
+                                accessible: true,
+                                doc_visible,
+                                note: None,
+                                via_import: false,
+                            },
+                        ));
                     } else {
                         // add the module to the lookup
                         if seen_modules.insert(module_def_id) {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 1cf821653c9..90191b7776f 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -358,7 +358,7 @@ impl Segment {
     }
 
     fn names_to_string(segments: &[Segment]) -> String {
-        names_to_string(&segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>())
+        names_to_string(segments.iter().map(|seg| seg.ident.name))
     }
 }
 
@@ -2241,13 +2241,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     }
 }
 
-fn names_to_string(names: &[Symbol]) -> String {
+fn names_to_string(names: impl Iterator<Item = Symbol>) -> String {
     let mut result = String::new();
-    for (i, name) in names.iter().filter(|name| **name != kw::PathRoot).enumerate() {
+    for (i, name) in names.filter(|name| *name != kw::PathRoot).enumerate() {
         if i > 0 {
             result.push_str("::");
         }
-        if Ident::with_dummy_span(*name).is_raw_guess() {
+        if Ident::with_dummy_span(name).is_raw_guess() {
             result.push_str("r#");
         }
         result.push_str(name.as_str());
@@ -2256,31 +2256,32 @@ fn names_to_string(names: &[Symbol]) -> String {
 }
 
 fn path_names_to_string(path: &Path) -> String {
-    names_to_string(&path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>())
+    names_to_string(path.segments.iter().map(|seg| seg.ident.name))
 }
 
 /// A somewhat inefficient routine to obtain the name of a module.
-fn module_to_string(module: Module<'_>) -> Option<String> {
+fn module_to_string(mut module: Module<'_>) -> Option<String> {
     let mut names = Vec::new();
-
-    fn collect_mod(names: &mut Vec<Symbol>, module: Module<'_>) {
+    loop {
         if let ModuleKind::Def(.., name) = module.kind {
             if let Some(parent) = module.parent {
                 names.push(name);
-                collect_mod(names, parent);
+                module = parent
+            } else {
+                break;
             }
         } else {
             names.push(sym::opaque_module_name_placeholder);
-            collect_mod(names, module.parent.unwrap());
+            let Some(parent) = module.parent else {
+                return None;
+            };
+            module = parent;
         }
     }
-    collect_mod(&mut names, module);
-
     if names.is_empty() {
         return None;
     }
-    names.reverse();
-    Some(names_to_string(&names))
+    Some(names_to_string(names.iter().rev().copied()))
 }
 
 #[derive(Copy, Clone, Debug)]
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index aeb9672b758..cca01a01e98 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -888,12 +888,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                                 None,
                             )
                         };
-                    self.report_error(span, ResolutionError::FailedToResolve {
-                        segment: path.last().map(|segment| segment.ident.name),
-                        label,
-                        suggestion,
-                        module,
-                    });
+                    self.report_error(
+                        span,
+                        ResolutionError::FailedToResolve {
+                            segment: path.last().map(|segment| segment.ident.name),
+                            label,
+                            suggestion,
+                            module,
+                        },
+                    );
                 }
                 PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
             }
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index eb14b78a003..e5fba8cc5a2 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -133,7 +133,8 @@ session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination`
 session_unsupported_crate_type_for_target =
     dropping unsupported crate type `{$crate_type}` for target `{$target_triple}`
 
-session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is greater than 5
+session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is not supported
+session_unsupported_dwarf_version_help = supported DWARF versions are 2, 3, 4 and 5
 
 session_unsupported_reg_struct_return_arch = `-Zreg-struct-return` is only supported on x86
 session_unsupported_regparm = `-Zregparm={$regparm}` is unsupported (valid values 0-3)
diff --git a/compiler/rustc_session/src/config/native_libs/tests.rs b/compiler/rustc_session/src/config/native_libs/tests.rs
index 3bcab93ef4b..287c98fe7eb 100644
--- a/compiler/rustc_session/src/config/native_libs/tests.rs
+++ b/compiler/rustc_session/src/config/native_libs/tests.rs
@@ -14,30 +14,22 @@ fn split() {
         (":bar", P { kind: None, modifiers: None, name: "", new_name: Some("bar") }),
         ("kind=foo", P { kind: Some("kind"), modifiers: None, name: "foo", new_name: None }),
         (":mods=foo", P { kind: Some(""), modifiers: Some("mods"), name: "foo", new_name: None }),
-        (":mods=:bar", P {
-            kind: Some(""),
-            modifiers: Some("mods"),
-            name: "",
-            new_name: Some("bar"),
-        }),
-        ("kind=foo:bar", P {
-            kind: Some("kind"),
-            modifiers: None,
-            name: "foo",
-            new_name: Some("bar"),
-        }),
-        ("kind:mods=foo", P {
-            kind: Some("kind"),
-            modifiers: Some("mods"),
-            name: "foo",
-            new_name: None,
-        }),
-        ("kind:mods=foo:bar", P {
-            kind: Some("kind"),
-            modifiers: Some("mods"),
-            name: "foo",
-            new_name: Some("bar"),
-        }),
+        (
+            ":mods=:bar",
+            P { kind: Some(""), modifiers: Some("mods"), name: "", new_name: Some("bar") },
+        ),
+        (
+            "kind=foo:bar",
+            P { kind: Some("kind"), modifiers: None, name: "foo", new_name: Some("bar") },
+        ),
+        (
+            "kind:mods=foo",
+            P { kind: Some("kind"), modifiers: Some("mods"), name: "foo", new_name: None },
+        ),
+        (
+            "kind:mods=foo:bar",
+            P { kind: Some("kind"), modifiers: Some("mods"), name: "foo", new_name: Some("bar") },
+        ),
         ("::==::", P { kind: Some(""), modifiers: Some(":"), name: "=", new_name: Some(":") }),
         ("==::==", P { kind: Some(""), modifiers: None, name: "=", new_name: Some(":==") }),
     ];
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 6c26a781487..75c3b2c7a85 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -161,6 +161,7 @@ pub(crate) struct UnstableVirtualFunctionElimination;
 
 #[derive(Diagnostic)]
 #[diag(session_unsupported_dwarf_version)]
+#[help(session_unsupported_dwarf_version_help)]
 pub(crate) struct UnsupportedDwarfVersion {
     pub(crate) dwarf_version: u32,
 }
diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs
index 78473fccd2d..b750d870cb6 100644
--- a/compiler/rustc_session/src/search_paths.rs
+++ b/compiler/rustc_session/src/search_paths.rs
@@ -140,10 +140,10 @@ impl SearchPath {
                     e.ok().and_then(|e| {
                         e.file_name().to_str().map(|s| {
                             let file_name_str: Arc<str> = s.into();
-                            (Arc::clone(&file_name_str), SearchPathFile {
-                                path: e.path().into(),
-                                file_name_str,
-                            })
+                            (
+                                Arc::clone(&file_name_str),
+                                SearchPathFile { path: e.path().into(), file_name_str },
+                            )
                         })
                     })
                 })
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 0851e859a0f..f795ad1ee17 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1251,7 +1251,8 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
     }
 
     if let Some(dwarf_version) = sess.opts.unstable_opts.dwarf_version {
-        if dwarf_version > 5 {
+        // DWARF 1 is not supported by LLVM and DWARF 6 is not yet finalized.
+        if dwarf_version < 2 || dwarf_version > 5 {
             sess.dcx().emit_err(errors::UnsupportedDwarfVersion { dwarf_version });
         }
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index a2d95f0f693..a0faf20c79a 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -771,12 +771,10 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
                 index: early_reg.index,
                 name: early_reg.name.to_string(),
             }),
-            ty::ReBound(db_index, bound_reg) => {
-                RegionKind::ReBound(db_index.as_u32(), BoundRegion {
-                    var: bound_reg.var.as_u32(),
-                    kind: bound_reg.kind.stable(tables),
-                })
-            }
+            ty::ReBound(db_index, bound_reg) => RegionKind::ReBound(
+                db_index.as_u32(),
+                BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) },
+            ),
             ty::ReStatic => RegionKind::ReStatic,
             ty::RePlaceholder(place_holder) => {
                 RegionKind::RePlaceholder(stable_mir::ty::Placeholder {
diff --git a/compiler/rustc_target/src/callconv/aarch64.rs b/compiler/rustc_target/src/callconv/aarch64.rs
index d712bec9b78..5c23e7036b0 100644
--- a/compiler/rustc_target/src/callconv/aarch64.rs
+++ b/compiler/rustc_target/src/callconv/aarch64.rs
@@ -2,7 +2,7 @@ use std::iter;
 
 use rustc_abi::{BackendRepr, HasDataLayout, Primitive, TyAbiInterface};
 
-use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
+use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
 use crate::spec::{HasTargetSpec, Target};
 
 /// Indicates the variant of the AArch64 ABI we are compiling for.
diff --git a/compiler/rustc_target/src/callconv/amdgpu.rs b/compiler/rustc_target/src/callconv/amdgpu.rs
index 91ac00e0250..3ec6d0b3da2 100644
--- a/compiler/rustc_target/src/callconv/amdgpu.rs
+++ b/compiler/rustc_target/src/callconv/amdgpu.rs
@@ -1,6 +1,6 @@
 use rustc_abi::{HasDataLayout, TyAbiInterface};
 
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::callconv::{ArgAbi, FnAbi};
 
 fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>)
 where
diff --git a/compiler/rustc_target/src/callconv/arm.rs b/compiler/rustc_target/src/callconv/arm.rs
index 75797daba69..0a5dcc66347 100644
--- a/compiler/rustc_target/src/callconv/arm.rs
+++ b/compiler/rustc_target/src/callconv/arm.rs
@@ -1,6 +1,6 @@
 use rustc_abi::{HasDataLayout, TyAbiInterface};
 
-use crate::abi::call::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform};
+use crate::callconv::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform};
 use crate::spec::HasTargetSpec;
 
 fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
diff --git a/compiler/rustc_target/src/callconv/avr.rs b/compiler/rustc_target/src/callconv/avr.rs
index dfc991e0954..0d690eff68d 100644
--- a/compiler/rustc_target/src/callconv/avr.rs
+++ b/compiler/rustc_target/src/callconv/avr.rs
@@ -30,7 +30,7 @@
 //! compatible with AVR-GCC - Rust and AVR-GCC only differ in the small amount
 //! of compiler frontend specific calling convention logic implemented here.
 
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::callconv::{ArgAbi, FnAbi};
 
 fn classify_ret_ty<Ty>(ret: &mut ArgAbi<'_, Ty>) {
     if ret.layout.is_aggregate() {
diff --git a/compiler/rustc_target/src/callconv/bpf.rs b/compiler/rustc_target/src/callconv/bpf.rs
index f19772ac709..f958aeb9bb6 100644
--- a/compiler/rustc_target/src/callconv/bpf.rs
+++ b/compiler/rustc_target/src/callconv/bpf.rs
@@ -1,5 +1,5 @@
 // see https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFCallingConv.td
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::callconv::{ArgAbi, FnAbi};
 
 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
     if ret.layout.is_aggregate() || ret.layout.size.bits() > 64 {
diff --git a/compiler/rustc_target/src/callconv/csky.rs b/compiler/rustc_target/src/callconv/csky.rs
index b1c1ae814a7..cf289e639ea 100644
--- a/compiler/rustc_target/src/callconv/csky.rs
+++ b/compiler/rustc_target/src/callconv/csky.rs
@@ -4,7 +4,7 @@
 // Reference: Clang CSKY lowering code
 // https://github.com/llvm/llvm-project/blob/4a074f32a6914f2a8d7215d78758c24942dddc3d/clang/lib/CodeGen/Targets/CSKY.cpp#L76-L162
 
-use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
+use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform};
 
 fn classify_ret<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     if !arg.layout.is_sized() {
diff --git a/compiler/rustc_target/src/callconv/hexagon.rs b/compiler/rustc_target/src/callconv/hexagon.rs
index 0a0688880c0..d4f6dd0a5b4 100644
--- a/compiler/rustc_target/src/callconv/hexagon.rs
+++ b/compiler/rustc_target/src/callconv/hexagon.rs
@@ -1,4 +1,4 @@
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::callconv::{ArgAbi, FnAbi};
 
 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
     if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 {
diff --git a/compiler/rustc_target/src/callconv/m68k.rs b/compiler/rustc_target/src/callconv/m68k.rs
index 82fe81f8c52..0b637e1e27a 100644
--- a/compiler/rustc_target/src/callconv/m68k.rs
+++ b/compiler/rustc_target/src/callconv/m68k.rs
@@ -1,4 +1,4 @@
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::callconv::{ArgAbi, FnAbi};
 
 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
     if ret.layout.is_aggregate() {
diff --git a/compiler/rustc_target/src/callconv/mips.rs b/compiler/rustc_target/src/callconv/mips.rs
index f7d68822155..6162267a0d0 100644
--- a/compiler/rustc_target/src/callconv/mips.rs
+++ b/compiler/rustc_target/src/callconv/mips.rs
@@ -1,6 +1,6 @@
 use rustc_abi::{HasDataLayout, Size};
 
-use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
+use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform};
 
 fn classify_ret<Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
 where
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index 9e651376cd7..50ac6c8fcde 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -2,10 +2,9 @@ use std::str::FromStr;
 use std::{fmt, iter};
 
 use rustc_abi::{
-    AddressSpace, Align, BackendRepr, ExternAbi, HasDataLayout, Scalar, Size, TyAbiInterface,
-    TyAndLayout,
+    AddressSpace, Align, BackendRepr, ExternAbi, HasDataLayout, Primitive, Reg, RegKind, Scalar,
+    Size, TyAbiInterface, TyAndLayout,
 };
-pub use rustc_abi::{Primitive, Reg, RegKind};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
diff --git a/compiler/rustc_target/src/callconv/msp430.rs b/compiler/rustc_target/src/callconv/msp430.rs
index 4f613aa6c15..3b53d183ddc 100644
--- a/compiler/rustc_target/src/callconv/msp430.rs
+++ b/compiler/rustc_target/src/callconv/msp430.rs
@@ -1,7 +1,7 @@
 // Reference: MSP430 Embedded Application Binary Interface
 // https://www.ti.com/lit/an/slaa534a/slaa534a.pdf
 
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::callconv::{ArgAbi, FnAbi};
 
 // 3.5 Structures or Unions Passed and Returned by Reference
 //
diff --git a/compiler/rustc_target/src/callconv/nvptx64.rs b/compiler/rustc_target/src/callconv/nvptx64.rs
index c5da1855658..a26e7dac5ba 100644
--- a/compiler/rustc_target/src/callconv/nvptx64.rs
+++ b/compiler/rustc_target/src/callconv/nvptx64.rs
@@ -1,7 +1,7 @@
 use rustc_abi::{HasDataLayout, Reg, Size, TyAbiInterface};
 
 use super::{ArgAttribute, ArgAttributes, ArgExtension, CastTarget};
-use crate::abi::call::{ArgAbi, FnAbi, Uniform};
+use crate::callconv::{ArgAbi, FnAbi, Uniform};
 
 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
     if ret.layout.is_aggregate() && ret.layout.is_sized() {
diff --git a/compiler/rustc_target/src/callconv/powerpc.rs b/compiler/rustc_target/src/callconv/powerpc.rs
index f3b05c48173..2f6129626b8 100644
--- a/compiler/rustc_target/src/callconv/powerpc.rs
+++ b/compiler/rustc_target/src/callconv/powerpc.rs
@@ -1,4 +1,4 @@
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::callconv::{ArgAbi, FnAbi};
 use crate::spec::HasTargetSpec;
 
 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs
index 7a66ce8529a..89ec85e4b66 100644
--- a/compiler/rustc_target/src/callconv/powerpc64.rs
+++ b/compiler/rustc_target/src/callconv/powerpc64.rs
@@ -4,7 +4,7 @@
 
 use rustc_abi::{Endian, HasDataLayout, TyAbiInterface};
 
-use crate::abi::call::{Align, ArgAbi, FnAbi, Reg, RegKind, Uniform};
+use crate::callconv::{Align, ArgAbi, FnAbi, Reg, RegKind, Uniform};
 use crate::spec::HasTargetSpec;
 
 #[derive(Debug, Clone, Copy, PartialEq)]
diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs
index 24531b0ef63..265ae20f991 100644
--- a/compiler/rustc_target/src/callconv/riscv.rs
+++ b/compiler/rustc_target/src/callconv/riscv.rs
@@ -9,7 +9,7 @@ use rustc_abi::{
     TyAbiInterface, TyAndLayout, Variants,
 };
 
-use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform};
+use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform};
 use crate::spec::HasTargetSpec;
 
 #[derive(Copy, Clone)]
diff --git a/compiler/rustc_target/src/callconv/s390x.rs b/compiler/rustc_target/src/callconv/s390x.rs
index edf57098d6d..4f69e32b2e3 100644
--- a/compiler/rustc_target/src/callconv/s390x.rs
+++ b/compiler/rustc_target/src/callconv/s390x.rs
@@ -3,7 +3,7 @@
 
 use rustc_abi::{BackendRepr, HasDataLayout, TyAbiInterface};
 
-use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind};
+use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind};
 use crate::spec::HasTargetSpec;
 
 fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
diff --git a/compiler/rustc_target/src/callconv/sparc.rs b/compiler/rustc_target/src/callconv/sparc.rs
index f7d68822155..6162267a0d0 100644
--- a/compiler/rustc_target/src/callconv/sparc.rs
+++ b/compiler/rustc_target/src/callconv/sparc.rs
@@ -1,6 +1,6 @@
 use rustc_abi::{HasDataLayout, Size};
 
-use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
+use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform};
 
 fn classify_ret<Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
 where
diff --git a/compiler/rustc_target/src/callconv/sparc64.rs b/compiler/rustc_target/src/callconv/sparc64.rs
index 392fb5156fc..7ca0031fc59 100644
--- a/compiler/rustc_target/src/callconv/sparc64.rs
+++ b/compiler/rustc_target/src/callconv/sparc64.rs
@@ -5,7 +5,7 @@ use rustc_abi::{
     TyAndLayout,
 };
 
-use crate::abi::call::{
+use crate::callconv::{
     ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, Uniform,
 };
 use crate::spec::HasTargetSpec;
diff --git a/compiler/rustc_target/src/callconv/wasm.rs b/compiler/rustc_target/src/callconv/wasm.rs
index 56cd7a3f93d..364a6551131 100644
--- a/compiler/rustc_target/src/callconv/wasm.rs
+++ b/compiler/rustc_target/src/callconv/wasm.rs
@@ -1,6 +1,6 @@
 use rustc_abi::{BackendRepr, Float, HasDataLayout, Integer, Primitive, TyAbiInterface};
 
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::callconv::{ArgAbi, FnAbi};
 
 fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool
 where
diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs
index 7c88d9b55cf..5b9414536d8 100644
--- a/compiler/rustc_target/src/callconv/x86.rs
+++ b/compiler/rustc_target/src/callconv/x86.rs
@@ -3,7 +3,7 @@ use rustc_abi::{
     TyAbiInterface, TyAndLayout,
 };
 
-use crate::abi::call::{ArgAttribute, FnAbi, PassMode};
+use crate::callconv::{ArgAttribute, FnAbi, PassMode};
 use crate::spec::HasTargetSpec;
 
 #[derive(PartialEq)]
diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs
index 6e9b4690a2c..b15d82c26da 100644
--- a/compiler/rustc_target/src/callconv/x86_64.rs
+++ b/compiler/rustc_target/src/callconv/x86_64.rs
@@ -6,7 +6,7 @@ use rustc_abi::{
     Variants,
 };
 
-use crate::abi::call::{ArgAbi, CastTarget, FnAbi};
+use crate::callconv::{ArgAbi, CastTarget, FnAbi};
 
 /// Classification of "eightbyte" components.
 // N.B., the order of the variants is from general to specific,
diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs
index 816564d2fed..23ef2cf8284 100644
--- a/compiler/rustc_target/src/callconv/x86_win64.rs
+++ b/compiler/rustc_target/src/callconv/x86_win64.rs
@@ -1,6 +1,6 @@
 use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind, Size};
 
-use crate::abi::call::{ArgAbi, FnAbi, Reg};
+use crate::callconv::{ArgAbi, FnAbi, Reg};
 use crate::spec::HasTargetSpec;
 
 // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
diff --git a/compiler/rustc_target/src/callconv/xtensa.rs b/compiler/rustc_target/src/callconv/xtensa.rs
index 2542713bc11..6c030cb3bf7 100644
--- a/compiler/rustc_target/src/callconv/xtensa.rs
+++ b/compiler/rustc_target/src/callconv/xtensa.rs
@@ -7,7 +7,7 @@
 
 use rustc_abi::{BackendRepr, HasDataLayout, Size, TyAbiInterface};
 
-use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
+use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform};
 use crate::spec::HasTargetSpec;
 
 const NUM_ARG_GPRS: u64 = 6;
diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs
index 961cce5d6b9..15cf7e195db 100644
--- a/compiler/rustc_target/src/json.rs
+++ b/compiler/rustc_target/src/json.rs
@@ -92,7 +92,7 @@ impl<A: ToJson> ToJson for Option<A> {
     }
 }
 
-impl ToJson for crate::abi::call::Conv {
+impl ToJson for crate::callconv::Conv {
     fn to_json(&self) -> Json {
         let buf: String;
         let s = match self {
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index 11fc09d26e4..bde4af643fa 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -30,12 +30,6 @@ pub mod target_features;
 #[cfg(test)]
 mod tests;
 
-pub mod abi {
-    pub use rustc_abi::*;
-
-    pub use crate::callconv as call;
-}
-
 pub use rustc_abi::HashStableContext;
 
 /// The name of rustc's own place to organize libraries.
diff --git a/compiler/rustc_target/src/spec/base/apple/tests.rs b/compiler/rustc_target/src/spec/base/apple/tests.rs
index a7335c9bcae..7a985ad4dc0 100644
--- a/compiler/rustc_target/src/spec/base/apple/tests.rs
+++ b/compiler/rustc_target/src/spec/base/apple/tests.rs
@@ -32,10 +32,13 @@ fn macos_link_environment_unmodified() {
     for target in all_macos_targets {
         // macOS targets should only remove information for cross-compiling, but never
         // for the host.
-        assert_eq!(target.link_env_remove, crate::spec::cvs![
-            "IPHONEOS_DEPLOYMENT_TARGET",
-            "TVOS_DEPLOYMENT_TARGET",
-            "XROS_DEPLOYMENT_TARGET"
-        ],);
+        assert_eq!(
+            target.link_env_remove,
+            crate::spec::cvs![
+                "IPHONEOS_DEPLOYMENT_TARGET",
+                "TVOS_DEPLOYMENT_TARGET",
+                "XROS_DEPLOYMENT_TARGET"
+            ],
+        );
     }
 }
diff --git a/compiler/rustc_target/src/spec/base/avr_gnu.rs b/compiler/rustc_target/src/spec/base/avr_gnu.rs
index 4f348af21ad..3554dcfcb4a 100644
--- a/compiler/rustc_target/src/spec/base/avr_gnu.rs
+++ b/compiler/rustc_target/src/spec/base/avr_gnu.rs
@@ -28,9 +28,10 @@ pub(crate) fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
             linker: Some("avr-gcc".into()),
             eh_frame_header: false,
             pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]),
-            late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-                "-lgcc",
-            ]),
+            late_link_args: TargetOptions::link_args(
+                LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+                &["-lgcc"],
+            ),
             max_atomic_width: Some(16),
             atomic_cas: false,
             relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/base/fuchsia.rs b/compiler/rustc_target/src/spec/base/fuchsia.rs
index 910ee328368..9deafcac27f 100644
--- a/compiler/rustc_target/src/spec/base/fuchsia.rs
+++ b/compiler/rustc_target/src/spec/base/fuchsia.rs
@@ -8,19 +8,22 @@ pub(crate) fn opts() -> TargetOptions {
     // so we only list them for ld/lld.
     //
     // https://github.com/llvm/llvm-project/blob/db9322b2066c55254e7691efeab863f43bfcc084/clang/lib/Driver/ToolChains/Fuchsia.cpp#L31
-    let pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "--build-id",
-        "--hash-style=gnu",
-        "-z",
-        "max-page-size=4096",
-        "-z",
-        "now",
-        "-z",
-        "rodynamic",
-        "-z",
-        "separate-loadable-segments",
-        "--pack-dyn-relocs=relr",
-    ]);
+    let pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &[
+            "--build-id",
+            "--hash-style=gnu",
+            "-z",
+            "max-page-size=4096",
+            "-z",
+            "now",
+            "-z",
+            "rodynamic",
+            "-z",
+            "separate-loadable-segments",
+            "--pack-dyn-relocs=relr",
+        ],
+    );
 
     TargetOptions {
         os: "fuchsia".into(),
diff --git a/compiler/rustc_target/src/spec/base/illumos.rs b/compiler/rustc_target/src/spec/base/illumos.rs
index bb7dfafc53e..2391b229e5b 100644
--- a/compiler/rustc_target/src/spec/base/illumos.rs
+++ b/compiler/rustc_target/src/spec/base/illumos.rs
@@ -1,25 +1,28 @@
 use crate::spec::{Cc, FramePointer, LinkerFlavor, TargetOptions, cvs};
 
 pub(crate) fn opts() -> TargetOptions {
-    let late_link_args = TargetOptions::link_args(LinkerFlavor::Unix(Cc::Yes), &[
-        // The illumos libc contains a stack unwinding implementation, as
-        // does libgcc_s. The latter implementation includes several
-        // additional symbols that are not always in base libc. To force
-        // the consistent use of just one unwinder, we ensure libc appears
-        // after libgcc_s in the NEEDED list for the resultant binary by
-        // ignoring any attempts to add it as a dynamic dependency until the
-        // very end.
-        // FIXME: This should be replaced by a more complete and generic
-        // mechanism for controlling the order of library arguments passed
-        // to the linker.
-        "-lc",
-        // LLVM will insert calls to the stack protector functions
-        // "__stack_chk_fail" and "__stack_chk_guard" into code in native
-        // object files. Some platforms include these symbols directly in
-        // libc, but at least historically these have been provided in
-        // libssp.so on illumos and Solaris systems.
-        "-lssp",
-    ]);
+    let late_link_args = TargetOptions::link_args(
+        LinkerFlavor::Unix(Cc::Yes),
+        &[
+            // The illumos libc contains a stack unwinding implementation, as
+            // does libgcc_s. The latter implementation includes several
+            // additional symbols that are not always in base libc. To force
+            // the consistent use of just one unwinder, we ensure libc appears
+            // after libgcc_s in the NEEDED list for the resultant binary by
+            // ignoring any attempts to add it as a dynamic dependency until the
+            // very end.
+            // FIXME: This should be replaced by a more complete and generic
+            // mechanism for controlling the order of library arguments passed
+            // to the linker.
+            "-lc",
+            // LLVM will insert calls to the stack protector functions
+            // "__stack_chk_fail" and "__stack_chk_guard" into code in native
+            // object files. Some platforms include these symbols directly in
+            // libc, but at least historically these have been provided in
+            // libssp.so on illumos and Solaris systems.
+            "-lssp",
+        ],
+    );
 
     TargetOptions {
         os: "illumos".into(),
diff --git a/compiler/rustc_target/src/spec/base/nto_qnx.rs b/compiler/rustc_target/src/spec/base/nto_qnx.rs
index 819e68a0500..3f35b8b801a 100644
--- a/compiler/rustc_target/src/spec/base/nto_qnx.rs
+++ b/compiler/rustc_target/src/spec/base/nto_qnx.rs
@@ -77,10 +77,10 @@ pub(crate) fn pre_link_args(api_var: ApiVariant, arch: Arch) -> LinkArgs {
         ApiVariant::Default => {
             TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[qcc_arg])
         }
-        ApiVariant::IoSock => TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-            qcc_arg,
-            get_iosock_param(arch_lib_dir),
-        ]),
+        ApiVariant::IoSock => TargetOptions::link_args(
+            LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+            &[qcc_arg, get_iosock_param(arch_lib_dir)],
+        ),
     }
 }
 
diff --git a/compiler/rustc_target/src/spec/base/uefi_msvc.rs b/compiler/rustc_target/src/spec/base/uefi_msvc.rs
index b0232ecbe61..4766eab7fd7 100644
--- a/compiler/rustc_target/src/spec/base/uefi_msvc.rs
+++ b/compiler/rustc_target/src/spec/base/uefi_msvc.rs
@@ -14,22 +14,25 @@ use crate::spec::{LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOption
 pub(crate) fn opts() -> TargetOptions {
     let mut base = base::msvc::opts();
 
-    base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &[
-        // Non-standard subsystems have no default entry-point in PE+ files. We have to define
-        // one. "efi_main" seems to be a common choice amongst other implementations and the
-        // spec.
-        "/entry:efi_main",
-        // COFF images have a "Subsystem" field in their header, which defines what kind of
-        // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
-        // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
-        // which is very likely the most common option. Individual projects can override this
-        // with custom linker flags.
-        // The subsystem-type only has minor effects on the application. It defines the memory
-        // regions the application is loaded into (runtime-drivers need to be put into
-        // reserved areas), as well as whether a return from the entry-point is treated as
-        // exit (default for applications).
-        "/subsystem:efi_application",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Msvc(Lld::No),
+        &[
+            // Non-standard subsystems have no default entry-point in PE+ files. We have to define
+            // one. "efi_main" seems to be a common choice amongst other implementations and the
+            // spec.
+            "/entry:efi_main",
+            // COFF images have a "Subsystem" field in their header, which defines what kind of
+            // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
+            // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
+            // which is very likely the most common option. Individual projects can override this
+            // with custom linker flags.
+            // The subsystem-type only has minor effects on the application. It defines the memory
+            // regions the application is loaded into (runtime-drivers need to be put into
+            // reserved areas), as well as whether a return from the entry-point is treated as
+            // exit (default for applications).
+            "/subsystem:efi_application",
+        ],
+    );
 
     TargetOptions {
         os: "uefi".into(),
diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs
index d8b6ae8cf32..024b10f2faa 100644
--- a/compiler/rustc_target/src/spec/base/windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs
@@ -6,19 +6,26 @@ use crate::spec::{
 };
 
 pub(crate) fn opts() -> TargetOptions {
-    let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        // Enable ASLR
-        "--dynamicbase",
-        // ASLR will rebase it anyway so leaving that option enabled only leads to confusion
-        "--disable-auto-image-base",
-    ]);
-    add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-        // Tell GCC to avoid linker plugins, because we are not bundling
-        // them with Windows installer, and Rust does its own LTO anyways.
-        "-fno-use-linker-plugin",
-        "-Wl,--dynamicbase",
-        "-Wl,--disable-auto-image-base",
-    ]);
+    let mut pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &[
+            // Enable ASLR
+            "--dynamicbase",
+            // ASLR will rebase it anyway so leaving that option enabled only leads to confusion
+            "--disable-auto-image-base",
+        ],
+    );
+    add_link_args(
+        &mut pre_link_args,
+        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        &[
+            // Tell GCC to avoid linker plugins, because we are not bundling
+            // them with Windows installer, and Rust does its own LTO anyways.
+            "-fno-use-linker-plugin",
+            "-Wl,--dynamicbase",
+            "-Wl,--disable-auto-image-base",
+        ],
+    );
 
     // Order of `late_link_args*` was found through trial and error to work with various
     // mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
index 86e52117dbf..4a6e7c75200 100644
--- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
@@ -7,18 +7,15 @@ pub(crate) fn opts() -> TargetOptions {
     // as a path since it's not added to linker search path by the default.
     // There were attempts to make it behave like libgcc (so one can just use -l<name>)
     // but LLVM maintainers rejected it: https://reviews.llvm.org/D51440
-    let pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-        "-nolibc",
-        "--unwindlib=none",
-    ]);
+    let pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        &["-nolibc", "--unwindlib=none"],
+    );
     // Order of `late_link_args*` does not matter with LLD.
-    let late_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-        "-lmingw32",
-        "-lmingwex",
-        "-lmsvcrt",
-        "-lkernel32",
-        "-luser32",
-    ]);
+    let late_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"],
+    );
 
     TargetOptions {
         os: "windows".into(),
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index a6b0ec072e8..f703132e51f 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -647,10 +647,10 @@ impl Target {
 
         // Each field should have been read using `Json::remove` so any keys remaining are unused.
         let remaining_keys = obj.keys();
-        Ok((base, TargetWarnings {
-            unused_fields: remaining_keys.cloned().collect(),
-            incorrect_type,
-        }))
+        Ok((
+            base,
+            TargetWarnings { unused_fields: remaining_keys.cloned().collect(), incorrect_type },
+        ))
     }
 }
 
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index e95c4dbd2cf..df1862ec27e 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -51,7 +51,7 @@ use rustc_span::{Symbol, kw, sym};
 use serde_json::Value;
 use tracing::debug;
 
-use crate::abi::call::Conv;
+use crate::callconv::Conv;
 use crate::json::{Json, ToJson};
 use crate::spec::crt_objects::CrtObjects;
 
@@ -1934,6 +1934,8 @@ supported_targets! {
 
     ("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda),
 
+    ("amdgcn-amd-amdhsa", amdgcn_amd_amdhsa),
+
     ("xtensa-esp32-none-elf", xtensa_esp32_none_elf),
     ("xtensa-esp32-espidf", xtensa_esp32_espidf),
     ("xtensa-esp32s2-none-elf", xtensa_esp32s2_none_elf),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
index 1511c0ccaad..de6fe991460 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
index e7070778794..8fdaff822fe 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
index f0f6e49eedd..4e1e95ab751 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
index 05fe32734a7..27dd713cc53 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
@@ -16,9 +16,10 @@ pub(crate) fn target() -> Target {
         linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
         linker: Some("rust-lld".into()),
         // Enable the Cortex-A53 errata 843419 mitigation by default
-        pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-            "--fix-cortex-a53-843419",
-        ]),
+        pre_link_args: TargetOptions::link_args(
+            LinkerFlavor::Gnu(Cc::No, Lld::No),
+            &["--fix-cortex-a53-843419"],
+        ),
         features: "+v8a,+strict-align,+neon,+fp-armv8".into(),
         supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
         relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs
index 582211b02b6..f7f8dc1e1ef 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs
@@ -16,9 +16,10 @@ pub(crate) fn target() -> Target {
         linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
         linker: Some("rust-lld".into()),
         // Enable the Cortex-A53 errata 843419 mitigation by default
-        pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-            "--fix-cortex-a53-843419",
-        ]),
+        pre_link_args: TargetOptions::link_args(
+            LinkerFlavor::Gnu(Cc::No, Lld::No),
+            &["--fix-cortex-a53-843419"],
+        ),
         features: "+v8a,+strict-align,+neon,+fp-armv8".into(),
         supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
         relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs
new file mode 100644
index 00000000000..bb488c350c2
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs
@@ -0,0 +1,51 @@
+use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, Target, TargetOptions};
+
+pub(crate) fn target() -> Target {
+    Target {
+        arch: "amdgpu".into(),
+        data_layout: "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9".into(),
+        llvm_target: "amdgcn-amd-amdhsa".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("AMD GPU".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 64,
+
+        options: TargetOptions {
+            os: "amdhsa".into(),
+            vendor: "amd".into(),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+
+            // There are many CPUs, one for each hardware generation.
+            // Require to set one explicitly as there is no good default.
+            need_explicit_cpu: true,
+
+            max_atomic_width: Some(64),
+
+            // Unwinding on GPUs is not useful.
+            panic_strategy: PanicStrategy::Abort,
+
+            // amdgpu backend does not support libcalls.
+            no_builtins: true,
+            simd_types_indirect: false,
+
+            // Allow `cdylib` crate type.
+            dynamic_linking: true,
+            only_cdylib: true,
+            executables: false,
+            dll_prefix: "".into(),
+            dll_suffix: ".elf".into(),
+
+            // The LLVM backend does not support stack canaries for this target
+            supports_stack_protector: false,
+
+            // Force LTO, object linking does not yet work with amdgpu.
+            requires_lto: true,
+
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
index 03c96fbfdb0..5026c52429e 100644
--- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
@@ -4,10 +4,11 @@ pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.max_atomic_width = Some(128);
     base.features = "+v8a,+neon,+fp-armv8".into();
-    add_link_args(&mut base.late_link_args, LinkerFlavor::Msvc(Lld::No), &[
-        "/machine:arm64ec",
-        "softintrin.lib",
-    ]);
+    add_link_args(
+        &mut base.late_link_args,
+        LinkerFlavor::Msvc(Lld::No),
+        &["/machine:arm64ec", "softintrin.lib"],
+    );
 
     Target {
         llvm_target: "arm64ec-pc-windows-msvc".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs
index bac9b39bbf2..60ec4edbb0d 100644
--- a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{FloatAbi, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs
index db774323e7b..18b93f6cbc4 100644
--- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs
@@ -1,6 +1,7 @@
 // Targets the Big endian Cortex-R4/R5 processor (ARMv7-R)
 
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{
     Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions,
 };
diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
index de006a92668..6c22cd34fc3 100644
--- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
@@ -1,6 +1,7 @@
 // Targets the Cortex-R4F/R5F processor (ARMv7-R)
 
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{
     Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions,
 };
diff --git a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs
index b323d2f8655..5438811803b 100644
--- a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs
+++ b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs
@@ -5,12 +5,10 @@ use crate::spec::{Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetOpt
 /// Requires the devkitARM toolchain for 3DS targets on the host system.
 
 pub(crate) fn target() -> Target {
-    let pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-        "-specs=3dsx.specs",
-        "-mtune=mpcore",
-        "-mfloat-abi=hard",
-        "-mtp=soft",
-    ]);
+    let pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        &["-specs=3dsx.specs", "-mtune=mpcore", "-mfloat-abi=hard", "-mtp=soft"],
+    );
 
     Target {
         llvm_target: "armv6k-none-eabihf".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
index 18d834597d8..4b2ab8b8f20 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetOptions, cvs};
 
 /// A base target for PlayStation Vita devices using the VITASDK toolchain (using newlib).
@@ -6,10 +7,10 @@ use crate::spec::{Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetOpt
 /// Requires the VITASDK toolchain on the host system.
 
 pub(crate) fn target() -> Target {
-    let pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-        "-Wl,-q",
-        "-Wl,--pic-veneer",
-    ]);
+    let pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        &["-Wl,-q", "-Wl,--pic-veneer"],
+    );
 
     Target {
         llvm_target: "thumbv7a-vita-eabihf".into(),
diff --git a/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs b/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs
index df0f29ceab2..b95f93c3553 100644
--- a/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs b/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs
index 691acf89d64..711bbb04b19 100644
--- a/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
index 9ef8e120e0d..208fe50912c 100644
--- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
@@ -9,11 +9,10 @@ pub(crate) fn target() -> Target {
 
     // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
     // space available to x86 Windows binaries on x86_64.
-    base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "-m",
-        "i386pe",
-        "--large-address-aware",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &["-m", "i386pe", "--large-address-aware"],
+    );
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]);
 
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs
index 13d3c5532ff..5df8dce1aa3 100644
--- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs
@@ -9,11 +9,10 @@ pub(crate) fn target() -> Target {
 
     // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
     // space available to x86 Windows binaries on x86_64.
-    base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "-m",
-        "i386pe",
-        "--large-address-aware",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &["-m", "i386pe", "--large-address-aware"],
+    );
 
     Target {
         llvm_target: "i686-pc-windows-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
index aacad266863..180750bc7a8 100644
--- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
@@ -6,15 +6,18 @@ pub(crate) fn target() -> Target {
     base.max_atomic_width = Some(64);
     base.supported_sanitizers = SanitizerSet::ADDRESS;
 
-    base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &[
-        // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
-        // space available to x86 Windows binaries on x86_64.
-        "/LARGEADDRESSAWARE",
-        // Ensure the linker will only produce an image if it can also produce a table of
-        // the image's safe exception handlers.
-        // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
-        "/SAFESEH",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Msvc(Lld::No),
+        &[
+            // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
+            // space available to x86 Windows binaries on x86_64.
+            "/LARGEADDRESSAWARE",
+            // Ensure the linker will only produce an image if it can also produce a table of
+            // the image's safe exception handlers.
+            // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
+            "/SAFESEH",
+        ],
+    );
 
     Target {
         llvm_target: "i686-pc-windows-msvc".into(),
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs
index 3961656d1b6..2f93e97d9fc 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs
@@ -2,7 +2,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::hurd_gnu::opts();
-    base.cpu = "pentiumpro".into();
+    base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
     base.stack_probes = StackProbeType::Inline;
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
index c1ed565f0fe..736b9131022 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
@@ -5,7 +5,7 @@
 // The cdecl ABI is used. It differs from the stdcall or fastcall ABI.
 // "i686-unknown-windows" is used to get the minimal subset of windows-specific features.
 
-use crate::spec::{RustcAbi, Target, base};
+use crate::spec::{LinkerFlavor, Lld, RustcAbi, Target, add_link_args, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::uefi_msvc::opts();
@@ -24,6 +24,13 @@ pub(crate) fn target() -> Target {
     base.features = "-mmx,-sse,+soft-float".into();
     base.rustc_abi = Some(RustcAbi::X86Softfloat);
 
+    // Turn off DWARF. This fixes an lld warning, "section name .debug_frame is longer than 8
+    // characters and will use a non-standard string table". That section will not be created if
+    // DWARF is disabled.
+    //
+    // This is only needed in the i686 target due to using the `-gnu` LLVM target (see below).
+    add_link_args(&mut base.post_link_args, LinkerFlavor::Msvc(Lld::No), &["/DEBUG:NODWARF"]);
+
     // Use -GNU here, because of the reason below:
     // Background and Problem:
     //   If we use i686-unknown-windows, the LLVM IA32 MSVC generates compiler intrinsic
diff --git a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs
index ffb9926e944..6e3733538ed 100644
--- a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs
@@ -8,11 +8,10 @@ pub(crate) fn target() -> Target {
 
     // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
     // space available to x86 Windows binaries on x86_64.
-    base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "-m",
-        "i386pe",
-        "--large-address-aware",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &["-m", "i386pe", "--large-address-aware"],
+    );
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]);
 
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs
index 086a799a68c..1d084c0729c 100644
--- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs
@@ -10,11 +10,10 @@ pub(crate) fn target() -> Target {
 
     // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
     // space available to x86 Windows binaries on x86_64.
-    base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "-m",
-        "i386pe",
-        "--large-address-aware",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &["-m", "i386pe", "--large-address-aware"],
+    );
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]);
 
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
index 173977b77bd..7efba3aa986 100644
--- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
@@ -7,15 +7,18 @@ pub(crate) fn target() -> Target {
     base.max_atomic_width = Some(64);
     base.supported_sanitizers = SanitizerSet::ADDRESS;
 
-    base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &[
-        // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
-        // space available to x86 Windows binaries on x86_64.
-        "/LARGEADDRESSAWARE",
-        // Ensure the linker will only produce an image if it can also produce a table of
-        // the image's safe exception handlers.
-        // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
-        "/SAFESEH",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Msvc(Lld::No),
+        &[
+            // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
+            // space available to x86 Windows binaries on x86_64.
+            "/LARGEADDRESSAWARE",
+            // Ensure the linker will only produce an image if it can also produce a table of
+            // the image's safe exception handlers.
+            // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
+            "/SAFESEH",
+        ],
+    );
 
     Target {
         llvm_target: "i686-pc-windows-msvc".into(),
diff --git a/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
index 47c6d805483..d3584a1be74 100644
--- a/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{LinkSelfContainedDefault, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs
index 6b8b7c6ae00..8b8693b55c5 100644
--- a/compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{CodeModel, PanicStrategy, RelocModel, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
index bddcc457498..4880e993722 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
@@ -1,6 +1,7 @@
 //! A target tuple for OpenWrt MIPS64 targets.
 
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
index 75da4abc6b6..daf6d5de4c0 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
index 32f5c79d653..03c8fa92450 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs b/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs
index 4637e31fb17..2815d995c31 100644
--- a/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs
index b9dc0d4a6ce..19cf62d19f6 100644
--- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
index 5076ae345a9..dbca90ba569 100644
--- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
index 36e61d55fa0..c26c7867ec7 100644
--- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs b/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs
index a89c0fce88c..f532643b56a 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs
index bf51d864372..2c63b0f2f38 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs
@@ -4,10 +4,10 @@ use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions, cvs}
 const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld");
 
 pub(crate) fn target() -> Target {
-    let pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "--emit-relocs",
-        "--nmagic",
-    ]);
+    let pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &["--emit-relocs", "--nmagic"],
+    );
 
     Target {
         llvm_target: "mipsel-sony-psp".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs
index e1adeb98ec2..400e05f1478 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs
index 3ef0988d235..c7b0a05d889 100644
--- a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
index d0d0ed1acc3..49bec90022c 100644
--- a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs
index edabbbf5f00..2125c95e266 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs
@@ -3,12 +3,10 @@ use crate::spec::{Cc, LinkerFlavor, Target, base};
 pub(crate) fn target() -> Target {
     let mut base = base::aix::opts();
     base.max_atomic_width = Some(64);
-    base.add_pre_link_args(LinkerFlavor::Unix(Cc::No), &[
-        "-b64",
-        "-bpT:0x100000000",
-        "-bpD:0x110000000",
-        "-bcdtors:all:0:s",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Unix(Cc::No),
+        &["-b64", "-bpT:0x100000000", "-bpD:0x110000000", "-bcdtors:all:0:s"],
+    );
 
     Target {
         llvm_target: "powerpc64-ibm-aix".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
index 4ccb3ee4664..201ab0d534f 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs
index 351ffa65eba..1a2f2125942 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
index a54b17c87a7..417c8b63c86 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs
index 31fbb141524..15947fdb0ac 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
index c37aa8d502a..d48c2f5e744 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs
index 9cfc2153ac1..d6a84f55f5e 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs
@@ -1,13 +1,14 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::freebsd::opts();
     // Extra hint to linker that we are generating secure-PLT code.
-    base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-        "-m32",
-        "--target=powerpc-unknown-freebsd13.0",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        &["-m32", "--target=powerpc-unknown-freebsd13.0"],
+    );
     base.max_atomic_width = Some(32);
     base.stack_probes = StackProbeType::Inline;
 
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs
index 1c537491a6c..6f3a2baf405 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs
index 4f5d9c661b0..c4d894823e6 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
index 0cd0ea96ad3..5b5fea666bb 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
index b86c3c2e8e0..dfd99635ddd 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs
index 142443aa5b1..7492077bb88 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs
index 7aedc2d0665..dd82a6a71cd 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{StackProbeType, Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
index 22b38208b10..c4f93c60d3e 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs
index ee61a7da41c..0284c50bd65 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
index a84a18a433f..41aa400f3e0 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{SanitizerSet, StackProbeType, Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
index fbe8c48eca7..61c01eba70d 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{SanitizerSet, StackProbeType, Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
index ac2141f9b08..3317fe51c33 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
index d16b3776cfb..4c2b971c0f1 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
index 91e64061020..81d7bf9a628 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
index 45941cd7c01..6abef79be96 100644
--- a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
@@ -17,9 +18,10 @@ pub(crate) fn target() -> Target {
             features: "+v8plus".into(),
             cpu: "v9".into(),
             endian: Endian::Big,
-            late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
-                "-mcpu=v9", "-m32",
-            ]),
+            late_link_args: TargetOptions::link_args(
+                LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+                &["-mcpu=v9", "-m32"],
+            ),
             max_atomic_width: Some(32),
             ..base::linux_gnu::opts()
         },
diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
index 987f69429c0..00cd7438f7e 100644
--- a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
index 770da60da9e..5b7d560a8e0 100644
--- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::{Cc, LinkerFlavor, Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs
index 96237f20891..bcf7b69fe74 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs
@@ -16,17 +16,23 @@ pub(crate) fn target() -> Target {
     let mut options = base::wasm::options();
     options.os = "unknown".into();
 
-    options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), &[
-        // For now this target just never has an entry symbol no matter the output
-        // type, so unconditionally pass this.
-        "--no-entry",
-    ]);
-    options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &[
-        // Make sure clang uses LLD as its linker and is configured appropriately
-        // otherwise
-        "--target=wasm32-unknown-unknown",
-        "-Wl,--no-entry",
-    ]);
+    options.add_pre_link_args(
+        LinkerFlavor::WasmLld(Cc::No),
+        &[
+            // For now this target just never has an entry symbol no matter the output
+            // type, so unconditionally pass this.
+            "--no-entry",
+        ],
+    );
+    options.add_pre_link_args(
+        LinkerFlavor::WasmLld(Cc::Yes),
+        &[
+            // Make sure clang uses LLD as its linker and is configured appropriately
+            // otherwise
+            "--target=wasm32-unknown-unknown",
+            "-Wl,--no-entry",
+        ],
+    );
 
     Target {
         llvm_target: "wasm32-unknown-unknown".into(),
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs
index 0c2e2bfeda6..2411d386f52 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs
@@ -15,17 +15,19 @@ pub(crate) fn target() -> Target {
     options.os = "wasi".into();
     options.env = "p1".into();
 
-    options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), &[
-        "--import-memory",
-        "--export-memory",
-        "--shared-memory",
-    ]);
-    options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &[
-        "--target=wasm32-wasip1-threads",
-        "-Wl,--import-memory",
-        "-Wl,--export-memory,",
-        "-Wl,--shared-memory",
-    ]);
+    options.add_pre_link_args(
+        LinkerFlavor::WasmLld(Cc::No),
+        &["--import-memory", "--export-memory", "--shared-memory"],
+    );
+    options.add_pre_link_args(
+        LinkerFlavor::WasmLld(Cc::Yes),
+        &[
+            "--target=wasm32-wasip1-threads",
+            "-Wl,--import-memory",
+            "-Wl,--export-memory,",
+            "-Wl,--shared-memory",
+        ],
+    );
 
     options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
     options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
diff --git a/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs b/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs
index 5c35e9c21d3..ab1dc21d125 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs
@@ -23,17 +23,23 @@ pub(crate) fn target() -> Target {
     options.cpu = "mvp".into();
     options.features = "+mutable-globals".into();
 
-    options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), &[
-        // For now this target just never has an entry symbol no matter the output
-        // type, so unconditionally pass this.
-        "--no-entry",
-    ]);
-    options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &[
-        // Make sure clang uses LLD as its linker and is configured appropriately
-        // otherwise
-        "--target=wasm32-unknown-unknown",
-        "-Wl,--no-entry",
-    ]);
+    options.add_pre_link_args(
+        LinkerFlavor::WasmLld(Cc::No),
+        &[
+            // For now this target just never has an entry symbol no matter the output
+            // type, so unconditionally pass this.
+            "--no-entry",
+        ],
+    );
+    options.add_pre_link_args(
+        LinkerFlavor::WasmLld(Cc::Yes),
+        &[
+            // Make sure clang uses LLD as its linker and is configured appropriately
+            // otherwise
+            "--target=wasm32-unknown-unknown",
+            "-Wl,--no-entry",
+        ],
+    );
 
     Target {
         llvm_target: "wasm32-unknown-unknown".into(),
diff --git a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs
index 22fa26d3cdb..596e26d1e9d 100644
--- a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs
@@ -13,18 +13,24 @@ pub(crate) fn target() -> Target {
     let mut options = base::wasm::options();
     options.os = "unknown".into();
 
-    options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), &[
-        // For now this target just never has an entry symbol no matter the output
-        // type, so unconditionally pass this.
-        "--no-entry",
-        "-mwasm64",
-    ]);
-    options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &[
-        // Make sure clang uses LLD as its linker and is configured appropriately
-        // otherwise
-        "--target=wasm64-unknown-unknown",
-        "-Wl,--no-entry",
-    ]);
+    options.add_pre_link_args(
+        LinkerFlavor::WasmLld(Cc::No),
+        &[
+            // For now this target just never has an entry symbol no matter the output
+            // type, so unconditionally pass this.
+            "--no-entry",
+            "-mwasm64",
+        ],
+    );
+    options.add_pre_link_args(
+        LinkerFlavor::WasmLld(Cc::Yes),
+        &[
+            // Make sure clang uses LLD as its linker and is configured appropriately
+            // otherwise
+            "--target=wasm64-unknown-unknown",
+            "-Wl,--no-entry",
+        ],
+    );
 
     // Any engine that implements wasm64 will surely implement the rest of these
     // features since they were all merged into the official spec by the time
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs
index 65c31634630..60d078371bb 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs
@@ -3,37 +3,40 @@ use std::borrow::Cow;
 use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, cvs};
 
 pub(crate) fn target() -> Target {
-    let pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "-e",
-        "elf_entry",
-        "-Bstatic",
-        "--gc-sections",
-        "-z",
-        "text",
-        "-z",
-        "norelro",
-        "--no-undefined",
-        "--error-unresolved-symbols",
-        "--no-undefined-version",
-        "-Bsymbolic",
-        "--export-dynamic",
-        // The following symbols are needed by libunwind, which is linked after
-        // libstd. Make sure they're included in the link.
-        "-u",
-        "__rust_abort",
-        "-u",
-        "__rust_c_alloc",
-        "-u",
-        "__rust_c_dealloc",
-        "-u",
-        "__rust_print_err",
-        "-u",
-        "__rust_rwlock_rdlock",
-        "-u",
-        "__rust_rwlock_unlock",
-        "-u",
-        "__rust_rwlock_wrlock",
-    ]);
+    let pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &[
+            "-e",
+            "elf_entry",
+            "-Bstatic",
+            "--gc-sections",
+            "-z",
+            "text",
+            "-z",
+            "norelro",
+            "--no-undefined",
+            "--error-unresolved-symbols",
+            "--no-undefined-version",
+            "-Bsymbolic",
+            "--export-dynamic",
+            // The following symbols are needed by libunwind, which is linked after
+            // libstd. Make sure they're included in the link.
+            "-u",
+            "__rust_abort",
+            "-u",
+            "__rust_c_alloc",
+            "-u",
+            "__rust_c_dealloc",
+            "-u",
+            "__rust_print_err",
+            "-u",
+            "__rust_rwlock_rdlock",
+            "-u",
+            "__rust_rwlock_unlock",
+            "-u",
+            "__rust_rwlock_wrlock",
+        ],
+    );
 
     const EXPORT_SYMBOLS: &[&str] = &[
         "sgx_entry",
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs
index e0ffcaf5a72..b10d4478d5e 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs
@@ -6,11 +6,10 @@ pub(crate) fn target() -> Target {
     base.features = "+cx16,+sse3,+sahf".into();
     base.plt_by_default = false;
     // Use high-entropy 64 bit address space for ASLR
-    base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "-m",
-        "i386pep",
-        "--high-entropy-va",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &["-m", "i386pep", "--high-entropy-va"],
+    );
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]);
     base.max_atomic_width = Some(128);
     base.linker = Some("x86_64-w64-mingw32-gcc".into());
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
index 8fd92e8123b..bce6aa0ebc6 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
@@ -5,7 +5,7 @@
 // The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
 // LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
 
-use crate::abi::call::Conv;
+use crate::callconv::Conv;
 use crate::spec::{RustcAbi, Target, base};
 
 pub(crate) fn target() -> Target {
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs
index fd10bc087ef..0ef41d315af 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs
@@ -6,11 +6,10 @@ pub(crate) fn target() -> Target {
     base.features = "+cx16,+sse3,+sahf".into();
     base.plt_by_default = false;
     // Use high-entropy 64 bit address space for ASLR
-    base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "-m",
-        "i386pep",
-        "--high-entropy-va",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &["-m", "i386pep", "--high-entropy-va"],
+    );
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]);
     base.max_atomic_width = Some(128);
 
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs
index d40df5a3e7d..8f903934a90 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs
@@ -6,11 +6,10 @@ pub(crate) fn target() -> Target {
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
     // Use high-entropy 64 bit address space for ASLR
-    base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
-        "-m",
-        "i386pep",
-        "--high-entropy-va",
-    ]);
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &["-m", "i386pep", "--high-entropy-va"],
+    );
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]);
     base.max_atomic_width = Some(64);
     base.linker = Some("x86_64-w64-mingw32-gcc".into());
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
index 442523aa397..b2a7c8551e4 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::base::xtensa;
 use crate::spec::{Target, TargetOptions, cvs};
 
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
index 353034df6f1..4fab2bac8e2 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::base::xtensa;
 use crate::spec::{Target, TargetOptions, cvs};
 
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
index a242f451c34..45d409a509f 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
@@ -1,4 +1,5 @@
-use crate::abi::Endian;
+use rustc_abi::Endian;
+
 use crate::spec::base::xtensa;
 use crate::spec::{Target, TargetOptions, cvs};
 
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index e423ca71dfc..ea7c15a3595 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -341,13 +341,17 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
     // FEAT_TME
     ("tme", Stable, &[]),
-    ("v8.1a", Unstable(sym::aarch64_ver_target_feature), &[
-        "crc", "lse", "rdm", "pan", "lor", "vh",
-    ]),
+    (
+        "v8.1a",
+        Unstable(sym::aarch64_ver_target_feature),
+        &["crc", "lse", "rdm", "pan", "lor", "vh"],
+    ),
     ("v8.2a", Unstable(sym::aarch64_ver_target_feature), &["v8.1a", "ras", "dpb"]),
-    ("v8.3a", Unstable(sym::aarch64_ver_target_feature), &[
-        "v8.2a", "rcpc", "paca", "pacg", "jsconv",
-    ]),
+    (
+        "v8.3a",
+        Unstable(sym::aarch64_ver_target_feature),
+        &["v8.2a", "rcpc", "paca", "pacg", "jsconv"],
+    ),
     ("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
     ("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
     ("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
index dfbef39e9e1..039e21cb556 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
@@ -323,9 +323,12 @@ pub fn suggest_new_region_bound(
                             .params
                             .iter()
                             .filter(|p| {
-                                matches!(p.kind, GenericParamKind::Lifetime {
-                                    kind: hir::LifetimeParamKind::Explicit
-                                })
+                                matches!(
+                                    p.kind,
+                                    GenericParamKind::Lifetime {
+                                        kind: hir::LifetimeParamKind::Explicit
+                                    }
+                                )
                             })
                             .map(|p| {
                                 if let hir::ParamName::Plain(name) = p.name {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 3128577776a..1b43820bac0 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1837,13 +1837,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 }
             }
             span.push_span_label(self.tcx.def_span(other_trait_def_id), "this is the found trait");
-            err.highlighted_span_note(span, vec![
-                StringPart::normal("there are ".to_string()),
-                StringPart::highlighted("multiple different versions".to_string()),
-                StringPart::normal(" of crate `".to_string()),
-                StringPart::highlighted(format!("{crate_name}")),
-                StringPart::normal("` in the dependency graph\n".to_string()),
-            ]);
+            err.highlighted_span_note(
+                span,
+                vec![
+                    StringPart::normal("there are ".to_string()),
+                    StringPart::highlighted("multiple different versions".to_string()),
+                    StringPart::normal(" of crate `".to_string()),
+                    StringPart::highlighted(format!("{crate_name}")),
+                    StringPart::normal("` in the dependency graph\n".to_string()),
+                ],
+            );
             if points_at_type {
                 // We only clarify that the same type from different crate versions are not the
                 // same when we *find* the same type coming from different crate versions, otherwise
@@ -2977,12 +2980,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     .inputs
                     .iter()
                     .map(|arg| match arg.kind {
-                        hir::TyKind::Tup(tys) => {
-                            ArgKind::Tuple(Some(arg.span), vec![
-                                ("_".to_owned(), "_".to_owned());
-                                tys.len()
-                            ])
-                        }
+                        hir::TyKind::Tup(tys) => ArgKind::Tuple(
+                            Some(arg.span),
+                            vec![("_".to_owned(), "_".to_owned()); tys.len()],
+                        ),
                         _ => ArgKind::empty(),
                     })
                     .collect::<Vec<ArgKind>>(),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index c194cc11727..527d2e54e43 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -640,10 +640,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     }
                     // Empty suggestions with empty spans ICE with debug assertions
                     if steps == 0 {
-                        return (msg.trim_end_matches(" and dereferencing instead"), vec![(
-                            prefix_span,
-                            String::new(),
-                        )]);
+                        return (
+                            msg.trim_end_matches(" and dereferencing instead"),
+                            vec![(prefix_span, String::new())],
+                        );
                     }
                     let derefs = "*".repeat(steps);
                     let needs_parens = steps > 0
@@ -3552,10 +3552,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
             ObligationCauseCode::TrivialBound => {
                 err.help("see issue #48214");
-                tcx.disabled_nightly_features(err, Some(tcx.local_def_id_to_hir_id(body_id)), [(
-                    String::new(),
-                    sym::trivial_bounds,
-                )]);
+                tcx.disabled_nightly_features(
+                    err,
+                    Some(tcx.local_def_id_to_hir_id(body_id)),
+                    [(String::new(), sym::trivial_bounds)],
+                );
             }
             ObligationCauseCode::OpaqueReturnType(expr_info) => {
                 let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
index 8edd623e5d0..7364b4aa343 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
@@ -153,10 +153,10 @@ fn find_best_leaf_obligation<'tcx>(
     infcx
         .fudge_inference_if_ok(|| {
             infcx
-                .visit_proof_tree(obligation.clone().into(), &mut BestObligation {
-                    obligation: obligation.clone(),
-                    consider_ambiguities,
-                })
+                .visit_proof_tree(
+                    obligation.clone().into(),
+                    &mut BestObligation { obligation: obligation.clone(), consider_ambiguities },
+                )
                 .break_value()
                 .ok_or(())
         })
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index a724705ffe9..232357dc71a 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -130,11 +130,12 @@ where
         self.depth += 1;
 
         let new_infer_ct = infcx.next_const_var(self.at.cause.span);
-        let obligation =
-            Obligation::new(tcx, self.at.cause.clone(), self.at.param_env, ty::NormalizesTo {
-                alias: uv.into(),
-                term: new_infer_ct.into(),
-            });
+        let obligation = Obligation::new(
+            tcx,
+            self.at.cause.clone(),
+            self.at.param_env,
+            ty::NormalizesTo { alias: uv.into(), term: new_infer_ct.into() },
+        );
 
         let result = if infcx.predicate_may_hold(&obligation) {
             self.fulfill_cx.register_predicate_obligation(infcx, obligation);
@@ -252,20 +253,20 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_,
     }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        deeply_normalize_with_skipped_universes(self.at, ty, vec![
-            None;
-            ty.outer_exclusive_binder()
-                .as_usize()
-        ])
+        deeply_normalize_with_skipped_universes(
+            self.at,
+            ty,
+            vec![None; ty.outer_exclusive_binder().as_usize()],
+        )
         .unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ty.super_fold_with(self))
     }
 
     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
-        deeply_normalize_with_skipped_universes(self.at, ct, vec![
-            None;
-            ct.outer_exclusive_binder()
-                .as_usize()
-        ])
+        deeply_normalize_with_skipped_universes(
+            self.at,
+            ct,
+            vec![None; ct.outer_exclusive_binder().as_usize()],
+        )
         .unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ct.super_fold_with(self))
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 7ee9eb45309..3b40882ef57 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -368,9 +368,10 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
                 overflowing_predicates: ambiguities
                     .into_iter()
                     .filter(|error| {
-                        matches!(error.code, FulfillmentErrorCode::Ambiguity {
-                            overflow: Some(true)
-                        })
+                        matches!(
+                            error.code,
+                            FulfillmentErrorCode::Ambiguity { overflow: Some(true) }
+                        )
                     })
                     .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate))
                     .collect(),
@@ -491,13 +492,16 @@ fn plug_infer_with_placeholders<'tcx>(
                         // Comparing against a type variable never registers hidden types anyway
                         DefineOpaqueTypes::Yes,
                         ty,
-                        Ty::new_placeholder(self.infcx.tcx, ty::Placeholder {
-                            universe: self.universe,
-                            bound: ty::BoundTy {
-                                var: self.next_var(),
-                                kind: ty::BoundTyKind::Anon,
+                        Ty::new_placeholder(
+                            self.infcx.tcx,
+                            ty::Placeholder {
+                                universe: self.universe,
+                                bound: ty::BoundTy {
+                                    var: self.next_var(),
+                                    kind: ty::BoundTyKind::Anon,
+                                },
                             },
-                        }),
+                        ),
                     )
                 else {
                     bug!("we always expect to be able to plug an infer var with placeholder")
@@ -517,10 +521,10 @@ fn plug_infer_with_placeholders<'tcx>(
                         // registration happening anyway.
                         DefineOpaqueTypes::Yes,
                         ct,
-                        ty::Const::new_placeholder(self.infcx.tcx, ty::Placeholder {
-                            universe: self.universe,
-                            bound: self.next_var(),
-                        }),
+                        ty::Const::new_placeholder(
+                            self.infcx.tcx,
+                            ty::Placeholder { universe: self.universe, bound: self.next_var() },
+                        ),
                     )
                 else {
                     bug!("we always expect to be able to plug an infer var with placeholder")
@@ -545,13 +549,16 @@ fn plug_infer_with_placeholders<'tcx>(
                             // Lifetimes don't contain opaque types (or any types for that matter).
                             DefineOpaqueTypes::Yes,
                             r,
-                            ty::Region::new_placeholder(self.infcx.tcx, ty::Placeholder {
-                                universe: self.universe,
-                                bound: ty::BoundRegion {
-                                    var: self.next_var(),
-                                    kind: ty::BoundRegionKind::Anon,
+                            ty::Region::new_placeholder(
+                                self.infcx.tcx,
+                                ty::Placeholder {
+                                    universe: self.universe,
+                                    bound: ty::BoundRegion {
+                                        var: self.next_var(),
+                                        kind: ty::BoundRegionKind::Anon,
+                                    },
                                 },
-                            }),
+                            ),
                         )
                     else {
                         bug!("we always expect to be able to plug an infer var with placeholder")
@@ -763,9 +770,9 @@ fn search_ambiguity_causes<'tcx>(
     causes: &mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
 ) {
     infcx.probe(|_| {
-        infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor {
-            cache: Default::default(),
-            causes,
-        })
+        infcx.visit_proof_tree(
+            goal,
+            &mut AmbiguityCausesVisitor { cache: Default::default(), causes },
+        )
     });
 }
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index d4a9664e282..105cb917571 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -660,13 +660,16 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
                     self.idx += 1;
                     idx
                 };
-                Ty::new_placeholder(self.tcx, ty::PlaceholderType {
-                    universe: ty::UniverseIndex::ROOT,
-                    bound: ty::BoundTy {
-                        var: ty::BoundVar::from_u32(idx),
-                        kind: ty::BoundTyKind::Anon,
+                Ty::new_placeholder(
+                    self.tcx,
+                    ty::PlaceholderType {
+                        universe: ty::UniverseIndex::ROOT,
+                        bound: ty::BoundTy {
+                            var: ty::BoundVar::from_u32(idx),
+                            kind: ty::BoundTyKind::Anon,
+                        },
                     },
-                })
+                )
             } else {
                 t.super_fold_with(self)
             }
@@ -674,14 +677,17 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
 
         fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
             if let ty::ConstKind::Infer(_) = c.kind() {
-                ty::Const::new_placeholder(self.tcx, ty::PlaceholderConst {
-                    universe: ty::UniverseIndex::ROOT,
-                    bound: ty::BoundVar::from_u32({
-                        let idx = self.idx;
-                        self.idx += 1;
-                        idx
-                    }),
-                })
+                ty::Const::new_placeholder(
+                    self.tcx,
+                    ty::PlaceholderConst {
+                        universe: ty::UniverseIndex::ROOT,
+                        bound: ty::BoundVar::from_u32({
+                            let idx = self.idx;
+                            self.idx += 1;
+                            idx
+                        }),
+                    },
+                )
             } else {
                 c.super_fold_with(self)
             }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 537b042bde5..de5aaa5bd97 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1670,14 +1670,18 @@ fn confirm_closure_candidate<'cx, 'tcx>(
                 } else {
                     let upvars_projection_def_id =
                         tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None);
-                    let tupled_upvars_ty = Ty::new_projection(tcx, upvars_projection_def_id, [
-                        ty::GenericArg::from(kind_ty),
-                        Ty::from_closure_kind(tcx, ty::ClosureKind::FnOnce).into(),
-                        tcx.lifetimes.re_static.into(),
-                        sig.tupled_inputs_ty.into(),
-                        args.tupled_upvars_ty().into(),
-                        args.coroutine_captures_by_ref_ty().into(),
-                    ]);
+                    let tupled_upvars_ty = Ty::new_projection(
+                        tcx,
+                        upvars_projection_def_id,
+                        [
+                            ty::GenericArg::from(kind_ty),
+                            Ty::from_closure_kind(tcx, ty::ClosureKind::FnOnce).into(),
+                            tcx.lifetimes.re_static.into(),
+                            sig.tupled_inputs_ty.into(),
+                            args.tupled_upvars_ty().into(),
+                            args.coroutine_captures_by_ref_ty().into(),
+                        ],
+                    );
                     sig.to_coroutine(
                         tcx,
                         args.parent_args(),
@@ -1795,14 +1799,18 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                         // will project to the right upvars for the generator, appending the inputs and
                         // coroutine upvars respecting the closure kind.
                         // N.B. No need to register a `AsyncFnKindHelper` goal here, it's already in `nested`.
-                        let tupled_upvars_ty = Ty::new_projection(tcx, upvars_projection_def_id, [
-                            ty::GenericArg::from(kind_ty),
-                            Ty::from_closure_kind(tcx, goal_kind).into(),
-                            env_region.into(),
-                            sig.tupled_inputs_ty.into(),
-                            args.tupled_upvars_ty().into(),
-                            args.coroutine_captures_by_ref_ty().into(),
-                        ]);
+                        let tupled_upvars_ty = Ty::new_projection(
+                            tcx,
+                            upvars_projection_def_id,
+                            [
+                                ty::GenericArg::from(kind_ty),
+                                Ty::from_closure_kind(tcx, goal_kind).into(),
+                                env_region.into(),
+                                sig.tupled_inputs_ty.into(),
+                                args.tupled_upvars_ty().into(),
+                                args.coroutine_captures_by_ref_ty().into(),
+                            ],
+                        );
                         sig.to_coroutine(
                             tcx,
                             args.parent_args(),
@@ -1816,17 +1824,16 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                 name => bug!("no such associated type: {name}"),
             };
             let projection_term = match item_name {
-                sym::CallOnceFuture | sym::Output => {
-                    ty::AliasTerm::new(tcx, obligation.predicate.def_id, [
-                        self_ty,
-                        sig.tupled_inputs_ty,
-                    ])
-                }
-                sym::CallRefFuture => ty::AliasTerm::new(tcx, obligation.predicate.def_id, [
-                    ty::GenericArg::from(self_ty),
-                    sig.tupled_inputs_ty.into(),
-                    env_region.into(),
-                ]),
+                sym::CallOnceFuture | sym::Output => ty::AliasTerm::new(
+                    tcx,
+                    obligation.predicate.def_id,
+                    [self_ty, sig.tupled_inputs_ty],
+                ),
+                sym::CallRefFuture => ty::AliasTerm::new(
+                    tcx,
+                    obligation.predicate.def_id,
+                    [ty::GenericArg::from(self_ty), sig.tupled_inputs_ty.into(), env_region.into()],
+                ),
                 name => bug!("no such associated type: {name}"),
             };
 
@@ -1846,17 +1853,20 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                 name => bug!("no such associated type: {name}"),
             };
             let projection_term = match item_name {
-                sym::CallOnceFuture | sym::Output => {
-                    ty::AliasTerm::new(tcx, obligation.predicate.def_id, [
-                        self_ty,
-                        Ty::new_tup(tcx, sig.inputs()),
-                    ])
-                }
-                sym::CallRefFuture => ty::AliasTerm::new(tcx, obligation.predicate.def_id, [
-                    ty::GenericArg::from(self_ty),
-                    Ty::new_tup(tcx, sig.inputs()).into(),
-                    env_region.into(),
-                ]),
+                sym::CallOnceFuture | sym::Output => ty::AliasTerm::new(
+                    tcx,
+                    obligation.predicate.def_id,
+                    [self_ty, Ty::new_tup(tcx, sig.inputs())],
+                ),
+                sym::CallRefFuture => ty::AliasTerm::new(
+                    tcx,
+                    obligation.predicate.def_id,
+                    [
+                        ty::GenericArg::from(self_ty),
+                        Ty::new_tup(tcx, sig.inputs()).into(),
+                        env_region.into(),
+                    ],
+                ),
                 name => bug!("no such associated type: {name}"),
             };
 
@@ -1879,11 +1889,11 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                 sym::CallOnceFuture | sym::Output => {
                     ty::AliasTerm::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]])
                 }
-                sym::CallRefFuture => ty::AliasTerm::new(tcx, obligation.predicate.def_id, [
-                    ty::GenericArg::from(self_ty),
-                    sig.inputs()[0].into(),
-                    env_region.into(),
-                ]),
+                sym::CallRefFuture => ty::AliasTerm::new(
+                    tcx,
+                    obligation.predicate.def_id,
+                    [ty::GenericArg::from(self_ty), sig.inputs()[0].into(), env_region.into()],
+                ),
                 name => bug!("no such associated type: {name}"),
             };
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 729ae3f2c2a..eb4adde716a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -301,11 +301,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             let make_transmute_obl = |src, dst| {
                 let transmute_trait = obligation.predicate.def_id();
                 let assume = obligation.predicate.skip_binder().trait_ref.args.const_at(2);
-                let trait_ref = ty::TraitRef::new(tcx, transmute_trait, [
-                    ty::GenericArg::from(dst),
-                    ty::GenericArg::from(src),
-                    ty::GenericArg::from(assume),
-                ]);
+                let trait_ref = ty::TraitRef::new(
+                    tcx,
+                    transmute_trait,
+                    [
+                        ty::GenericArg::from(dst),
+                        ty::GenericArg::from(src),
+                        ty::GenericArg::from(assume),
+                    ],
+                );
                 Obligation::with_depth(
                     tcx,
                     obligation.cause.clone(),
@@ -316,10 +320,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             };
 
             let make_freeze_obl = |ty| {
-                let trait_ref =
-                    ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Freeze, None), [
-                        ty::GenericArg::from(ty),
-                    ]);
+                let trait_ref = ty::TraitRef::new(
+                    tcx,
+                    tcx.require_lang_item(LangItem::Freeze, None),
+                    [ty::GenericArg::from(ty)],
+                );
                 Obligation::with_depth(
                     tcx,
                     obligation.cause.clone(),
@@ -863,10 +868,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
             ty::CoroutineClosure(_, args) => {
                 args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
-                    ty::TraitRef::new(self.tcx(), obligation.predicate.def_id(), [
-                        self_ty,
-                        sig.tupled_inputs_ty,
-                    ])
+                    ty::TraitRef::new(
+                        self.tcx(),
+                        obligation.predicate.def_id(),
+                        [self_ty, sig.tupled_inputs_ty],
+                    )
                 })
             }
             _ => {
@@ -892,10 +898,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::CoroutineClosure(_, args) => {
                 let args = args.as_coroutine_closure();
                 let trait_ref = args.coroutine_closure_sig().map_bound(|sig| {
-                    ty::TraitRef::new(self.tcx(), obligation.predicate.def_id(), [
-                        self_ty,
-                        sig.tupled_inputs_ty,
-                    ])
+                    ty::TraitRef::new(
+                        self.tcx(),
+                        obligation.predicate.def_id(),
+                        [self_ty, sig.tupled_inputs_ty],
+                    )
                 });
 
                 // Note that unlike below, we don't need to check `Future + Sized` for
@@ -906,10 +913,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::FnDef(..) | ty::FnPtr(..) => {
                 let sig = self_ty.fn_sig(tcx);
                 let trait_ref = sig.map_bound(|sig| {
-                    ty::TraitRef::new(self.tcx(), obligation.predicate.def_id(), [
-                        self_ty,
-                        Ty::new_tup(tcx, sig.inputs()),
-                    ])
+                    ty::TraitRef::new(
+                        self.tcx(),
+                        obligation.predicate.def_id(),
+                        [self_ty, Ty::new_tup(tcx, sig.inputs())],
+                    )
                 });
 
                 // We must additionally check that the return type impls `Future + Sized`.
@@ -934,10 +942,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let args = args.as_closure();
                 let sig = args.sig();
                 let trait_ref = sig.map_bound(|sig| {
-                    ty::TraitRef::new(self.tcx(), obligation.predicate.def_id(), [
-                        self_ty,
-                        sig.inputs()[0],
-                    ])
+                    ty::TraitRef::new(
+                        self.tcx(),
+                        obligation.predicate.def_id(),
+                        [self_ty, sig.inputs()[0]],
+                    )
                 });
 
                 // We must additionally check that the return type impls `Future + Sized`.
@@ -1295,10 +1304,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // Construct the nested `TailField<T>: Unsize<TailField<U>>` predicate.
                 let tail_unsize_obligation = obligation.with(
                     tcx,
-                    ty::TraitRef::new(tcx, obligation.predicate.def_id(), [
-                        source_tail,
-                        target_tail,
-                    ]),
+                    ty::TraitRef::new(
+                        tcx,
+                        obligation.predicate.def_id(),
+                        [source_tail, target_tail],
+                    ),
                 );
                 nested.push(tail_unsize_obligation);
 
@@ -1359,10 +1369,11 @@ fn pointer_like_goal_for_rpitit<'tcx>(
         ty::GenericParamDefKind::Lifetime => {
             let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id));
             bound_vars.push(ty::BoundVariableKind::Region(kind));
-            ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
-                var: ty::BoundVar::from_usize(bound_vars.len() - 1),
-                kind,
-            })
+            ty::Region::new_bound(
+                tcx,
+                ty::INNERMOST,
+                ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
+            )
             .into()
         }
         ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => {
@@ -1371,9 +1382,11 @@ fn pointer_like_goal_for_rpitit<'tcx>(
     });
 
     ty::Binder::bind_with_vars(
-        ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)), [
-            Ty::new_projection_from_args(tcx, rpitit_item, args),
-        ]),
+        ty::TraitRef::new(
+            tcx,
+            tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)),
+            [Ty::new_projection_from_args(tcx, rpitit_item, args)],
+        ),
         tcx.mk_bound_variable_kinds(&bound_vars),
     )
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 99ce1fd9fb4..6b1e1774f03 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2422,9 +2422,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 } else {
                     // If this is an ill-formed auto/built-in trait, then synthesize
                     // new error args for the missing generics.
-                    let err_args = ty::GenericArgs::extend_with_error(tcx, trait_def_id, &[
-                        normalized_ty.into(),
-                    ]);
+                    let err_args = ty::GenericArgs::extend_with_error(
+                        tcx,
+                        trait_def_id,
+                        &[normalized_ty.into()],
+                    );
                     ty::TraitRef::new_from_args(tcx, trait_def_id, err_args)
                 };
 
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index c4637f1293c..cc7baf8daac 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -79,10 +79,10 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
                         if matches!(*orig_lt, ty::ReLateParam(..)) {
                             mapping.insert(
                                 orig_lt,
-                                ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
-                                    index: param.index,
-                                    name: param.name,
-                                }),
+                                ty::Region::new_early_param(
+                                    tcx,
+                                    ty::EarlyParamRegion { index: param.index, name: param.name },
+                                ),
                             );
                         }
                     }
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 2f258b23f2d..ce8dc3a2515 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -240,14 +240,20 @@ fn layout_of_uncached<'tcx>(
         }
 
         // Basic scalars.
-        ty::Bool => tcx.mk_layout(LayoutData::scalar(cx, Scalar::Initialized {
-            value: Int(I8, false),
-            valid_range: WrappingRange { start: 0, end: 1 },
-        })),
-        ty::Char => tcx.mk_layout(LayoutData::scalar(cx, Scalar::Initialized {
-            value: Int(I32, false),
-            valid_range: WrappingRange { start: 0, end: 0x10FFFF },
-        })),
+        ty::Bool => tcx.mk_layout(LayoutData::scalar(
+            cx,
+            Scalar::Initialized {
+                value: Int(I8, false),
+                valid_range: WrappingRange { start: 0, end: 1 },
+            },
+        )),
+        ty::Char => tcx.mk_layout(LayoutData::scalar(
+            cx,
+            Scalar::Initialized {
+                value: Int(I32, false),
+                valid_range: WrappingRange { start: 0, end: 0x10FFFF },
+            },
+        )),
         ty::Int(ity) => scalar(Int(abi::Integer::from_int_ty(dl, ity), true)),
         ty::Uint(ity) => scalar(Int(abi::Integer::from_uint_ty(dl, ity), false)),
         ty::Float(fty) => scalar(Float(abi::Float::from_float_ty(fty))),
@@ -551,10 +557,13 @@ fn layout_of_uncached<'tcx>(
                 // Non-power-of-two vectors have padding up to the next power-of-two.
                 // If we're a packed repr, remove the padding while keeping the alignment as close
                 // to a vector as possible.
-                (BackendRepr::Memory { sized: true }, AbiAndPrefAlign {
-                    abi: Align::max_for_offset(size),
-                    pref: dl.vector_align(size).pref,
-                })
+                (
+                    BackendRepr::Memory { sized: true },
+                    AbiAndPrefAlign {
+                        abi: Align::max_for_offset(size),
+                        pref: dl.vector_align(size).pref,
+                    },
+                )
             } else {
                 (BackendRepr::Vector { element: e_abi, count: e_len }, dl.vector_align(size))
             };
@@ -1179,10 +1188,13 @@ fn variant_info_for_adt<'tcx>(
                 })
                 .collect();
 
-            (variant_infos, match tag_encoding {
-                TagEncoding::Direct => Some(tag.size(cx)),
-                _ => None,
-            })
+            (
+                variant_infos,
+                match tag_encoding {
+                    TagEncoding::Direct => Some(tag.size(cx)),
+                    _ => None,
+                },
+            )
         }
     }
 }
@@ -1302,8 +1314,11 @@ fn variant_info_for_coroutine<'tcx>(
     let end_states: Vec<_> = end_states.collect();
     variant_infos.extend(end_states);
 
-    (variant_infos, match tag_encoding {
-        TagEncoding::Direct => Some(tag.size(cx)),
-        _ => None,
-    })
+    (
+        variant_infos,
+        match tag_encoding {
+            TagEncoding::Direct => Some(tag.size(cx)),
+            _ => None,
+        },
+    )
 }
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index a6c72da0c56..aae2d2e96b9 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -141,6 +141,12 @@ pub trait Interner:
     type VariancesOf: Copy + Debug + SliceLike<Item = ty::Variance>;
     fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf;
 
+    fn opt_alias_variances(
+        self,
+        kind: impl Into<ty::AliasTermKind>,
+        def_id: Self::DefId,
+    ) -> Option<Self::VariancesOf>;
+
     fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;
 
     type AdtDef: AdtDef<Self>;
diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs
index c26e211a794..b09a378d341 100644
--- a/compiler/rustc_type_ir/src/outlives.rs
+++ b/compiler/rustc_type_ir/src/outlives.rs
@@ -148,7 +148,7 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
             // trait-ref. Therefore, if we see any higher-ranked regions,
             // we simply fallback to the most restrictive rule, which
             // requires that `Pi: 'a` for all `i`.
-            ty::Alias(_, alias_ty) => {
+            ty::Alias(kind, alias_ty) => {
                 if !alias_ty.has_escaping_bound_vars() {
                     // best case: no escaping regions, so push the
                     // projection and skip the subtree (thus generating no
@@ -162,7 +162,7 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
                     // OutlivesProjectionComponents. Continue walking
                     // through and constrain Pi.
                     let mut subcomponents = smallvec![];
-                    compute_alias_components_recursive(self.cx, ty, &mut subcomponents);
+                    compute_alias_components_recursive(self.cx, kind, alias_ty, &mut subcomponents);
                     self.out.push(Component::EscapingAlias(subcomponents.into_iter().collect()));
                 }
             }
@@ -217,21 +217,17 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
     }
 }
 
-/// Collect [Component]s for *all* the args of `parent`.
+/// Collect [Component]s for *all* the args of `alias_ty`.
 ///
-/// This should not be used to get the components of `parent` itself.
+/// This should not be used to get the components of `alias_ty` itself.
 /// Use [push_outlives_components] instead.
 pub fn compute_alias_components_recursive<I: Interner>(
     cx: I,
-    alias_ty: I::Ty,
+    kind: ty::AliasTyKind,
+    alias_ty: ty::AliasTy<I>,
     out: &mut SmallVec<[Component<I>; 4]>,
 ) {
-    let ty::Alias(kind, alias_ty) = alias_ty.kind() else {
-        unreachable!("can only call `compute_alias_components_recursive` on an alias type")
-    };
-
-    let opt_variances =
-        if kind == ty::Opaque { Some(cx.variances_of(alias_ty.def_id)) } else { None };
+    let opt_variances = cx.opt_alias_variances(kind, alias_ty.def_id);
 
     let mut visitor = OutlivesCollector { cx, out, visited: Default::default() };
 
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index 9a80f97e274..51790b13ec7 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -469,6 +469,17 @@ impl AliasTermKind {
     }
 }
 
+impl From<ty::AliasTyKind> for AliasTermKind {
+    fn from(value: ty::AliasTyKind) -> Self {
+        match value {
+            ty::Projection => AliasTermKind::ProjectionTy,
+            ty::Opaque => AliasTermKind::OpaqueTy,
+            ty::Weak => AliasTermKind::WeakTy,
+            ty::Inherent => AliasTermKind::InherentTy,
+        }
+    }
+}
+
 /// Represents the unprojected term of a projection goal.
 ///
 /// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
@@ -541,35 +552,29 @@ impl<I: Interner> AliasTerm<I> {
 
     pub fn to_term(self, interner: I) -> I::Term {
         match self.kind(interner) {
-            AliasTermKind::ProjectionTy => {
-                Ty::new_alias(interner, ty::AliasTyKind::Projection, ty::AliasTy {
-                    def_id: self.def_id,
-                    args: self.args,
-                    _use_alias_ty_new_instead: (),
-                })
-                .into()
-            }
-            AliasTermKind::InherentTy => {
-                Ty::new_alias(interner, ty::AliasTyKind::Inherent, ty::AliasTy {
-                    def_id: self.def_id,
-                    args: self.args,
-                    _use_alias_ty_new_instead: (),
-                })
-                .into()
-            }
-            AliasTermKind::OpaqueTy => {
-                Ty::new_alias(interner, ty::AliasTyKind::Opaque, ty::AliasTy {
-                    def_id: self.def_id,
-                    args: self.args,
-                    _use_alias_ty_new_instead: (),
-                })
-                .into()
-            }
-            AliasTermKind::WeakTy => Ty::new_alias(interner, ty::AliasTyKind::Weak, ty::AliasTy {
-                def_id: self.def_id,
-                args: self.args,
-                _use_alias_ty_new_instead: (),
-            })
+            AliasTermKind::ProjectionTy => Ty::new_alias(
+                interner,
+                ty::AliasTyKind::Projection,
+                ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
+            )
+            .into(),
+            AliasTermKind::InherentTy => Ty::new_alias(
+                interner,
+                ty::AliasTyKind::Inherent,
+                ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
+            )
+            .into(),
+            AliasTermKind::OpaqueTy => Ty::new_alias(
+                interner,
+                ty::AliasTyKind::Opaque,
+                ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
+            )
+            .into(),
+            AliasTermKind::WeakTy => Ty::new_alias(
+                interner,
+                ty::AliasTyKind::Weak,
+                ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
+            )
             .into(),
             AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
                 I::Const::new_unevaluated(
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index 5b696ee5ed4..d065384b58e 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -236,28 +236,14 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
                 ExpectedFound::new(a, b)
             }))
         } else {
-            let args = match a.kind(relation.cx()) {
-                ty::Opaque => relate_args_with_variances(
-                    relation,
-                    a.def_id,
-                    relation.cx().variances_of(a.def_id),
-                    a.args,
-                    b.args,
+            let cx = relation.cx();
+            let args = if let Some(variances) = cx.opt_alias_variances(a.kind(cx), a.def_id) {
+                relate_args_with_variances(
+                    relation, a.def_id, variances, a.args, b.args,
                     false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
-                )?,
-                ty::Projection if relation.cx().is_impl_trait_in_trait(a.def_id) => {
-                    relate_args_with_variances(
-                        relation,
-                        a.def_id,
-                        relation.cx().variances_of(a.def_id),
-                        a.args,
-                        b.args,
-                        false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
-                    )?
-                }
-                ty::Projection | ty::Weak | ty::Inherent => {
-                    relate_args_invariantly(relation, a.args, b.args)?
-                }
+                )?
+            } else {
+                relate_args_invariantly(relation, a.args, b.args)?
             };
             Ok(ty::AliasTy::new_from_args(relation.cx(), a.def_id, args))
         }
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs
index 74e4e035c87..d1ca9bdb7fb 100644
--- a/compiler/rustc_type_ir/src/ty_kind/closure.rs
+++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -399,15 +399,18 @@ impl<I: Interner> CoroutineClosureSignature<I> {
         coroutine_def_id: I::DefId,
         tupled_upvars_ty: I::Ty,
     ) -> I::Ty {
-        let coroutine_args = ty::CoroutineArgs::new(cx, ty::CoroutineArgsParts {
-            parent_args,
-            kind_ty: coroutine_kind_ty,
-            resume_ty: self.resume_ty,
-            yield_ty: self.yield_ty,
-            return_ty: self.return_ty,
-            witness: self.interior,
-            tupled_upvars_ty,
-        });
+        let coroutine_args = ty::CoroutineArgs::new(
+            cx,
+            ty::CoroutineArgsParts {
+                parent_args,
+                kind_ty: coroutine_kind_ty,
+                resume_ty: self.resume_ty,
+                yield_ty: self.yield_ty,
+                return_ty: self.return_ty,
+                witness: self.interior,
+                tupled_upvars_ty,
+            },
+        );
 
         Ty::new_coroutine(cx, coroutine_def_id, coroutine_args.args)
     }
diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs
index aaf69e2648d..ede6dcd469c 100644
--- a/compiler/rustc_type_ir_macros/src/lib.rs
+++ b/compiler/rustc_type_ir_macros/src/lib.rs
@@ -57,15 +57,18 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok
     });
     s.bind_with(|_| synstructure::BindStyle::Move);
 
-    s.bound_impl(quote!(::rustc_type_ir::visit::TypeVisitable<I>), quote! {
-        fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor<I>>(
-            &self,
-            __visitor: &mut __V
-        ) -> __V::Result {
-            match *self { #body_visit }
-            <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
-        }
-    })
+    s.bound_impl(
+        quote!(::rustc_type_ir::visit::TypeVisitable<I>),
+        quote! {
+            fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor<I>>(
+                &self,
+                __visitor: &mut __V
+            ) -> __V::Result {
+                match *self { #body_visit }
+                <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
+            }
+        },
+    )
 }
 
 fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
@@ -101,14 +104,17 @@ fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke
     // to generate code for them.
     s.filter(|bi| !has_ignore_attr(&bi.ast().attrs, "type_foldable", "identity"));
     s.add_bounds(synstructure::AddBounds::Fields);
-    s.bound_impl(quote!(::rustc_type_ir::fold::TypeFoldable<I>), quote! {
-        fn try_fold_with<__F: ::rustc_type_ir::fold::FallibleTypeFolder<I>>(
-            self,
-            __folder: &mut __F
-        ) -> Result<Self, __F::Error> {
-            Ok(match self { #body_fold })
-        }
-    })
+    s.bound_impl(
+        quote!(::rustc_type_ir::fold::TypeFoldable<I>),
+        quote! {
+            fn try_fold_with<__F: ::rustc_type_ir::fold::FallibleTypeFolder<I>>(
+                self,
+                __folder: &mut __F
+            ) -> Result<Self, __F::Error> {
+                Ok(match self { #body_fold })
+            }
+        },
+    )
 }
 
 fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
@@ -148,16 +154,19 @@ fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
     let self_ty: syn::Type = parse_quote! { #name #ty_generics };
     let lifted_ty = lift(self_ty);
 
-    s.bound_impl(quote!(::rustc_type_ir::lift::Lift<J>), quote! {
-        type Lifted = #lifted_ty;
+    s.bound_impl(
+        quote!(::rustc_type_ir::lift::Lift<J>),
+        quote! {
+            type Lifted = #lifted_ty;
 
-        fn lift_to_interner(
-            self,
-            interner: J,
-        ) -> Option<Self::Lifted> {
-            Some(match self { #body_fold })
-        }
-    })
+            fn lift_to_interner(
+                self,
+                interner: J,
+            ) -> Option<Self::Lifted> {
+                Some(match self { #body_fold })
+            }
+        },
+    )
 }
 
 fn lift(mut ty: syn::Type) -> syn::Type {
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index a6406e9db8e..bc2e427f50c 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -307,7 +307,7 @@ impl AssertMessage {
             AssertMessage::MisalignedPointerDereference { .. } => {
                 Ok("misaligned pointer dereference")
             }
-            AssertMessage::NullPointerDereference => Ok("null pointer dereference occured"),
+            AssertMessage::NullPointerDereference => Ok("null pointer dereference occurred"),
         }
     }
 }
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index 6638f93e555..8278afb7a2f 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -299,7 +299,7 @@ fn pretty_assert_message<W: Write>(writer: &mut W, msg: &AssertMessage) -> io::R
             )
         }
         AssertMessage::NullPointerDereference => {
-            write!(writer, "\"null pointer dereference occured.\"")
+            write!(writer, "\"null pointer dereference occurred\"")
         }
         AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
             write!(writer, "{}", msg.description().unwrap())
diff --git a/config.example.toml b/config.example.toml
index 04e7310e6bc..7f6bbf27992 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -108,7 +108,7 @@
 # the resulting rustc being unable to compile for the disabled architectures.
 #
 # To add support for new targets, see https://rustc-dev-guide.rust-lang.org/building/new-target.html.
-#targets = "AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
+#targets = "AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
 
 # LLVM experimental targets to build support for. These targets are specified in
 # the same format as above, but since these targets are experimental, they are
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 8b78908e6d7..930db2ecd57 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -61,9 +61,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.145"
+version = "0.1.146"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0705f5abaaab7168ccc14f8f340ded61be2bd3ebea86b9834b6acbc8495de8"
+checksum = "a97117b1434b79833f39a5fabdf82f890bd98c1988334dea1cb67f7e627fa311"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index db7eaf52fb2..6b0b5761391 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2021"
 
 [dependencies]
 core = { path = "../core" }
-compiler_builtins = { version = "=0.1.145", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
 rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index e9b7f985667..e686a02f29b 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -10,7 +10,7 @@ use core::hint;
 #[cfg(not(test))]
 use core::ptr::{self, NonNull};
 
-extern "Rust" {
+unsafe extern "Rust" {
     // These are the magic symbols to call the global allocator. rustc generates
     // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute
     // (the code expanding that attribute macro generates those functions), or to call
@@ -355,7 +355,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
 // # Allocation error handler
 
 #[cfg(not(no_global_oom_handling))]
-extern "Rust" {
+unsafe extern "Rust" {
     // This is the magic symbol to call the global alloc error handler. rustc generates
     // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the
     // default implementations below (`__rdl_oom`) otherwise.
@@ -426,7 +426,7 @@ pub mod __alloc_error_handler {
     // `#[alloc_error_handler]`.
     #[rustc_std_internal_symbol]
     pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! {
-        extern "Rust" {
+        unsafe extern "Rust" {
             // This symbol is emitted by rustc next to __rust_alloc_error_handler.
             // Its value depends on the -Zoom={panic,abort} compiler option.
             static __rust_alloc_error_handler_should_panic: u8;
diff --git a/library/alloc/src/collections/btree/merge_iter.rs b/library/alloc/src/collections/btree/merge_iter.rs
index c5b93d30a11..5077062e25d 100644
--- a/library/alloc/src/collections/btree/merge_iter.rs
+++ b/library/alloc/src/collections/btree/merge_iter.rs
@@ -74,7 +74,7 @@ impl<I: Iterator> MergeIterInner<I> {
                 b_next = self.b.next();
             }
         }
-        if let (Some(ref a1), Some(ref b1)) = (&a_next, &b_next) {
+        if let (Some(a1), Some(b1)) = (&a_next, &b_next) {
             match cmp(a1, b1) {
                 Ordering::Less => self.peeked = b_next.take().map(Peeked::B),
                 Ordering::Greater => self.peeked = a_next.take().map(Peeked::A),
diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs
index 990044e069f..d538ef707eb 100644
--- a/library/alloc/src/collections/btree/set/tests.rs
+++ b/library/alloc/src/collections/btree/set/tests.rs
@@ -132,9 +132,11 @@ fn test_difference() {
     check_difference(&[1, 3, 5, 9, 11], &[3, 6, 9], &[1, 5, 11]);
     check_difference(&[1, 3, 5, 9, 11], &[0, 1], &[3, 5, 9, 11]);
     check_difference(&[1, 3, 5, 9, 11], &[11, 12], &[1, 3, 5, 9]);
-    check_difference(&[-5, 11, 22, 33, 40, 42], &[-12, -5, 14, 23, 34, 38, 39, 50], &[
-        11, 22, 33, 40, 42,
-    ]);
+    check_difference(
+        &[-5, 11, 22, 33, 40, 42],
+        &[-12, -5, 14, 23, 34, 38, 39, 50],
+        &[11, 22, 33, 40, 42],
+    );
 
     if cfg!(miri) {
         // Miri is too slow
@@ -250,9 +252,11 @@ fn test_union() {
     check_union(&[], &[], &[]);
     check_union(&[1, 2, 3], &[2], &[1, 2, 3]);
     check_union(&[2], &[1, 2, 3], &[1, 2, 3]);
-    check_union(&[1, 3, 5, 9, 11, 16, 19, 24], &[-2, 1, 5, 9, 13, 19], &[
-        -2, 1, 3, 5, 9, 11, 13, 16, 19, 24,
-    ]);
+    check_union(
+        &[1, 3, 5, 9, 11, 16, 19, 24],
+        &[-2, 1, 5, 9, 13, 19],
+        &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24],
+    );
 }
 
 #[test]
diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs
index aa19239f6c5..812fe229a0f 100644
--- a/library/alloc/src/collections/linked_list/tests.rs
+++ b/library/alloc/src/collections/linked_list/tests.rs
@@ -696,9 +696,10 @@ fn test_cursor_mut_insert() {
     cursor.splice_after(p);
     cursor.splice_before(q);
     check_links(&m);
-    assert_eq!(m.iter().cloned().collect::<Vec<_>>(), &[
-        200, 201, 202, 203, 1, 100, 101, 102, 103, 8, 2, 3, 4, 5, 6
-    ]);
+    assert_eq!(
+        m.iter().cloned().collect::<Vec<_>>(),
+        &[200, 201, 202, 203, 1, 100, 101, 102, 103, 8, 2, 3, 4, 5, 6]
+    );
     let mut cursor = m.cursor_front_mut();
     cursor.move_prev();
     let tmp = cursor.split_before();
@@ -915,9 +916,10 @@ fn extract_if_complex() {
         assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
 
         assert_eq!(list.len(), 14);
-        assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![
-            1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39
-        ]);
+        assert_eq!(
+            list.into_iter().collect::<Vec<_>>(),
+            vec![1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]
+        );
     }
 
     {
@@ -932,9 +934,10 @@ fn extract_if_complex() {
         assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
 
         assert_eq!(list.len(), 13);
-        assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![
-            7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39
-        ]);
+        assert_eq!(
+            list.into_iter().collect::<Vec<_>>(),
+            vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]
+        );
     }
 
     {
@@ -949,9 +952,10 @@ fn extract_if_complex() {
         assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
 
         assert_eq!(list.len(), 11);
-        assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![
-            7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35
-        ]);
+        assert_eq!(
+            list.into_iter().collect::<Vec<_>>(),
+            vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35]
+        );
     }
 
     {
diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs
index 6328b3b4db8..c90679f1797 100644
--- a/library/alloc/src/collections/vec_deque/tests.rs
+++ b/library/alloc/src/collections/vec_deque/tests.rs
@@ -562,9 +562,10 @@ fn make_contiguous_head_to_end() {
         tester.push_front(i as char);
     }
 
-    assert_eq!(tester, [
-        'P', 'O', 'N', 'M', 'L', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'
-    ]);
+    assert_eq!(
+        tester,
+        ['P', 'O', 'N', 'M', 'L', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
+    );
 
     // ABCDEFGHIJKPONML
     let expected_start = 0;
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index c7d6d8a55c2..fd93045a5ac 100644
--- a/library/alloc/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -397,7 +397,7 @@ impl CString {
         // information about the size of the allocation is correct on Rust's
         // side.
         unsafe {
-            extern "C" {
+            unsafe extern "C" {
                 /// Provided by libc or compiler_builtins.
                 fn strlen(s: *const c_char) -> usize;
             }
@@ -965,8 +965,9 @@ impl Default for Rc<CStr> {
     /// This may or may not share an allocation with other Rcs on the same thread.
     #[inline]
     fn default() -> Self {
-        let c_str: &CStr = Default::default();
-        Rc::from(c_str)
+        let rc = Rc::<[u8]>::from(*b"\0");
+        // `[u8]` has the same layout as `CStr`, and it is `NUL` terminated.
+        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) }
     }
 }
 
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 0bb7c432cc3..1bb0f761064 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -156,7 +156,6 @@
 #![feature(unicode_internals)]
 #![feature(unsize)]
 #![feature(unwrap_infallible)]
-#![feature(vec_pop_if)]
 // tidy-alphabetical-end
 //
 // Language features:
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index ae3318b839d..09206c2f8b2 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1462,18 +1462,18 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
     /// Provides a raw pointer to the data.
     ///
     /// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
-    /// for as long there are strong counts in the `Rc`.
+    /// for as long as there are strong counts in the `Rc`.
     ///
     /// # Examples
     ///
     /// ```
     /// use std::rc::Rc;
     ///
-    /// let x = Rc::new("hello".to_owned());
+    /// let x = Rc::new(0);
     /// let y = Rc::clone(&x);
     /// let x_ptr = Rc::as_ptr(&x);
     /// assert_eq!(x_ptr, Rc::as_ptr(&y));
-    /// assert_eq!(unsafe { &*x_ptr }, "hello");
+    /// assert_eq!(unsafe { *x_ptr }, 0);
     /// ```
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     #[rustc_never_returns_null_ptr]
@@ -2350,11 +2350,10 @@ impl<T: Default> Default for Rc<T> {
     fn default() -> Rc<T> {
         unsafe {
             Self::from_inner(
-                Box::leak(Box::write(Box::new_uninit(), RcInner {
-                    strong: Cell::new(1),
-                    weak: Cell::new(1),
-                    value: T::default(),
-                }))
+                Box::leak(Box::write(
+                    Box::new_uninit(),
+                    RcInner { strong: Cell::new(1), weak: Cell::new(1), value: T::default() },
+                ))
                 .into(),
             )
         }
@@ -2369,7 +2368,9 @@ impl Default for Rc<str> {
     /// This may or may not share an allocation with other Rcs on the same thread.
     #[inline]
     fn default() -> Self {
-        Rc::from("")
+        let rc = Rc::<[u8]>::default();
+        // `[u8]` has the same layout as `str`.
+        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const str) }
     }
 }
 
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 431e19e6ef1..dba1449347a 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -3466,11 +3466,14 @@ impl<T: Default> Default for Arc<T> {
     fn default() -> Arc<T> {
         unsafe {
             Self::from_inner(
-                Box::leak(Box::write(Box::new_uninit(), ArcInner {
-                    strong: atomic::AtomicUsize::new(1),
-                    weak: atomic::AtomicUsize::new(1),
-                    data: T::default(),
-                }))
+                Box::leak(Box::write(
+                    Box::new_uninit(),
+                    ArcInner {
+                        strong: atomic::AtomicUsize::new(1),
+                        weak: atomic::AtomicUsize::new(1),
+                        data: T::default(),
+                    },
+                ))
                 .into(),
             )
         }
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 48afcf6e064..55cd0569538 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2519,8 +2519,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(vec_pop_if)]
-    ///
     /// let mut vec = vec![1, 2, 3, 4];
     /// let pred = |x: &mut i32| *x % 2 == 0;
     ///
@@ -2528,7 +2526,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert_eq!(vec, [1, 2, 3]);
     /// assert_eq!(vec.pop_if(pred), None);
     /// ```
-    #[unstable(feature = "vec_pop_if", issue = "122741")]
+    #[stable(feature = "vec_pop_if", since = "CURRENT_RUSTC_VERSION")]
     pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
         let last = self.last_mut()?;
         if predicate(last) { self.pop() } else { None }
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 391ff04a4b8..1bcec4037cd 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -37,7 +37,6 @@
 #![feature(local_waker)]
 #![feature(str_as_str)]
 #![feature(strict_provenance_lints)]
-#![feature(vec_pop_if)]
 #![feature(vec_deque_pop_if)]
 #![feature(unique_rc_arc)]
 #![feature(macro_metavar_expr_concat)]
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index 5720d3ffd97..23a0e5e5256 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -1524,18 +1524,14 @@ fn test_lines() {
     t("bare\r", &["bare\r"]);
     t("bare\rcr", &["bare\rcr"]);
     t("Text\n\r", &["Text", "\r"]);
-    t("\nMäry häd ä little lämb\n\r\nLittle lämb\n", &[
-        "",
-        "Märy häd ä little lämb",
-        "",
-        "Little lämb",
-    ]);
-    t("\r\nMäry häd ä little lämb\n\nLittle lämb", &[
-        "",
-        "Märy häd ä little lämb",
-        "",
-        "Little lämb",
-    ]);
+    t(
+        "\nMäry häd ä little lämb\n\r\nLittle lämb\n",
+        &["", "Märy häd ä little lämb", "", "Little lämb"],
+    );
+    t(
+        "\r\nMäry häd ä little lämb\n\nLittle lämb",
+        &["", "Märy häd ä little lämb", "", "Little lämb"],
+    );
 }
 
 #[test]
@@ -1978,73 +1974,88 @@ mod pattern {
         assert_eq!(v, right);
     }
 
-    make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
-        Reject(0, 1),
-        Match(1, 3),
-        Reject(3, 4),
-        Match(4, 6),
-        Reject(6, 7),
-    ]);
-    make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
-        Reject(0, 1),
-        Match(1, 3),
-        Reject(3, 4),
-        Match(4, 6),
-        Match(6, 8),
-        Reject(8, 9),
-    ]);
-    make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
-        Match(0, 0),
-        Reject(0, 1),
-        Match(1, 1),
-        Reject(1, 2),
-        Match(2, 2),
-        Reject(2, 3),
-        Match(3, 3),
-        Reject(3, 4),
-        Match(4, 4),
-        Reject(4, 5),
-        Match(5, 5),
-        Reject(5, 6),
-        Match(6, 6),
-        Reject(6, 7),
-        Match(7, 7),
-    ]);
-    make_test!(str_searcher_multibyte_haystack, " ", "├──", [
-        Reject(0, 3),
-        Reject(3, 6),
-        Reject(6, 9),
-    ]);
-    make_test!(str_searcher_empty_needle_multibyte_haystack, "", "├──", [
-        Match(0, 0),
-        Reject(0, 3),
-        Match(3, 3),
-        Reject(3, 6),
-        Match(6, 6),
-        Reject(6, 9),
-        Match(9, 9),
-    ]);
+    make_test!(
+        str_searcher_ascii_haystack,
+        "bb",
+        "abbcbbd",
+        [Reject(0, 1), Match(1, 3), Reject(3, 4), Match(4, 6), Reject(6, 7),]
+    );
+    make_test!(
+        str_searcher_ascii_haystack_seq,
+        "bb",
+        "abbcbbbbd",
+        [Reject(0, 1), Match(1, 3), Reject(3, 4), Match(4, 6), Match(6, 8), Reject(8, 9),]
+    );
+    make_test!(
+        str_searcher_empty_needle_ascii_haystack,
+        "",
+        "abbcbbd",
+        [
+            Match(0, 0),
+            Reject(0, 1),
+            Match(1, 1),
+            Reject(1, 2),
+            Match(2, 2),
+            Reject(2, 3),
+            Match(3, 3),
+            Reject(3, 4),
+            Match(4, 4),
+            Reject(4, 5),
+            Match(5, 5),
+            Reject(5, 6),
+            Match(6, 6),
+            Reject(6, 7),
+            Match(7, 7),
+        ]
+    );
+    make_test!(
+        str_searcher_multibyte_haystack,
+        " ",
+        "├──",
+        [Reject(0, 3), Reject(3, 6), Reject(6, 9),]
+    );
+    make_test!(
+        str_searcher_empty_needle_multibyte_haystack,
+        "",
+        "├──",
+        [
+            Match(0, 0),
+            Reject(0, 3),
+            Match(3, 3),
+            Reject(3, 6),
+            Match(6, 6),
+            Reject(6, 9),
+            Match(9, 9),
+        ]
+    );
     make_test!(str_searcher_empty_needle_empty_haystack, "", "", [Match(0, 0),]);
     make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", []);
-    make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
-        Reject(0, 1),
-        Match(1, 2),
-        Match(2, 3),
-        Reject(3, 4),
-        Match(4, 5),
-        Match(5, 6),
-        Reject(6, 7),
-    ]);
-    make_test!(char_searcher_multibyte_haystack, ' ', "├──", [
-        Reject(0, 3),
-        Reject(3, 6),
-        Reject(6, 9),
-    ]);
-    make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
-        Reject(0, 1),
-        Reject(1, 2),
-        Reject(2, 3),
-    ]);
+    make_test!(
+        char_searcher_ascii_haystack,
+        'b',
+        "abbcbbd",
+        [
+            Reject(0, 1),
+            Match(1, 2),
+            Match(2, 3),
+            Reject(3, 4),
+            Match(4, 5),
+            Match(5, 6),
+            Reject(6, 7),
+        ]
+    );
+    make_test!(
+        char_searcher_multibyte_haystack,
+        ' ',
+        "├──",
+        [Reject(0, 3), Reject(3, 6), Reject(6, 9),]
+    );
+    make_test!(
+        char_searcher_short_haystack,
+        '\u{1F4A9}',
+        "* \t",
+        [Reject(0, 1), Reject(1, 2), Reject(2, 3),]
+    );
 
     // See #85462
     #[test]
diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs
index 1c8bff1564d..d996c55f946 100644
--- a/library/alloc/tests/string.rs
+++ b/library/alloc/tests/string.rs
@@ -154,19 +154,28 @@ fn test_fromutf8error_into_lossy() {
 #[test]
 fn test_from_utf16() {
     let pairs = [
-        (String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"), vec![
-            0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800, 0xdf39, 0xd800,
-            0xdf3b, 0xd800, 0xdf30, 0x000a,
-        ]),
-        (String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"), vec![
-            0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801, 0xdc32, 0xd801,
-            0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801, 0xdc4d, 0x000a,
-        ]),
-        (String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"), vec![
-            0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800, 0xdf11, 0xd800,
-            0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800, 0xdf15, 0xd800, 0xdf04, 0xd800,
-            0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11, 0x000a,
-        ]),
+        (
+            String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
+            vec![
+                0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800, 0xdf39,
+                0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a,
+            ],
+        ),
+        (
+            String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
+            vec![
+                0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801, 0xdc32,
+                0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801, 0xdc4d, 0x000a,
+            ],
+        ),
+        (
+            String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
+            vec![
+                0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800, 0xdf11,
+                0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800, 0xdf15, 0xd800,
+                0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11, 0x000a,
+            ],
+        ),
         (
             String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
             vec![
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 320d8176011..cbf00106c51 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1590,10 +1590,10 @@ impl<'b, T: ?Sized> Ref<'b, T> {
     {
         let (a, b) = f(&*orig);
         let borrow = orig.borrow.clone();
-        (Ref { value: NonNull::from(a), borrow }, Ref {
-            value: NonNull::from(b),
-            borrow: orig.borrow,
-        })
+        (
+            Ref { value: NonNull::from(a), borrow },
+            Ref { value: NonNull::from(b), borrow: orig.borrow },
+        )
     }
 
     /// Converts into a reference to the underlying data.
@@ -1758,11 +1758,10 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
     {
         let borrow = orig.borrow.clone();
         let (a, b) = f(&mut *orig);
-        (RefMut { value: NonNull::from(a), borrow, marker: PhantomData }, RefMut {
-            value: NonNull::from(b),
-            borrow: orig.borrow,
-            marker: PhantomData,
-        })
+        (
+            RefMut { value: NonNull::from(a), borrow, marker: PhantomData },
+            RefMut { value: NonNull::from(b), borrow: orig.borrow, marker: PhantomData },
+        )
     }
 
     /// Converts into a mutable reference to the underlying data.
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 7180593edf0..75338e492ee 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -731,7 +731,7 @@ const unsafe fn strlen(ptr: *const c_char) -> usize {
 
             len
         } else {
-            extern "C" {
+            unsafe extern "C" {
                 /// Provided by libc or compiler_builtins.
                 fn strlen(s: *const c_char) -> usize;
             }
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index 50968c57adc..9bae5fd466a 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -90,4 +90,4 @@ impl fmt::Debug for c_void {
     cfg(not(target_feature = "crt-static"))
 )]
 #[link(name = "/defaultlib:libcmt", modifiers = "+verbatim", cfg(target_feature = "crt-static"))]
-extern "C" {}
+unsafe extern "C" {}
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 3b249c835f2..6c9c6d0edc2 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -4855,7 +4855,7 @@ pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128 {
 #[cfg(miri)]
 #[rustc_allow_const_fn_unstable(const_eval_select)]
 pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize) {
-    extern "Rust" {
+    unsafe extern "Rust" {
         /// Miri-provided extern function to promise that a given pointer is properly aligned for
         /// "symbolic" alignment checks. Will fail if the pointer is not actually aligned or `align` is
         /// not a power of two. Has no effect when alignment checks are concrete (which is the default).
diff --git a/library/core/src/iter/sources/once_with.rs b/library/core/src/iter/sources/once_with.rs
index 8b31ab2ff90..c9698b4fd43 100644
--- a/library/core/src/iter/sources/once_with.rs
+++ b/library/core/src/iter/sources/once_with.rs
@@ -58,8 +58,8 @@ use crate::iter::{FusedIterator, TrustedLen};
 /// ```
 #[inline]
 #[stable(feature = "iter_once_with", since = "1.43.0")]
-pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
-    OnceWith { gen: Some(gen) }
+pub fn once_with<A, F: FnOnce() -> A>(make: F) -> OnceWith<F> {
+    OnceWith { make: Some(make) }
 }
 
 /// An iterator that yields a single element of type `A` by
@@ -70,13 +70,13 @@ pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
 #[derive(Clone)]
 #[stable(feature = "iter_once_with", since = "1.43.0")]
 pub struct OnceWith<F> {
-    gen: Option<F>,
+    make: Option<F>,
 }
 
 #[stable(feature = "iter_once_with_debug", since = "1.68.0")]
 impl<F> fmt::Debug for OnceWith<F> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if self.gen.is_some() {
+        if self.make.is_some() {
             f.write_str("OnceWith(Some(_))")
         } else {
             f.write_str("OnceWith(None)")
@@ -90,13 +90,13 @@ impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        let f = self.gen.take()?;
+        let f = self.make.take()?;
         Some(f())
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        self.gen.iter().size_hint()
+        self.make.iter().size_hint()
     }
 }
 
@@ -110,7 +110,7 @@ impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
 #[stable(feature = "iter_once_with", since = "1.43.0")]
 impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
     fn len(&self) -> usize {
-        self.gen.iter().len()
+        self.make.iter().len()
     }
 }
 
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 91c3a4b29b5..42886e90f99 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -3493,7 +3493,8 @@ pub trait Iterator {
     ///
     /// Takes each element, adds them together, and returns the result.
     ///
-    /// An empty iterator returns the zero value of the type.
+    /// An empty iterator returns the *additive identity* ("zero") of the type,
+    /// which is `0` for integers and `-0.0` for floats.
     ///
     /// `sum()` can be used to sum any type implementing [`Sum`][`core::iter::Sum`],
     /// including [`Option`][`Option::sum`] and [`Result`][`Result::sum`].
@@ -3511,6 +3512,10 @@ pub trait Iterator {
     /// let sum: i32 = a.iter().sum();
     ///
     /// assert_eq!(sum, 6);
+    ///
+    /// let b: Vec<f32> = vec![];
+    /// let sum: f32 = b.iter().sum();
+    /// assert_eq!(sum, -0.0_f32);
     /// ```
     #[stable(feature = "iter_arith", since = "1.11.0")]
     fn sum<S>(self) -> S
diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs
index c90ae7babbd..6be42ca7d32 100644
--- a/library/core/src/ops/async_function.rs
+++ b/library/core/src/ops/async_function.rs
@@ -6,7 +6,6 @@ use crate::marker::Tuple;
 /// All `async fn` and functions returning futures implement this trait.
 #[stable(feature = "async_closure", since = "1.85.0")]
 #[rustc_paren_sugar]
-#[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
 #[lang = "async_fn"]
 pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
@@ -20,7 +19,6 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
 /// All `async fn` and functions returning futures implement this trait.
 #[stable(feature = "async_closure", since = "1.85.0")]
 #[rustc_paren_sugar]
-#[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
 #[lang = "async_fn_mut"]
 pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
@@ -41,7 +39,6 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
 /// All `async fn` and functions returning futures implement this trait.
 #[stable(feature = "async_closure", since = "1.85.0")]
 #[rustc_paren_sugar]
-#[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
 #[lang = "async_fn_once"]
 pub trait AsyncFnOnce<Args: Tuple> {
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index a89de12c02b..d36e677d21a 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -59,7 +59,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
 
     // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
     // that gets resolved to the `#[panic_handler]` function.
-    extern "Rust" {
+    unsafe extern "Rust" {
         #[lang = "panic_impl"]
         fn panic_impl(pi: &PanicInfo<'_>) -> !;
     }
@@ -100,7 +100,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
 
             // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
             // that gets resolved to the `#[panic_handler]` function.
-            extern "Rust" {
+            unsafe extern "Rust" {
                 #[lang = "panic_impl"]
                 fn panic_impl(pi: &PanicInfo<'_>) -> !;
             }
@@ -302,7 +302,7 @@ fn panic_null_pointer_dereference() -> ! {
     }
 
     panic_nounwind_fmt(
-        format_args!("null pointer dereference occured"),
+        format_args!("null pointer dereference occurred"),
         /* force_no_backtrace */ false,
     )
 }
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index e93b5658e24..9eee29d485f 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -155,7 +155,7 @@ pub struct DynMetadata<Dyn: ?Sized> {
     _phantom: crate::marker::PhantomData<Dyn>,
 }
 
-extern "C" {
+unsafe extern "C" {
     /// Opaque type for accessing vtables.
     ///
     /// Private implementation detail of `DynMetadata::size_of` etc.
diff --git a/library/coretests/tests/iter/adapters/map_windows.rs b/library/coretests/tests/iter/adapters/map_windows.rs
index b677f1cfd55..01cebc9b27f 100644
--- a/library/coretests/tests/iter/adapters/map_windows.rs
+++ b/library/coretests/tests/iter/adapters/map_windows.rs
@@ -159,11 +159,10 @@ fn output_n2() {
         <Vec<[char; 2]>>::new(),
     );
     assert_eq!("ab".chars().map_windows(|a: &[_; 2]| *a).collect::<Vec<_>>(), vec![['a', 'b']]);
-    assert_eq!("abcd".chars().map_windows(|a: &[_; 2]| *a).collect::<Vec<_>>(), vec![
-        ['a', 'b'],
-        ['b', 'c'],
-        ['c', 'd']
-    ],);
+    assert_eq!(
+        "abcd".chars().map_windows(|a: &[_; 2]| *a).collect::<Vec<_>>(),
+        vec![['a', 'b'], ['b', 'c'], ['c', 'd']],
+    );
 }
 
 #[test]
diff --git a/library/coretests/tests/mem.rs b/library/coretests/tests/mem.rs
index 1b5c5fc82a6..9cb94ca3b0f 100644
--- a/library/coretests/tests/mem.rs
+++ b/library/coretests/tests/mem.rs
@@ -648,7 +648,7 @@ fn offset_of_dst() {
         z: dyn Trait,
     }
 
-    extern "C" {
+    unsafe extern "C" {
         type Extern;
     }
 
diff --git a/library/coretests/tests/num/flt2dec/mod.rs b/library/coretests/tests/num/flt2dec/mod.rs
index 3d825224813..6041923117c 100644
--- a/library/coretests/tests/num/flt2dec/mod.rs
+++ b/library/coretests/tests/num/flt2dec/mod.rs
@@ -80,7 +80,7 @@ fn ldexp_f32(a: f32, b: i32) -> f32 {
 }
 
 fn ldexp_f64(a: f64, b: i32) -> f64 {
-    extern "C" {
+    unsafe extern "C" {
         fn ldexp(x: f64, n: i32) -> f64;
     }
     // SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs
index 345bec345d1..0c9f9b338b0 100644
--- a/library/coretests/tests/ptr.rs
+++ b/library/coretests/tests/ptr.rs
@@ -97,7 +97,7 @@ fn test_is_null() {
     let nmi: *mut dyn ToString = null_mut::<isize>();
     assert!(nmi.is_null());
 
-    extern "C" {
+    unsafe extern "C" {
         type Extern;
     }
     let ec: *const Extern = null::<Extern>();
@@ -308,7 +308,7 @@ fn test_const_nonnull_new() {
 pub fn test_variadic_fnptr() {
     use core::ffi;
     use core::hash::{Hash, SipHasher};
-    extern "C" {
+    unsafe extern "C" {
         // This needs to use the correct function signature even though it isn't called as some
         // codegen backends make it UB to declare a function with multiple conflicting signatures
         // (like LLVM) while others straight up return an error (like Cranelift).
@@ -506,7 +506,7 @@ fn offset_from() {
 fn ptr_metadata() {
     struct Unit;
     struct Pair<A, B: ?Sized>(A, B);
-    extern "C" {
+    unsafe extern "C" {
         type Extern;
     }
     let () = metadata(&());
diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index dc2b42bb90a..7718d68aef8 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -54,7 +54,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
         ))] {
             unsafe fn abort() -> ! {
                 // call std::sys::abort_internal
-                extern "C" {
+                unsafe extern "C" {
                     pub fn __rust_abort() -> !;
                 }
                 __rust_abort();
@@ -87,7 +87,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
             }
         } else if #[cfg(target_os = "teeos")] {
             mod teeos {
-                extern "C" {
+                unsafe extern "C" {
                     pub fn TEE_Panic(code: u32) -> !;
                 }
             }
diff --git a/library/panic_abort/src/zkvm.rs b/library/panic_abort/src/zkvm.rs
index a6a02abf109..11150eafd0b 100644
--- a/library/panic_abort/src/zkvm.rs
+++ b/library/panic_abort/src/zkvm.rs
@@ -16,7 +16,7 @@ pub(crate) unsafe fn zkvm_set_abort_message(payload: &mut dyn PanicPayload) {
         return;
     }
 
-    extern "C" {
+    unsafe extern "C" {
         fn sys_panic(msg_ptr: *const u8, len: usize) -> !;
     }
 
diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs
index 9127449edb1..4140b004ad1 100644
--- a/library/panic_unwind/src/emcc.rs
+++ b/library/panic_unwind/src/emcc.rs
@@ -21,7 +21,7 @@ struct TypeInfo {
 }
 unsafe impl Sync for TypeInfo {}
 
-extern "C" {
+unsafe extern "C" {
     // The leading `\x01` byte here is actually a magical signal to LLVM to
     // *not* apply any other mangling like prefixing with a `_` character.
     //
@@ -98,11 +98,14 @@ pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     if exception.is_null() {
         return uw::_URC_FATAL_PHASE1_ERROR as u32;
     }
-    ptr::write(exception, Exception {
-        canary: &EXCEPTION_TYPE_INFO,
-        caught: AtomicBool::new(false),
-        data: Some(data),
-    });
+    ptr::write(
+        exception,
+        Exception {
+            canary: &EXCEPTION_TYPE_INFO,
+            caught: AtomicBool::new(false),
+            data: Some(data),
+        },
+    );
     __cxa_throw(exception as *mut _, &EXCEPTION_TYPE_INFO, exception_cleanup);
 }
 
@@ -116,7 +119,7 @@ extern "C" fn exception_cleanup(ptr: *mut libc::c_void) -> *mut libc::c_void {
     }
 }
 
-extern "C" {
+unsafe extern "C" {
     fn __cxa_allocate_exception(thrown_size: libc::size_t) -> *mut libc::c_void;
     fn __cxa_begin_catch(thrown_exception: *mut libc::c_void) -> *mut libc::c_void;
     fn __cxa_end_catch();
diff --git a/library/panic_unwind/src/hermit.rs b/library/panic_unwind/src/hermit.rs
index 7e08ad66577..9719c133415 100644
--- a/library/panic_unwind/src/hermit.rs
+++ b/library/panic_unwind/src/hermit.rs
@@ -6,14 +6,14 @@ use alloc::boxed::Box;
 use core::any::Any;
 
 pub(crate) unsafe fn cleanup(_ptr: *mut u8) -> Box<dyn Any + Send> {
-    extern "C" {
+    unsafe extern "C" {
         fn __rust_abort() -> !;
     }
     __rust_abort();
 }
 
 pub(crate) unsafe fn panic(_data: Box<dyn Any + Send>) -> u32 {
-    extern "C" {
+    unsafe extern "C" {
         fn __rust_abort() -> !;
     }
     __rust_abort();
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index d6828164195..45e2a466b4d 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -75,7 +75,7 @@ cfg_if::cfg_if! {
     }
 }
 
-extern "C" {
+unsafe extern "C" {
     /// Handler in std called when a panic object is dropped outside of
     /// `catch_unwind`.
     fn __rust_drop_panic() -> !;
diff --git a/library/panic_unwind/src/miri.rs b/library/panic_unwind/src/miri.rs
index a86f0e91eef..ec48b1105ab 100644
--- a/library/panic_unwind/src/miri.rs
+++ b/library/panic_unwind/src/miri.rs
@@ -7,7 +7,7 @@ use core::any::Any;
 // Must be pointer-sized.
 type Payload = Box<Box<dyn Any + Send>>;
 
-extern "Rust" {
+unsafe extern "Rust" {
     /// Miri-provided extern function to begin unwinding.
     fn miri_start_unwind(payload: *mut u8) -> !;
 }
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 21bfe74e1a2..c8dfddf821e 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -135,7 +135,7 @@ mod imp {
     #[derive(Copy, Clone)]
     pub(super) struct ptr_t(u32);
 
-    extern "C" {
+    unsafe extern "C" {
         static __ImageBase: u8;
     }
 
@@ -229,7 +229,7 @@ static mut CATCHABLE_TYPE: _CatchableType = _CatchableType {
     copyFunction: ptr_t::null(),
 };
 
-extern "C" {
+unsafe extern "C" {
     // The leading `\x01` byte here is actually a magical signal to LLVM to
     // *not* apply any other mangling like prefixing with a `_` character.
     //
@@ -343,7 +343,7 @@ pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
         ptr_t::new(exception_copy as *mut u8).raw(),
     );
 
-    extern "system-unwind" {
+    unsafe extern "system-unwind" {
         fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8) -> !;
     }
 
diff --git a/library/portable-simd/.github/workflows/ci.yml b/library/portable-simd/.github/workflows/ci.yml
index b292be2d6f9..3984d8f0d8d 100644
--- a/library/portable-simd/.github/workflows/ci.yml
+++ b/library/portable-simd/.github/workflows/ci.yml
@@ -9,6 +9,7 @@ on:
 env:
   CARGO_NET_RETRY: 10
   RUSTUP_MAX_RETRIES: 10
+  PROPTEST_CASES: 64
 
 jobs:
   rustfmt:
@@ -16,12 +17,7 @@ jobs:
     runs-on: ubuntu-latest
 
     steps:
-      - uses: actions/checkout@v2
-      - name: Setup Rust
-        run: |
-          rustup update nightly --no-self-update
-          rustup default nightly
-          rustup component add rustfmt
+      - uses: actions/checkout@v4
       - name: Run rustfmt
         run: cargo fmt --all -- --check
 
@@ -37,7 +33,9 @@ jobs:
           - i686-unknown-linux-gnu
           - i586-unknown-linux-gnu
           - aarch64-unknown-linux-gnu
+          - arm64ec-pc-windows-msvc
           - armv7-unknown-linux-gnueabihf
+          - loongarch64-unknown-linux-gnu
           # non-nightly since https://github.com/rust-lang/rust/pull/113274
           # - mips-unknown-linux-gnu
           # - mips64-unknown-linux-gnuabi64
@@ -49,13 +47,9 @@ jobs:
           - wasm32-unknown-unknown
 
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v4
       - name: Setup Rust
-        run: |
-          rustup update nightly --no-self-update
-          rustup default nightly
-          rustup target add ${{ matrix.target }}
-          rustup component add clippy
+        run: rustup target add ${{ matrix.target }}
       - name: Run Clippy
         run: cargo clippy --all-targets --target ${{ matrix.target }}
 
@@ -65,26 +59,19 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        target: [x86_64-pc-windows-msvc, i686-pc-windows-msvc, i586-pc-windows-msvc, x86_64-unknown-linux-gnu, x86_64-apple-darwin]
+        target: [x86_64-pc-windows-msvc, i686-pc-windows-msvc, i586-pc-windows-msvc, x86_64-unknown-linux-gnu]
         # `default` means we use the default target config for the target,
         # `native` means we run with `-Ctarget-cpu=native`, and anything else is
         # an arg to `-Ctarget-feature`
         target_feature: [default, native, +sse3, +ssse3, +sse4.1, +sse4.2, +avx, +avx2]
 
         exclude:
-          # The macos runners seem to only reliably support up to `avx`.
-          - { target: x86_64-apple-darwin, target_feature: +avx2 }
-          # These features are statically known to be present for all 64 bit
-          # macs, and thus are covered by the `default` test
-          - { target: x86_64-apple-darwin, target_feature: +sse3 }
-          - { target: x86_64-apple-darwin, target_feature: +ssse3 }
           # -Ctarget-cpu=native sounds like bad-news if target != host
           - { target: i686-pc-windows-msvc, target_feature: native }
           - { target: i586-pc-windows-msvc, target_feature: native }
 
         include:
           # Populate the `matrix.os` field
-          - { target: x86_64-apple-darwin,      os: macos-latest }
           - { target: x86_64-unknown-linux-gnu, os: ubuntu-latest }
           - { target: x86_64-pc-windows-msvc,   os: windows-latest }
           - { target: i686-pc-windows-msvc,     os: windows-latest }
@@ -98,12 +85,9 @@ jobs:
           # avx512vl, but occasionally doesn't.  Maybe one day we can enable it.
 
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v4
       - name: Setup Rust
-        run: |
-          rustup update nightly --no-self-update
-          rustup default nightly
-          rustup target add ${{ matrix.target }}
+        run: rustup target add ${{ matrix.target }}
 
       - name: Configure RUSTFLAGS
         shell: bash
@@ -145,6 +129,35 @@ jobs:
         run: cargo doc --verbose --target=${{ matrix.target }}
         env:
           RUSTDOCFLAGS: -Dwarnings
+    
+  macos-tests:
+    name: ${{ matrix.target }}
+    runs-on: macos-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        target:
+          - aarch64-apple-darwin
+          - x86_64-apple-darwin
+    steps:
+      - uses: actions/checkout@v4
+      - name: Setup Rust
+        run: rustup target add ${{ matrix.target }}
+
+      - name: Configure RUSTFLAGS
+        shell: bash
+        run: echo "RUSTFLAGS=-Dwarnings" >> $GITHUB_ENV
+
+      - name: Test (debug)
+        run: cargo test --verbose --target=${{ matrix.target }}
+
+      - name: Test (release)
+        run: cargo test --verbose --target=${{ matrix.target }} --release
+
+      - name: Generate docs
+        run: cargo doc --verbose --target=${{ matrix.target }}
+        env:
+          RUSTDOCFLAGS: -Dwarnings
 
   wasm-tests:
     name: "wasm (firefox, ${{ matrix.name }})"
@@ -155,11 +168,7 @@ jobs:
           - { name: default, RUSTFLAGS: "" }
           - { name: simd128, RUSTFLAGS: "-C target-feature=+simd128" }
     steps:
-      - uses: actions/checkout@v2
-      - name: Setup Rust
-        run: |
-          rustup update nightly --no-self-update
-          rustup default nightly
+      - uses: actions/checkout@v4
       - name: Install wasm-pack
         run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
       - name: Test (debug)
@@ -174,6 +183,8 @@ jobs:
   cross-tests:
     name: "${{ matrix.target_feature }} on ${{ matrix.target }} (via cross)"
     runs-on: ubuntu-latest
+    env:
+      PROPTEST_CASES: 16
     strategy:
       fail-fast: false
 
@@ -185,6 +196,7 @@ jobs:
           - powerpc-unknown-linux-gnu
           - powerpc64le-unknown-linux-gnu       # includes altivec by default
           - riscv64gc-unknown-linux-gnu
+          - loongarch64-unknown-linux-gnu
           # MIPS uses a nonstandard binary representation for NaNs which makes it worth testing
           # non-nightly since https://github.com/rust-lang/rust/pull/113274
           # - mips-unknown-linux-gnu
@@ -201,24 +213,14 @@ jobs:
           # - { target: riscv64gc-unknown-linux-gnu, target_feature: "+v,+zvl128b" }
 
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v4
       - name: Setup Rust
-        run: |
-          rustup update nightly --no-self-update
-          rustup default nightly
-          rustup target add ${{ matrix.target }}
-          rustup component add rust-src
+        run: rustup target add ${{ matrix.target }}
 
       - name: Install Cross
-        # Equivalent to `cargo install cross`, but downloading a prebuilt
-        # binary. Ideally we wouldn't hardcode a version, but the version number
-        # being part of the tarball means we can't just use the download/latest
-        # URL :(
+        # Install the latest git version for newer targets.
         run: |
-          CROSS_URL=https://github.com/cross-rs/cross/releases/download/v0.2.5/cross-x86_64-unknown-linux-gnu.tar.gz
-          mkdir -p "$HOME/.bin"
-          curl -sfSL --retry-delay 10 --retry 5 "${CROSS_URL}" | tar zxf - -C "$HOME/.bin"
-          echo "$HOME/.bin" >> $GITHUB_PATH
+          cargo install cross --git https://github.com/cross-rs/cross --rev 4090beca3cfffa44371a5bba524de3a578aa46c3
 
       - name: Configure Emulated CPUs
         run: |
@@ -242,34 +244,11 @@ jobs:
       - name: Test (release)
         run: cross test --verbose --target=${{ matrix.target }} --release
 
-  features:
-    name: "Test cargo features (${{ matrix.simd }} × ${{ matrix.features }})"
+  miri:
     runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-      matrix:
-        simd:
-          - ""
-          - "avx512"
-        features:
-          - ""
-          - "--features std"
-          - "--features all_lane_counts"
-          - "--all-features"
-
+    env:
+      PROPTEST_CASES: 16
     steps:
-      - uses: actions/checkout@v2
-      - name: Setup Rust
-        run: |
-          rustup update nightly --no-self-update
-          rustup default nightly
-      - name: Detect AVX512
-        run: echo "CPU_FEATURE=$(lscpu | grep -o avx512[a-z]* | sed s/avx/+avx/ | tr '\n' ',' )" >> $GITHUB_ENV
-      - name: Check build
-        if: ${{ matrix.simd == '' }}
-        run: RUSTFLAGS="-Dwarnings" cargo test --all-targets --no-default-features ${{ matrix.features }}
-      - name: Check AVX
-        if: ${{ matrix.simd == 'avx512' && contains(env.CPU_FEATURE, 'avx512') }}
-        run: |
-          echo "Found AVX features: $CPU_FEATURE"
-          RUSTFLAGS="-Dwarnings -Ctarget-feature=$CPU_FEATURE" cargo test --all-targets --no-default-features ${{ matrix.features }}
+      - uses: actions/checkout@v4
+      - name: Test (Miri)
+        run: cargo miri test
diff --git a/library/portable-simd/.github/workflows/doc.yml b/library/portable-simd/.github/workflows/doc.yml
index 9d1fa66ccb5..22c2cb3f67f 100644
--- a/library/portable-simd/.github/workflows/doc.yml
+++ b/library/portable-simd/.github/workflows/doc.yml
@@ -12,7 +12,7 @@ jobs:
 
     steps:
       - name: Checkout Repository
-        uses: actions/checkout@v1
+        uses: actions/checkout@v4
 
       - name: Setup Rust
         run: |
diff --git a/library/portable-simd/.gitignore b/library/portable-simd/.gitignore
index ea8c4bf7f35..9673e52dcad 100644
--- a/library/portable-simd/.gitignore
+++ b/library/portable-simd/.gitignore
@@ -1 +1,2 @@
 /target
+git-subtree.sh
diff --git a/library/portable-simd/Cargo.toml b/library/portable-simd/Cargo.toml
index d1732aaec2f..21d4584a9f4 100644
--- a/library/portable-simd/Cargo.toml
+++ b/library/portable-simd/Cargo.toml
@@ -5,3 +5,9 @@ members = [
     "crates/std_float",
     "crates/test_helpers",
 ]
+
+[profile.test.package."*"]
+opt-level = 2
+
+[profile.test.package.test_helpers]
+opt-level = 2
diff --git a/library/portable-simd/Cross.toml b/library/portable-simd/Cross.toml
new file mode 100644
index 00000000000..d21e76b92dd
--- /dev/null
+++ b/library/portable-simd/Cross.toml
@@ -0,0 +1,2 @@
+[build.env]
+passthrough = ["PROPTEST_CASES"]
diff --git a/library/portable-simd/crates/core_simd/Cargo.toml b/library/portable-simd/crates/core_simd/Cargo.toml
index b4a8fd70f4c..a7a6d43b11d 100644
--- a/library/portable-simd/crates/core_simd/Cargo.toml
+++ b/library/portable-simd/crates/core_simd/Cargo.toml
@@ -9,10 +9,9 @@ categories = ["hardware-support", "no-std"]
 license = "MIT OR Apache-2.0"
 
 [features]
-default = ["as_crate"]
+default = ["as_crate", "std"]
 as_crate = []
 std = []
-all_lane_counts = []
 
 [target.'cfg(target_arch = "wasm32")'.dev-dependencies]
 wasm-bindgen = "0.2"
diff --git a/library/portable-simd/crates/core_simd/src/lane_count.rs b/library/portable-simd/crates/core_simd/src/lane_count.rs
index 4cd7265ed67..280b27bc9bc 100644
--- a/library/portable-simd/crates/core_simd/src/lane_count.rs
+++ b/library/portable-simd/crates/core_simd/src/lane_count.rs
@@ -33,10 +33,8 @@ macro_rules! supported_lane_count {
     };
 }
 
-supported_lane_count!(1, 2, 4, 8, 16, 32, 64);
-#[cfg(feature = "all_lane_counts")]
 supported_lane_count!(
-    3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
-    31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-    56, 57, 58, 59, 60, 61, 62, 63
+    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+    27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+    51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
 );
diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs
index 992a7705e3c..7f57847c9c2 100644
--- a/library/portable-simd/crates/core_simd/src/lib.rs
+++ b/library/portable-simd/crates/core_simd/src/lib.rs
@@ -1,7 +1,6 @@
 #![no_std]
 #![feature(
-    const_refs_to_cell,
-    const_mut_refs,
+    const_eval_select,
     convert_float_to_int,
     core_intrinsics,
     decl_macro,
@@ -26,6 +25,7 @@
     all(target_arch = "arm", target_feature = "v7"),
     feature(stdarch_arm_neon_intrinsics)
 )]
+#![cfg_attr(target_arch = "loongarch64", feature(stdarch_loongarch))]
 #![cfg_attr(
     any(target_arch = "powerpc", target_arch = "powerpc64"),
     feature(stdarch_powerpc)
diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs
index 04de3a96827..b763a7c75a5 100644
--- a/library/portable-simd/crates/core_simd/src/masks.rs
+++ b/library/portable-simd/crates/core_simd/src/masks.rs
@@ -308,48 +308,6 @@ where
         Self(mask_impl::Mask::from_bitmask_integer(bitmask))
     }
 
-    /// Creates a bitmask vector from a mask.
-    ///
-    /// Each bit is set if the corresponding element in the mask is `true`.
-    /// The remaining bits are unset.
-    ///
-    /// The bits are packed into the first N bits of the vector:
-    /// ```
-    /// # #![feature(portable_simd)]
-    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
-    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
-    /// # use simd::mask32x8;
-    /// let mask = mask32x8::from_array([true, false, true, false, false, false, true, false]);
-    /// assert_eq!(mask.to_bitmask_vector()[0], 0b01000101);
-    /// ```
-    #[inline]
-    #[must_use = "method returns a new integer and does not mutate the original value"]
-    pub fn to_bitmask_vector(self) -> Simd<u8, N> {
-        self.0.to_bitmask_vector()
-    }
-
-    /// Creates a mask from a bitmask vector.
-    ///
-    /// For each bit, if it is set, the corresponding element in the mask is set to `true`.
-    ///
-    /// The bits are packed into the first N bits of the vector:
-    /// ```
-    /// # #![feature(portable_simd)]
-    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
-    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
-    /// # use simd::{mask32x8, u8x8};
-    /// let bitmask = u8x8::from_array([0b01000101, 0, 0, 0, 0, 0, 0, 0]);
-    /// assert_eq!(
-    ///     mask32x8::from_bitmask_vector(bitmask),
-    ///     mask32x8::from_array([true, false, true, false, false, false, true, false]),
-    /// );
-    /// ```
-    #[inline]
-    #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
-        Self(mask_impl::Mask::from_bitmask_vector(bitmask))
-    }
-
     /// Finds the index of the first set element.
     ///
     /// ```
diff --git a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
index 96c553426ee..db4312d5bf8 100644
--- a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
@@ -123,23 +123,6 @@ where
     }
 
     #[inline]
-    #[must_use = "method returns a new vector and does not mutate the original value"]
-    pub fn to_bitmask_vector(self) -> Simd<u8, N> {
-        let mut bitmask = Simd::splat(0);
-        bitmask.as_mut_array()[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref());
-        bitmask
-    }
-
-    #[inline]
-    #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
-        let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
-        let len = bytes.as_ref().len();
-        bytes.as_mut().copy_from_slice(&bitmask.as_array()[..len]);
-        Self(bytes, PhantomData)
-    }
-
-    #[inline]
     pub fn to_bitmask_integer(self) -> u64 {
         let mut bitmask = [0u8; 8];
         bitmask[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref());
diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
index 87f031a9f36..2d01946b574 100644
--- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
@@ -141,62 +141,6 @@ where
     }
 
     #[inline]
-    #[must_use = "method returns a new vector and does not mutate the original value"]
-    pub fn to_bitmask_vector(self) -> Simd<u8, N> {
-        let mut bitmask = Simd::splat(0);
-
-        // Safety: Bytes is the right size array
-        unsafe {
-            // Compute the bitmask
-            let mut bytes: <LaneCount<N> as SupportedLaneCount>::BitMask =
-                core::intrinsics::simd::simd_bitmask(self.0);
-
-            // LLVM assumes bit order should match endianness
-            if cfg!(target_endian = "big") {
-                for x in bytes.as_mut() {
-                    *x = x.reverse_bits()
-                }
-                if N % 8 > 0 {
-                    bytes.as_mut()[N / 8] >>= 8 - N % 8;
-                }
-            }
-
-            bitmask.as_mut_array()[..bytes.as_ref().len()].copy_from_slice(bytes.as_ref());
-        }
-
-        bitmask
-    }
-
-    #[inline]
-    #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
-        let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
-
-        // Safety: Bytes is the right size array
-        unsafe {
-            let len = bytes.as_ref().len();
-            bytes.as_mut().copy_from_slice(&bitmask.as_array()[..len]);
-
-            // LLVM assumes bit order should match endianness
-            if cfg!(target_endian = "big") {
-                for x in bytes.as_mut() {
-                    *x = x.reverse_bits();
-                }
-                if N % 8 > 0 {
-                    bytes.as_mut()[N / 8] >>= 8 - N % 8;
-                }
-            }
-
-            // Compute the regular mask
-            Self::from_int_unchecked(core::intrinsics::simd::simd_select_bitmask(
-                bytes,
-                Self::splat(true).to_int(),
-                Self::splat(false).to_int(),
-            ))
-        }
-    }
-
-    #[inline]
     unsafe fn to_bitmask_impl<U: ReverseBits, const M: usize>(self) -> U
     where
         LaneCount<M>: SupportedLaneCount,
@@ -283,7 +227,7 @@ where
     }
 
     #[inline]
-    #[must_use = "method returns a new vector and does not mutate the original value"]
+    #[must_use = "method returns a new bool and does not mutate the original value"]
     pub fn all(self) -> bool {
         // Safety: use `self` as an integer vector
         unsafe { core::intrinsics::simd::simd_reduce_all(self.to_int()) }
diff --git a/library/portable-simd/crates/core_simd/src/ops.rs b/library/portable-simd/crates/core_simd/src/ops.rs
index dd7303a97b1..d3bd14a3402 100644
--- a/library/portable-simd/crates/core_simd/src/ops.rs
+++ b/library/portable-simd/crates/core_simd/src/ops.rs
@@ -77,7 +77,7 @@ macro_rules! int_divrem_guard {
     (   $lhs:ident,
         $rhs:ident,
         {   const PANIC_ZERO: &'static str = $zero:literal;
-            $simd_call:ident
+            $simd_call:ident, $op:tt
         },
         $int:ident ) => {
         if $rhs.simd_eq(Simd::splat(0 as _)).any() {
@@ -96,8 +96,23 @@ macro_rules! int_divrem_guard {
                 // Nice base case to make it easy to const-fold away the other branch.
                 $rhs
             };
-            // Safety: $lhs and rhs are vectors
-            unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) }
+
+            // aarch64 div fails for arbitrary `v % 0`, mod fails when rhs is MIN, for non-powers-of-two
+            // these operations aren't vectorized on aarch64 anyway
+            #[cfg(target_arch = "aarch64")]
+            {
+                let mut out = Simd::splat(0 as _);
+                for i in 0..Self::LEN {
+                    out[i] = $lhs[i] $op rhs[i];
+                }
+                out
+            }
+
+            #[cfg(not(target_arch = "aarch64"))]
+            {
+                // Safety: $lhs and rhs are vectors
+                unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) }
+            }
         }
     };
 }
@@ -205,14 +220,14 @@ for_base_ops! {
     impl Div::div {
         int_divrem_guard {
             const PANIC_ZERO: &'static str = "attempt to divide by zero";
-            simd_div
+            simd_div, /
         }
     }
 
     impl Rem::rem {
         int_divrem_guard {
             const PANIC_ZERO: &'static str = "attempt to calculate the remainder with a divisor of zero";
-            simd_rem
+            simd_rem, %
         }
     }
 
diff --git a/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs b/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs
index 5b4615ce51d..93989ce91b8 100644
--- a/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs
@@ -12,7 +12,7 @@ pub trait SimdPartialEq {
     #[must_use = "method returns a new mask and does not mutate the original value"]
     fn simd_eq(self, other: Self) -> Self::Mask;
 
-    /// Test if each element is equal to the corresponding element in `other`.
+    /// Test if each element is not equal to the corresponding element in `other`.
     #[must_use = "method returns a new mask and does not mutate the original value"]
     fn simd_ne(self, other: Self) -> Self::Mask;
 }
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs
index 59e43851ea8..79954b937b3 100644
--- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs
@@ -255,6 +255,7 @@ macro_rules! impl_trait {
             type Bits = Simd<$bits_ty, N>;
             type Cast<T: SimdElement> = Simd<T, N>;
 
+            #[cfg(not(target_arch = "aarch64"))]
             #[inline]
             fn cast<T: SimdCast>(self) -> Self::Cast<T>
             {
@@ -262,6 +263,33 @@ macro_rules! impl_trait {
                 unsafe { core::intrinsics::simd::simd_as(self) }
             }
 
+            // https://github.com/llvm/llvm-project/issues/94694
+            #[cfg(target_arch = "aarch64")]
+            #[inline]
+            fn cast<T: SimdCast>(self) -> Self::Cast<T>
+            {
+                const { assert!(N <= 64) };
+                if N <= 2 || N == 4 || N == 8 || N == 16 || N == 32 || N == 64 {
+                    // Safety: supported types are guaranteed by SimdCast
+                    unsafe { core::intrinsics::simd::simd_as(self) }
+                } else if N < 4 {
+                    let x = self.resize::<4>(Default::default()).cast();
+                    x.resize::<N>(x[0])
+                } else if N < 8 {
+                    let x = self.resize::<8>(Default::default()).cast();
+                    x.resize::<N>(x[0])
+                } else if N < 16 {
+                    let x = self.resize::<16>(Default::default()).cast();
+                    x.resize::<N>(x[0])
+                } else if N < 32 {
+                    let x = self.resize::<32>(Default::default()).cast();
+                    x.resize::<N>(x[0])
+                } else {
+                    let x = self.resize::<64>(Default::default()).cast();
+                    x.resize::<N>(x[0])
+                }
+            }
+
             #[inline]
             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
             unsafe fn to_int_unchecked<I: SimdCast>(self) -> Self::Cast<I>
@@ -391,7 +419,7 @@ macro_rules! impl_trait {
                     self.as_array().iter().sum()
                 } else {
                     // Safety: `self` is a float vector
-                    unsafe { core::intrinsics::simd::simd_reduce_add_ordered(self, 0.) }
+                    unsafe { core::intrinsics::simd::simd_reduce_add_ordered(self, -0.) }
                 }
             }
 
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/int.rs b/library/portable-simd/crates/core_simd/src/simd/num/int.rs
index d7598d9ceaf..3a51235ff95 100644
--- a/library/portable-simd/crates/core_simd/src/simd/num/int.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/num/int.rs
@@ -1,6 +1,6 @@
 use super::sealed::Sealed;
 use crate::simd::{
-    cmp::SimdPartialOrd, num::SimdUint, LaneCount, Mask, Simd, SimdCast, SimdElement,
+    cmp::SimdOrd, cmp::SimdPartialOrd, num::SimdUint, LaneCount, Mask, Simd, SimdCast, SimdElement,
     SupportedLaneCount,
 };
 
@@ -70,11 +70,27 @@ pub trait SimdInt: Copy + Sealed {
     /// # #[cfg(not(feature = "as_crate"))] use core::simd;
     /// # use simd::prelude::*;
     /// use core::i32::{MIN, MAX};
-    /// let xs = Simd::from_array([MIN, MIN +1, -5, 0]);
+    /// let xs = Simd::from_array([MIN, MIN + 1, -5, 0]);
     /// assert_eq!(xs.abs(), Simd::from_array([MIN, MAX, 5, 0]));
     /// ```
     fn abs(self) -> Self;
 
+    /// Lanewise absolute difference.
+    /// Every element becomes the absolute difference of `self` and `second`.
+    ///
+    /// # Examples
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+    /// # use simd::prelude::*;
+    /// use core::i32::{MIN, MAX};
+    /// let a = Simd::from_array([MIN, MAX, 100, -100]);
+    /// let b = Simd::from_array([MAX, MIN, -80, -120]);
+    /// assert_eq!(a.abs_diff(b), Simd::from_array([u32::MAX, u32::MAX, 180, 20]));
+    /// ```
+    fn abs_diff(self, second: Self) -> Self::Unsigned;
+
     /// Lanewise saturating absolute value, implemented in Rust.
     /// As abs(), except the MIN value becomes MAX instead of itself.
     ///
@@ -203,6 +219,12 @@ pub trait SimdInt: Copy + Sealed {
     /// The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc.
     fn reverse_bits(self) -> Self;
 
+    /// Returns the number of ones in the binary representation of each element.
+    fn count_ones(self) -> Self::Unsigned;
+
+    /// Returns the number of zeros in the binary representation of each element.
+    fn count_zeros(self) -> Self::Unsigned;
+
     /// Returns the number of leading zeros in the binary representation of each element.
     fn leading_zeros(self) -> Self::Unsigned;
 
@@ -260,6 +282,13 @@ macro_rules! impl_trait {
             }
 
             #[inline]
+            fn abs_diff(self, second: Self) -> Self::Unsigned {
+                let max = self.simd_max(second);
+                let min = self.simd_min(second);
+                (max - min).cast()
+            }
+
+            #[inline]
             fn saturating_abs(self) -> Self {
                 // arith shift for -1 or 0 mask based on sign bit, giving 2s complement
                 const SHR: $ty = <$ty>::BITS as $ty - 1;
@@ -345,6 +374,16 @@ macro_rules! impl_trait {
             }
 
             #[inline]
+            fn count_ones(self) -> Self::Unsigned {
+                self.cast::<$unsigned>().count_ones()
+            }
+
+            #[inline]
+            fn count_zeros(self) -> Self::Unsigned {
+                self.cast::<$unsigned>().count_zeros()
+            }
+
+            #[inline]
             fn leading_zeros(self) -> Self::Unsigned {
                 self.cast::<$unsigned>().leading_zeros()
             }
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/uint.rs b/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
index 53dd97f501c..1ab2d8c7b73 100644
--- a/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
@@ -1,5 +1,5 @@
 use super::sealed::Sealed;
-use crate::simd::{LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount};
+use crate::simd::{cmp::SimdOrd, LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount};
 
 /// Operations on SIMD vectors of unsigned integers.
 pub trait SimdUint: Copy + Sealed {
@@ -57,6 +57,22 @@ pub trait SimdUint: Copy + Sealed {
     /// assert_eq!(sat, Simd::splat(0));
     fn saturating_sub(self, second: Self) -> Self;
 
+    /// Lanewise absolute difference.
+    /// Every element becomes the absolute difference of `self` and `second`.
+    ///
+    /// # Examples
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+    /// # use simd::prelude::*;
+    /// use core::u32::MAX;
+    /// let a = Simd::from_array([0, MAX, 100, 20]);
+    /// let b = Simd::from_array([MAX, 0, 80, 200]);
+    /// assert_eq!(a.abs_diff(b), Simd::from_array([MAX, MAX, 20, 180]));
+    /// ```
+    fn abs_diff(self, second: Self) -> Self;
+
     /// Returns the sum of the elements of the vector, with wrapping addition.
     fn reduce_sum(self) -> Self::Scalar;
 
@@ -85,6 +101,12 @@ pub trait SimdUint: Copy + Sealed {
     /// The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc.
     fn reverse_bits(self) -> Self;
 
+    /// Returns the number of ones in the binary representation of each element.
+    fn count_ones(self) -> Self;
+
+    /// Returns the number of zeros in the binary representation of each element.
+    fn count_zeros(self) -> Self;
+
     /// Returns the number of leading zeros in the binary representation of each element.
     fn leading_zeros(self) -> Self;
 
@@ -139,6 +161,13 @@ macro_rules! impl_trait {
             }
 
             #[inline]
+            fn abs_diff(self, second: Self) -> Self {
+                let max = self.simd_max(second);
+                let min = self.simd_min(second);
+                max - min
+            }
+
+            #[inline]
             fn reduce_sum(self) -> Self::Scalar {
                 // Safety: `self` is an integer vector
                 unsafe { core::intrinsics::simd::simd_reduce_add_ordered(self, 0) }
@@ -193,6 +222,17 @@ macro_rules! impl_trait {
             }
 
             #[inline]
+            fn count_ones(self) -> Self {
+                // Safety: `self` is an integer vector
+                unsafe { core::intrinsics::simd::simd_ctpop(self) }
+            }
+
+            #[inline]
+            fn count_zeros(self) -> Self {
+                (!self).count_ones()
+            }
+
+            #[inline]
             fn leading_zeros(self) -> Self {
                 // Safety: `self` is an integer vector
                 unsafe { core::intrinsics::simd::simd_ctlz(self) }
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
index be635ea640b..47383809ffb 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
@@ -42,6 +42,19 @@ pub trait SimdConstPtr: Copy + Sealed {
     /// Equivalent to calling [`pointer::addr`] on each element.
     fn addr(self) -> Self::Usize;
 
+    /// Converts an address to a pointer without giving it any provenance.
+    ///
+    /// Without provenance, this pointer is not associated with any actual allocation. Such a
+    /// no-provenance pointer may be used for zero-sized memory accesses (if suitably aligned), but
+    /// non-zero-sized memory accesses with a no-provenance pointer are UB. No-provenance pointers
+    /// are little more than a usize address in disguise.
+    ///
+    /// This is different from [`Self::with_exposed_provenance`], which creates a pointer that picks up a
+    /// previously exposed provenance.
+    ///
+    /// Equivalent to calling [`core::ptr::without_provenance`] on each element.
+    fn without_provenance(addr: Self::Usize) -> Self;
+
     /// Creates a new pointer with the given address.
     ///
     /// This performs the same operation as a cast, but copies the *address-space* and
@@ -119,6 +132,14 @@ where
     }
 
     #[inline]
+    fn without_provenance(addr: Self::Usize) -> Self {
+        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
+        // SAFETY: Integer-to-pointer transmutes are valid (if you are okay with not getting any
+        // provenance).
+        unsafe { core::mem::transmute_copy(&addr) }
+    }
+
+    #[inline]
     fn with_addr(self, addr: Self::Usize) -> Self {
         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         //
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
index f6823a949e3..3f20eef21a3 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
@@ -39,6 +39,19 @@ pub trait SimdMutPtr: Copy + Sealed {
     /// Equivalent to calling [`pointer::addr`] on each element.
     fn addr(self) -> Self::Usize;
 
+    /// Converts an address to a pointer without giving it any provenance.
+    ///
+    /// Without provenance, this pointer is not associated with any actual allocation. Such a
+    /// no-provenance pointer may be used for zero-sized memory accesses (if suitably aligned), but
+    /// non-zero-sized memory accesses with a no-provenance pointer are UB. No-provenance pointers
+    /// are little more than a usize address in disguise.
+    ///
+    /// This is different from [`Self::with_exposed_provenance`], which creates a pointer that picks up a
+    /// previously exposed provenance.
+    ///
+    /// Equivalent to calling [`core::ptr::without_provenance`] on each element.
+    fn without_provenance(addr: Self::Usize) -> Self;
+
     /// Creates a new pointer with the given address.
     ///
     /// This performs the same operation as a cast, but copies the *address-space* and
@@ -116,6 +129,14 @@ where
     }
 
     #[inline]
+    fn without_provenance(addr: Self::Usize) -> Self {
+        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
+        // SAFETY: Integer-to-pointer transmutes are valid (if you are okay with not getting any
+        // provenance).
+        unsafe { core::mem::transmute_copy(&addr) }
+    }
+
+    #[inline]
     fn with_addr(self, addr: Self::Usize) -> Self {
         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         //
diff --git a/library/portable-simd/crates/core_simd/src/swizzle.rs b/library/portable-simd/crates/core_simd/src/swizzle.rs
index d62642fb906..42425ef37e5 100644
--- a/library/portable-simd/crates/core_simd/src/swizzle.rs
+++ b/library/portable-simd/crates/core_simd/src/swizzle.rs
@@ -155,8 +155,7 @@ pub trait Swizzle<const N: usize> {
 
     /// Creates a new mask from the elements of `mask`.
     ///
-    /// Element `i` of the output is `concat[Self::INDEX[i]]`, where `concat` is the concatenation of
-    /// `first` and `second`.
+    /// Element `i` of the output is `mask[Self::INDEX[i]]`.
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original inputs"]
     fn swizzle_mask<T, const M: usize>(mask: Mask<T, M>) -> Mask<T, N>
@@ -260,6 +259,50 @@ where
         Rotate::<OFFSET>::swizzle(self)
     }
 
+    /// Shifts the vector elements to the left by `OFFSET`, filling in with
+    /// `padding` from the right.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn shift_elements_left<const OFFSET: usize>(self, padding: T) -> Self {
+        struct Shift<const OFFSET: usize>;
+
+        impl<const OFFSET: usize, const N: usize> Swizzle<N> for Shift<OFFSET> {
+            const INDEX: [usize; N] = const {
+                let mut index = [N; N];
+                let mut i = 0;
+                while i + OFFSET < N {
+                    index[i] = i + OFFSET;
+                    i += 1;
+                }
+                index
+            };
+        }
+
+        Shift::<OFFSET>::concat_swizzle(self, Simd::splat(padding))
+    }
+
+    /// Shifts the vector elements to the right by `OFFSET`, filling in with
+    /// `padding` from the left.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn shift_elements_right<const OFFSET: usize>(self, padding: T) -> Self {
+        struct Shift<const OFFSET: usize>;
+
+        impl<const OFFSET: usize, const N: usize> Swizzle<N> for Shift<OFFSET> {
+            const INDEX: [usize; N] = const {
+                let mut index = [N; N];
+                let mut i = OFFSET;
+                while i < N {
+                    index[i] = i - OFFSET;
+                    i += 1;
+                }
+                index
+            };
+        }
+
+        Shift::<OFFSET>::concat_swizzle(self, Simd::splat(padding))
+    }
+
     /// Interleave two vectors.
     ///
     /// The resulting vectors contain elements taken alternatively from `self` and `other`, first
@@ -320,7 +363,9 @@ where
     ///
     /// ```
     /// # #![feature(portable_simd)]
-    /// # use core::simd::Simd;
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+    /// # use simd::Simd;
     /// let a = Simd::from_array([0, 4, 1, 5]);
     /// let b = Simd::from_array([2, 6, 3, 7]);
     /// let (x, y) = a.deinterleave(b);
@@ -391,4 +436,210 @@ where
         }
         Resize::<N>::concat_swizzle(self, Simd::splat(value))
     }
+
+    /// Extract a vector from another vector.
+    ///
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+    /// # use simd::u32x4;
+    /// let x = u32x4::from_array([0, 1, 2, 3]);
+    /// assert_eq!(x.extract::<1, 2>().to_array(), [1, 2]);
+    /// ```
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn extract<const START: usize, const LEN: usize>(self) -> Simd<T, LEN>
+    where
+        LaneCount<LEN>: SupportedLaneCount,
+    {
+        struct Extract<const N: usize, const START: usize>;
+        impl<const N: usize, const START: usize, const LEN: usize> Swizzle<LEN> for Extract<N, START> {
+            const INDEX: [usize; LEN] = const {
+                assert!(START + LEN <= N, "index out of bounds");
+                let mut index = [0; LEN];
+                let mut i = 0;
+                while i < LEN {
+                    index[i] = START + i;
+                    i += 1;
+                }
+                index
+            };
+        }
+        Extract::<N, START>::swizzle(self)
+    }
+}
+
+impl<T, const N: usize> Mask<T, N>
+where
+    T: MaskElement,
+    LaneCount<N>: SupportedLaneCount,
+{
+    /// Reverse the order of the elements in the mask.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn reverse(self) -> Self {
+        // Safety: swizzles are safe for masks
+        unsafe { Self::from_int_unchecked(self.to_int().reverse()) }
+    }
+
+    /// Rotates the mask such that the first `OFFSET` elements of the slice move to the end
+    /// while the last `self.len() - OFFSET` elements move to the front. After calling `rotate_elements_left`,
+    /// the element previously at index `OFFSET` will become the first element in the slice.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
+        // Safety: swizzles are safe for masks
+        unsafe { Self::from_int_unchecked(self.to_int().rotate_elements_left::<OFFSET>()) }
+    }
+
+    /// Rotates the mask such that the first `self.len() - OFFSET` elements of the mask move to
+    /// the end while the last `OFFSET` elements move to the front. After calling `rotate_elements_right`,
+    /// the element previously at index `self.len() - OFFSET` will become the first element in the slice.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
+        // Safety: swizzles are safe for masks
+        unsafe { Self::from_int_unchecked(self.to_int().rotate_elements_right::<OFFSET>()) }
+    }
+
+    /// Shifts the mask elements to the left by `OFFSET`, filling in with
+    /// `padding` from the right.
+    #[inline]
+    #[must_use = "method returns a new mask and does not mutate the original inputs"]
+    pub fn shift_elements_left<const OFFSET: usize>(self, padding: bool) -> Self {
+        // Safety: swizzles are safe for masks
+        unsafe {
+            Self::from_int_unchecked(self.to_int().shift_elements_left::<OFFSET>(if padding {
+                T::TRUE
+            } else {
+                T::FALSE
+            }))
+        }
+    }
+
+    /// Shifts the mask elements to the right by `OFFSET`, filling in with
+    /// `padding` from the left.
+    #[inline]
+    #[must_use = "method returns a new mask and does not mutate the original inputs"]
+    pub fn shift_elements_right<const OFFSET: usize>(self, padding: bool) -> Self {
+        // Safety: swizzles are safe for masks
+        unsafe {
+            Self::from_int_unchecked(self.to_int().shift_elements_right::<OFFSET>(if padding {
+                T::TRUE
+            } else {
+                T::FALSE
+            }))
+        }
+    }
+
+    /// Interleave two masks.
+    ///
+    /// The resulting masks contain elements taken alternatively from `self` and `other`, first
+    /// filling the first result, and then the second.
+    ///
+    /// The reverse of this operation is [`Mask::deinterleave`].
+    ///
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+    /// # use simd::mask32x4;
+    /// let a = mask32x4::from_array([false, true, false, true]);
+    /// let b = mask32x4::from_array([false, false, true, true]);
+    /// let (x, y) = a.interleave(b);
+    /// assert_eq!(x.to_array(), [false, false, true, false]);
+    /// assert_eq!(y.to_array(), [false, true, true, true]);
+    /// ```
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn interleave(self, other: Self) -> (Self, Self) {
+        let (lo, hi) = self.to_int().interleave(other.to_int());
+        // Safety: swizzles are safe for masks
+        unsafe { (Self::from_int_unchecked(lo), Self::from_int_unchecked(hi)) }
+    }
+
+    /// Deinterleave two masks.
+    ///
+    /// The first result takes every other element of `self` and then `other`, starting with
+    /// the first element.
+    ///
+    /// The second result takes every other element of `self` and then `other`, starting with
+    /// the second element.
+    ///
+    /// The reverse of this operation is [`Mask::interleave`].
+    ///
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+    /// # use simd::mask32x4;
+    /// let a = mask32x4::from_array([false, true, false, true]);
+    /// let b = mask32x4::from_array([false, false, true, true]);
+    /// let (x, y) = a.deinterleave(b);
+    /// assert_eq!(x.to_array(), [false, false, false, true]);
+    /// assert_eq!(y.to_array(), [true, true, false, true]);
+    /// ```
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn deinterleave(self, other: Self) -> (Self, Self) {
+        let (even, odd) = self.to_int().deinterleave(other.to_int());
+        // Safety: swizzles are safe for masks
+        unsafe {
+            (
+                Self::from_int_unchecked(even),
+                Self::from_int_unchecked(odd),
+            )
+        }
+    }
+
+    /// Resize a mask.
+    ///
+    /// If `M` > `N`, extends the length of a mask, setting the new elements to `value`.
+    /// If `M` < `N`, truncates the mask to the first `M` elements.
+    ///
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+    /// # use simd::mask32x4;
+    /// let x = mask32x4::from_array([false, true, true, false]);
+    /// assert_eq!(x.resize::<8>(true).to_array(), [false, true, true, false, true, true, true, true]);
+    /// assert_eq!(x.resize::<2>(true).to_array(), [false, true]);
+    /// ```
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn resize<const M: usize>(self, value: bool) -> Mask<T, M>
+    where
+        LaneCount<M>: SupportedLaneCount,
+    {
+        // Safety: swizzles are safe for masks
+        unsafe {
+            Mask::<T, M>::from_int_unchecked(self.to_int().resize::<M>(if value {
+                T::TRUE
+            } else {
+                T::FALSE
+            }))
+        }
+    }
+
+    /// Extract a vector from another vector.
+    ///
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
+    /// # use simd::mask32x4;
+    /// let x = mask32x4::from_array([false, true, true, false]);
+    /// assert_eq!(x.extract::<1, 2>().to_array(), [true, true]);
+    /// ```
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original inputs"]
+    pub fn extract<const START: usize, const LEN: usize>(self) -> Mask<T, LEN>
+    where
+        LaneCount<LEN>: SupportedLaneCount,
+    {
+        // Safety: swizzles are safe for masks
+        unsafe { Mask::<T, LEN>::from_int_unchecked(self.to_int().extract::<START, LEN>()) }
+    }
 }
diff --git a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs
index 3b6388d0f27..773bd028bae 100644
--- a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs
+++ b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs
@@ -59,15 +59,40 @@ where
                     target_endian = "little"
                 ))]
                 16 => transize(vqtbl1q_u8, self, idxs),
+                #[cfg(all(
+                    target_arch = "arm",
+                    target_feature = "v7",
+                    target_feature = "neon",
+                    target_endian = "little"
+                ))]
+                16 => transize(armv7_neon_swizzle_u8x16, self, idxs),
                 #[cfg(all(target_feature = "avx2", not(target_feature = "avx512vbmi")))]
                 32 => transize(avx2_pshufb, self, idxs),
                 #[cfg(all(target_feature = "avx512vl", target_feature = "avx512vbmi"))]
-                32 => transize(x86::_mm256_permutexvar_epi8, zeroing_idxs(idxs), self),
-                // Notable absence: avx512bw shuffle
-                // If avx512bw is available, odds of avx512vbmi are good
-                // FIXME: initial AVX512VBMI variant didn't actually pass muster
-                // #[cfg(target_feature = "avx512vbmi")]
-                // 64 => transize(x86::_mm512_permutexvar_epi8, self, idxs),
+                32 => {
+                    // Unlike vpshufb, vpermb doesn't zero out values in the result based on the index high bit
+                    let swizzler = |bytes, idxs| {
+                        let mask = x86::_mm256_cmp_epu8_mask::<{ x86::_MM_CMPINT_LT }>(
+                            idxs,
+                            Simd::<u8, 32>::splat(N as u8).into(),
+                        );
+                        x86::_mm256_maskz_permutexvar_epi8(mask, idxs, bytes)
+                    };
+                    transize(swizzler, self, idxs)
+                }
+                // Notable absence: avx512bw pshufb shuffle
+                #[cfg(all(target_feature = "avx512vl", target_feature = "avx512vbmi"))]
+                64 => {
+                    // Unlike vpshufb, vpermb doesn't zero out values in the result based on the index high bit
+                    let swizzler = |bytes, idxs| {
+                        let mask = x86::_mm512_cmp_epu8_mask::<{ x86::_MM_CMPINT_LT }>(
+                            idxs,
+                            Simd::<u8, 64>::splat(N as u8).into(),
+                        );
+                        x86::_mm512_maskz_permutexvar_epi8(mask, idxs, bytes)
+                    };
+                    transize(swizzler, self, idxs)
+                }
                 _ => {
                     let mut array = [0; N];
                     for (i, k) in idxs.to_array().into_iter().enumerate() {
@@ -82,6 +107,28 @@ where
     }
 }
 
+/// armv7 neon supports swizzling `u8x16` by swizzling two u8x8 blocks
+/// with a u8x8x2 lookup table.
+///
+/// # Safety
+/// This requires armv7 neon to work
+#[cfg(all(
+    target_arch = "arm",
+    target_feature = "v7",
+    target_feature = "neon",
+    target_endian = "little"
+))]
+unsafe fn armv7_neon_swizzle_u8x16(bytes: Simd<u8, 16>, idxs: Simd<u8, 16>) -> Simd<u8, 16> {
+    use core::arch::arm::{uint8x8x2_t, vcombine_u8, vget_high_u8, vget_low_u8, vtbl2_u8};
+    // SAFETY: Caller promised arm neon support
+    unsafe {
+        let bytes = uint8x8x2_t(vget_low_u8(bytes.into()), vget_high_u8(bytes.into()));
+        let lo = vtbl2_u8(bytes, vget_low_u8(idxs.into()));
+        let hi = vtbl2_u8(bytes, vget_high_u8(idxs.into()));
+        vcombine_u8(lo, hi).into()
+    }
+}
+
 /// "vpshufb like it was meant to be" on AVX2
 ///
 /// # Safety
diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs
index 3e239169149..9c4dd36c24f 100644
--- a/library/portable-simd/crates/core_simd/src/vector.rs
+++ b/library/portable-simd/crates/core_simd/src/vector.rs
@@ -99,7 +99,7 @@ use crate::simd::{
 // directly constructing an instance of the type (i.e. `let vector = Simd(array)`) should be
 // avoided, as it will likely become illegal on `#[repr(simd)]` structs in the future. It also
 // causes rustc to emit illegal LLVM IR in some cases.
-#[repr(simd)]
+#[repr(simd, packed)]
 pub struct Simd<T, const N: usize>([T; N])
 where
     LaneCount<N>: SupportedLaneCount,
@@ -144,14 +144,32 @@ where
     /// assert_eq!(v.as_array(), &[8, 8, 8, 8]);
     /// ```
     #[inline]
-    pub fn splat(value: T) -> Self {
-        // This is preferred over `[value; N]`, since it's explicitly a splat:
-        // https://github.com/rust-lang/rust/issues/97804
-        struct Splat;
-        impl<const N: usize> Swizzle<N> for Splat {
-            const INDEX: [usize; N] = [0; N];
+    #[rustc_const_unstable(feature = "portable_simd", issue = "86656")]
+    pub const fn splat(value: T) -> Self {
+        const fn splat_const<T, const N: usize>(value: T) -> Simd<T, N>
+        where
+            T: SimdElement,
+            LaneCount<N>: SupportedLaneCount,
+        {
+            Simd::from_array([value; N])
         }
-        Splat::swizzle::<T, 1>(Simd::<T, 1>::from([value]))
+
+        fn splat_rt<T, const N: usize>(value: T) -> Simd<T, N>
+        where
+            T: SimdElement,
+            LaneCount<N>: SupportedLaneCount,
+        {
+            // This is preferred over `[value; N]`, since it's explicitly a splat:
+            // https://github.com/rust-lang/rust/issues/97804
+            struct Splat;
+            impl<const N: usize> Swizzle<N> for Splat {
+                const INDEX: [usize; N] = [0; N];
+            }
+
+            Splat::swizzle::<T, 1>(Simd::<T, 1>::from([value]))
+        }
+
+        core::intrinsics::const_eval_select((value,), splat_const, splat_rt)
     }
 
     /// Returns an array reference containing the entire SIMD vector.
@@ -425,6 +443,9 @@ where
     ///
     /// When the element is disabled, that memory location is not accessed and the corresponding
     /// value from `or` is passed through.
+    ///
+    /// # Safety
+    /// Enabled loads must not exceed the length of `slice`.
     #[must_use]
     #[inline]
     pub unsafe fn load_select_unchecked(
@@ -442,6 +463,9 @@ where
     ///
     /// When the element is disabled, that memory location is not accessed and the corresponding
     /// value from `or` is passed through.
+    ///
+    /// # Safety
+    /// Enabled `ptr` elements must be safe to read as if by `std::ptr::read`.
     #[must_use]
     #[inline]
     pub unsafe fn load_select_ptr(
@@ -924,6 +948,7 @@ where
     }
 }
 
+/// Lexicographic order. For the SIMD elementwise minimum and maximum, use simd_min and simd_max instead.
 impl<T, const N: usize> PartialOrd for Simd<T, N>
 where
     LaneCount<N>: SupportedLaneCount,
@@ -943,6 +968,7 @@ where
 {
 }
 
+/// Lexicographic order. For the SIMD elementwise minimum and maximum, use simd_min and simd_max instead.
 impl<T, const N: usize> Ord for Simd<T, N>
 where
     LaneCount<N>: SupportedLaneCount,
@@ -1195,6 +1221,7 @@ fn lane_indices<const N: usize>() -> Simd<usize, N>
 where
     LaneCount<N>: SupportedLaneCount,
 {
+    #![allow(clippy::needless_range_loop)]
     let mut index = [0; N];
     for i in 0..N {
         index[i] = i;
diff --git a/library/portable-simd/crates/core_simd/src/vendor.rs b/library/portable-simd/crates/core_simd/src/vendor.rs
index 1a34a3a8de5..57536e4fc77 100644
--- a/library/portable-simd/crates/core_simd/src/vendor.rs
+++ b/library/portable-simd/crates/core_simd/src/vendor.rs
@@ -29,3 +29,6 @@ mod arm;
 
 #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
 mod powerpc;
+
+#[cfg(target_arch = "loongarch64")]
+mod loongarch64;
diff --git a/library/portable-simd/crates/core_simd/src/vendor/loongarch64.rs b/library/portable-simd/crates/core_simd/src/vendor/loongarch64.rs
new file mode 100644
index 00000000000..1290bc166b2
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/src/vendor/loongarch64.rs
@@ -0,0 +1,31 @@
+use crate::simd::*;
+use core::arch::loongarch64::*;
+
+from_transmute! { unsafe u8x16 => v16u8 }
+from_transmute! { unsafe u8x32 => v32u8 }
+from_transmute! { unsafe i8x16 => v16i8 }
+from_transmute! { unsafe i8x32 => v32i8 }
+
+from_transmute! { unsafe u16x8 => v8u16 }
+from_transmute! { unsafe u16x16 => v16u16 }
+from_transmute! { unsafe i16x8 => v8i16 }
+from_transmute! { unsafe i16x16 => v16i16 }
+
+from_transmute! { unsafe u32x4 => v4u32 }
+from_transmute! { unsafe u32x8 => v8u32 }
+from_transmute! { unsafe i32x4 => v4i32 }
+from_transmute! { unsafe i32x8 => v8i32 }
+from_transmute! { unsafe f32x4 => v4f32 }
+from_transmute! { unsafe f32x8 => v8f32 }
+
+from_transmute! { unsafe u64x2 => v2u64 }
+from_transmute! { unsafe u64x4 => v4u64 }
+from_transmute! { unsafe i64x2 => v2i64 }
+from_transmute! { unsafe i64x4 => v4i64 }
+from_transmute! { unsafe f64x2 => v2f64 }
+from_transmute! { unsafe f64x4 => v4f64 }
+
+from_transmute! { unsafe usizex2 => v2u64 }
+from_transmute! { unsafe usizex4 => v4u64 }
+from_transmute! { unsafe isizex2 => v2i64 }
+from_transmute! { unsafe isizex4 => v4i64 }
diff --git a/library/portable-simd/crates/core_simd/tests/layout.rs b/library/portable-simd/crates/core_simd/tests/layout.rs
new file mode 100644
index 00000000000..24114c2d261
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/tests/layout.rs
@@ -0,0 +1,35 @@
+#![feature(portable_simd)]
+
+macro_rules! layout_tests {
+    { $($mod:ident, $ty:ty,)* } => {
+        $(
+        mod $mod {
+            test_helpers::test_lanes! {
+                fn no_padding<const LANES: usize>() {
+                    assert_eq!(
+                        core::mem::size_of::<core_simd::simd::Simd::<$ty, LANES>>(),
+                        core::mem::size_of::<[$ty; LANES]>(),
+                    );
+                }
+            }
+        }
+        )*
+    }
+}
+
+layout_tests! {
+    i8, i8,
+    i16, i16,
+    i32, i32,
+    i64, i64,
+    isize, isize,
+    u8, u8,
+    u16, u16,
+    u32, u32,
+    u64, u64,
+    usize, usize,
+    f32, f32,
+    f64, f64,
+    mut_ptr, *mut (),
+    const_ptr, *const (),
+}
diff --git a/library/portable-simd/crates/core_simd/tests/masks.rs b/library/portable-simd/crates/core_simd/tests/masks.rs
index fc6a3476b7c..48786d02440 100644
--- a/library/portable-simd/crates/core_simd/tests/masks.rs
+++ b/library/portable-simd/crates/core_simd/tests/masks.rs
@@ -99,7 +99,6 @@ macro_rules! test_mask_api {
                 assert_eq!(Mask::<$type, 2>::from_bitmask(bitmask), mask);
             }
 
-            #[cfg(feature = "all_lane_counts")]
             #[test]
             fn roundtrip_bitmask_conversion_odd() {
                 let values = [
@@ -134,48 +133,6 @@ macro_rules! test_mask_api {
                 cast_impl::<i64>();
                 cast_impl::<isize>();
             }
-
-            #[test]
-            fn roundtrip_bitmask_vector_conversion() {
-                use core_simd::simd::ToBytes;
-                let values = [
-                    true, false, false, true, false, false, true, false,
-                    true, true, false, false, false, false, false, true,
-                ];
-                let mask = Mask::<$type, 16>::from_array(values);
-                let bitmask = mask.to_bitmask_vector();
-                assert_eq!(bitmask.resize::<2>(0).to_ne_bytes()[..2], [0b01001001, 0b10000011]);
-                assert_eq!(Mask::<$type, 16>::from_bitmask_vector(bitmask), mask);
-            }
-
-            // rust-lang/portable-simd#379
-            #[test]
-            fn roundtrip_bitmask_vector_conversion_small() {
-                use core_simd::simd::ToBytes;
-                let values = [
-                    true, false, true, true
-                ];
-                let mask = Mask::<$type, 4>::from_array(values);
-                let bitmask = mask.to_bitmask_vector();
-                assert_eq!(bitmask.resize::<1>(0).to_ne_bytes()[0], 0b00001101);
-                assert_eq!(Mask::<$type, 4>::from_bitmask_vector(bitmask), mask);
-            }
-
-            /* FIXME doesn't work with non-powers-of-two, yet
-            // rust-lang/portable-simd#379
-            #[cfg(feature = "all_lane_counts")]
-            #[test]
-            fn roundtrip_bitmask_vector_conversion_odd() {
-                use core_simd::simd::ToBytes;
-                let values = [
-                    true, false, true, false, true, true, false, false, false, true, true,
-                ];
-                let mask = Mask::<$type, 11>::from_array(values);
-                let bitmask = mask.to_bitmask_vector();
-                assert_eq!(bitmask.resize::<2>(0).to_ne_bytes()[..2], [0b00110101, 0b00000110]);
-                assert_eq!(Mask::<$type, 11>::from_bitmask_vector(bitmask), mask);
-            }
-            */
         }
     }
 }
diff --git a/library/portable-simd/crates/core_simd/tests/ops_macros.rs b/library/portable-simd/crates/core_simd/tests/ops_macros.rs
index aa565a13752..6de78f51e59 100644
--- a/library/portable-simd/crates/core_simd/tests/ops_macros.rs
+++ b/library/portable-simd/crates/core_simd/tests/ops_macros.rs
@@ -216,6 +216,22 @@ macro_rules! impl_common_integer_tests {
                 )
             }
 
+            fn count_ones<const LANES: usize>() {
+                test_helpers::test_unary_elementwise(
+                    &$vector::<LANES>::count_ones,
+                    &|x| x.count_ones() as _,
+                    &|_| true,
+                )
+            }
+
+            fn count_zeros<const LANES: usize>() {
+                test_helpers::test_unary_elementwise(
+                    &$vector::<LANES>::count_zeros,
+                    &|x| x.count_zeros() as _,
+                    &|_| true,
+                )
+            }
+
             fn leading_zeros<const LANES: usize>() {
                 test_helpers::test_unary_elementwise(
                     &$vector::<LANES>::leading_zeros,
@@ -307,6 +323,14 @@ macro_rules! impl_signed_tests {
                     assert_eq!(a % b, Vector::<LANES>::splat(0));
                 }
 
+                fn abs_diff<const LANES: usize>() {
+                    test_helpers::test_binary_elementwise(
+                        &Vector::<LANES>::abs_diff,
+                        &Scalar::abs_diff,
+                        &|_, _| true,
+                    )
+                }
+
                 fn simd_min<const LANES: usize>() {
                     use core_simd::simd::cmp::SimdOrd;
                     let a = Vector::<LANES>::splat(Scalar::MIN);
@@ -419,6 +443,14 @@ macro_rules! impl_unsigned_tests {
                         &|_| true,
                     );
                 }
+
+                fn abs_diff<const LANES: usize>() {
+                    test_helpers::test_binary_elementwise(
+                        &Vector::<LANES>::abs_diff,
+                        &Scalar::abs_diff,
+                        &|_, _| true,
+                    )
+                }
             }
 
             impl_binary_op_test!(Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add);
@@ -495,6 +527,9 @@ macro_rules! impl_float_tests {
                 }
 
                 fn is_normal<const LANES: usize>() {
+                    // Arm v7 Neon violates float opsem re: subnormals, see
+                    // https://github.com/rust-lang/portable-simd/issues/439
+                    #[cfg(not(target_arch = "arm"))]
                     test_helpers::test_unary_mask_elementwise(
                         &Vector::<LANES>::is_normal,
                         &Scalar::is_normal,
@@ -503,6 +538,9 @@ macro_rules! impl_float_tests {
                 }
 
                 fn is_subnormal<const LANES: usize>() {
+                    // Arm v7 Neon violates float opsem re: subnormals, see
+                    // https://github.com/rust-lang/portable-simd/issues/439
+                    #[cfg(not(target_arch = "arm"))]
                     test_helpers::test_unary_mask_elementwise(
                         &Vector::<LANES>::is_subnormal,
                         &Scalar::is_subnormal,
diff --git a/library/portable-simd/crates/core_simd/tests/swizzle.rs b/library/portable-simd/crates/core_simd/tests/swizzle.rs
index 522d71439b7..7001e5f6bf8 100644
--- a/library/portable-simd/crates/core_simd/tests/swizzle.rs
+++ b/library/portable-simd/crates/core_simd/tests/swizzle.rs
@@ -50,6 +50,24 @@ fn rotate() {
 
 #[test]
 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+fn shift() {
+    let a = Simd::from_array([1, 2, 3, 4]);
+    assert_eq!(a.shift_elements_left::<0>(0).to_array(), [1, 2, 3, 4]);
+    assert_eq!(a.shift_elements_left::<1>(0).to_array(), [2, 3, 4, 0]);
+    assert_eq!(a.shift_elements_left::<2>(9).to_array(), [3, 4, 9, 9]);
+    assert_eq!(a.shift_elements_left::<3>(8).to_array(), [4, 8, 8, 8]);
+    assert_eq!(a.shift_elements_left::<4>(7).to_array(), [7, 7, 7, 7]);
+    assert_eq!(a.shift_elements_left::<5>(6).to_array(), [6, 6, 6, 6]);
+    assert_eq!(a.shift_elements_right::<0>(0).to_array(), [1, 2, 3, 4]);
+    assert_eq!(a.shift_elements_right::<1>(0).to_array(), [0, 1, 2, 3]);
+    assert_eq!(a.shift_elements_right::<2>(-1).to_array(), [-1, -1, 1, 2]);
+    assert_eq!(a.shift_elements_right::<3>(-2).to_array(), [-2, -2, -2, 1]);
+    assert_eq!(a.shift_elements_right::<4>(-3).to_array(), [-3, -3, -3, -3]);
+    assert_eq!(a.shift_elements_right::<5>(-4).to_array(), [-4, -4, -4, -4]);
+}
+
+#[test]
+#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
 fn interleave() {
     let a = Simd::from_array([0, 1, 2, 3, 4, 5, 6, 7]);
     let b = Simd::from_array([8, 9, 10, 11, 12, 13, 14, 15]);
diff --git a/library/portable-simd/crates/test_helpers/Cargo.toml b/library/portable-simd/crates/test_helpers/Cargo.toml
index 23dae7c9338..a5359b9abc8 100644
--- a/library/portable-simd/crates/test_helpers/Cargo.toml
+++ b/library/portable-simd/crates/test_helpers/Cargo.toml
@@ -6,6 +6,3 @@ publish = false
 
 [dependencies]
 proptest = { version = "0.10", default-features = false, features = ["alloc"] }
-
-[features]
-all_lane_counts = []
diff --git a/library/portable-simd/crates/test_helpers/src/lib.rs b/library/portable-simd/crates/test_helpers/src/lib.rs
index 51b860a8635..197c920e11e 100644
--- a/library/portable-simd/crates/test_helpers/src/lib.rs
+++ b/library/portable-simd/crates/test_helpers/src/lib.rs
@@ -539,32 +539,22 @@ macro_rules! test_lanes {
                     #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
                     lanes_1 1;
                     lanes_2 2;
-                    lanes_4 4;
-                );
-
-                #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
-                $crate::test_lanes_helper!(
-                    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
-                    lanes_8 8;
-                    lanes_16 16;
-                    lanes_32 32;
-                    lanes_64 64;
-                );
-
-                #[cfg(feature = "all_lane_counts")]
-                $crate::test_lanes_helper!(
-                    // test some odd and even non-power-of-2 lengths on miri
-                    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
+                    // Cover an odd and an even non-power-of-2 length in Miri.
+                    // (Even non-power-of-2 vectors have alignment between element
+                    // and vector size, so we want to cover that case as well.)
                     lanes_3 3;
-                    lanes_5 5;
+
                     lanes_6 6;
                 );
 
-                #[cfg(feature = "all_lane_counts")]
                 #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
                 $crate::test_lanes_helper!(
                     #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
+                    lanes_4 4;
+                    lanes_5 5;
+
                     lanes_7 7;
+                    lanes_8 8;
                     lanes_9 9;
                     lanes_10 10;
                     lanes_11 11;
@@ -572,52 +562,55 @@ macro_rules! test_lanes {
                     lanes_13 13;
                     lanes_14 14;
                     lanes_15 15;
+                    lanes_16 16;
                     lanes_17 17;
-                    lanes_18 18;
-                    lanes_19 19;
-                    lanes_20 20;
-                    lanes_21 21;
-                    lanes_22 22;
-                    lanes_23 23;
+                    //lanes_18 18;
+                    //lanes_19 19;
+                    //lanes_20 20;
+                    //lanes_21 21;
+                    //lanes_22 22;
+                    //lanes_23 23;
                     lanes_24 24;
-                    lanes_25 25;
-                    lanes_26 26;
-                    lanes_27 27;
-                    lanes_28 28;
-                    lanes_29 29;
-                    lanes_30 30;
-                    lanes_31 31;
-                    lanes_33 33;
-                    lanes_34 34;
-                    lanes_35 35;
-                    lanes_36 36;
-                    lanes_37 37;
-                    lanes_38 38;
-                    lanes_39 39;
-                    lanes_40 40;
-                    lanes_41 41;
-                    lanes_42 42;
-                    lanes_43 43;
-                    lanes_44 44;
-                    lanes_45 45;
-                    lanes_46 46;
+                    //lanes_25 25;
+                    //lanes_26 26;
+                    //lanes_27 27;
+                    //lanes_28 28;
+                    //lanes_29 29;
+                    //lanes_30 30;
+                    //lanes_31 31;
+                    lanes_32 32;
+                    //lanes_33 33;
+                    //lanes_34 34;
+                    //lanes_35 35;
+                    //lanes_36 36;
+                    //lanes_37 37;
+                    //lanes_38 38;
+                    //lanes_39 39;
+                    //lanes_40 40;
+                    //lanes_41 41;
+                    //lanes_42 42;
+                    //lanes_43 43;
+                    //lanes_44 44;
+                    //lanes_45 45;
+                    //lanes_46 46;
                     lanes_47 47;
-                    lanes_48 48;
-                    lanes_49 49;
-                    lanes_50 50;
-                    lanes_51 51;
-                    lanes_52 52;
-                    lanes_53 53;
-                    lanes_54 54;
-                    lanes_55 55;
+                    //lanes_48 48;
+                    //lanes_49 49;
+                    //lanes_50 50;
+                    //lanes_51 51;
+                    //lanes_52 52;
+                    //lanes_53 53;
+                    //lanes_54 54;
+                    //lanes_55 55;
                     lanes_56 56;
                     lanes_57 57;
-                    lanes_58 58;
-                    lanes_59 59;
-                    lanes_60 60;
-                    lanes_61 61;
-                    lanes_62 62;
+                    //lanes_58 58;
+                    //lanes_59 59;
+                    //lanes_60 60;
+                    //lanes_61 61;
+                    //lanes_62 62;
                     lanes_63 63;
+                    lanes_64 64;
                 );
             }
         )*
@@ -639,36 +632,24 @@ macro_rules! test_lanes_panic {
                     core_simd::simd::LaneCount<$lanes>: core_simd::simd::SupportedLaneCount,
                 $body
 
+                // test some odd and even non-power-of-2 lengths on miri
                 $crate::test_lanes_helper!(
                     #[should_panic];
                     lanes_1 1;
                     lanes_2 2;
-                    lanes_4 4;
-                );
-
-                #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
-                $crate::test_lanes_helper!(
-                    #[should_panic];
-                    lanes_8 8;
-                    lanes_16 16;
-                    lanes_32 32;
-                    lanes_64 64;
-                );
-
-                #[cfg(feature = "all_lane_counts")]
-                $crate::test_lanes_helper!(
-                    // test some odd and even non-power-of-2 lengths on miri
-                    #[should_panic];
                     lanes_3 3;
-                    lanes_5 5;
+
                     lanes_6 6;
                 );
 
-                #[cfg(feature = "all_lane_counts")]
                 #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
                 $crate::test_lanes_helper!(
                     #[should_panic];
+                    lanes_4 4;
+                    lanes_5 5;
+
                     lanes_7 7;
+                    lanes_8 8;
                     lanes_9 9;
                     lanes_10 10;
                     lanes_11 11;
@@ -676,52 +657,55 @@ macro_rules! test_lanes_panic {
                     lanes_13 13;
                     lanes_14 14;
                     lanes_15 15;
+                    lanes_16 16;
                     lanes_17 17;
-                    lanes_18 18;
-                    lanes_19 19;
-                    lanes_20 20;
-                    lanes_21 21;
-                    lanes_22 22;
-                    lanes_23 23;
+                    //lanes_18 18;
+                    //lanes_19 19;
+                    //lanes_20 20;
+                    //lanes_21 21;
+                    //lanes_22 22;
+                    //lanes_23 23;
                     lanes_24 24;
-                    lanes_25 25;
-                    lanes_26 26;
-                    lanes_27 27;
-                    lanes_28 28;
-                    lanes_29 29;
-                    lanes_30 30;
-                    lanes_31 31;
-                    lanes_33 33;
-                    lanes_34 34;
-                    lanes_35 35;
-                    lanes_36 36;
-                    lanes_37 37;
-                    lanes_38 38;
-                    lanes_39 39;
-                    lanes_40 40;
-                    lanes_41 41;
-                    lanes_42 42;
-                    lanes_43 43;
-                    lanes_44 44;
-                    lanes_45 45;
-                    lanes_46 46;
+                    //lanes_25 25;
+                    //lanes_26 26;
+                    //lanes_27 27;
+                    //lanes_28 28;
+                    //lanes_29 29;
+                    //lanes_30 30;
+                    //lanes_31 31;
+                    lanes_32 32;
+                    //lanes_33 33;
+                    //lanes_34 34;
+                    //lanes_35 35;
+                    //lanes_36 36;
+                    //lanes_37 37;
+                    //lanes_38 38;
+                    //lanes_39 39;
+                    //lanes_40 40;
+                    //lanes_41 41;
+                    //lanes_42 42;
+                    //lanes_43 43;
+                    //lanes_44 44;
+                    //lanes_45 45;
+                    //lanes_46 46;
                     lanes_47 47;
-                    lanes_48 48;
-                    lanes_49 49;
-                    lanes_50 50;
-                    lanes_51 51;
-                    lanes_52 52;
-                    lanes_53 53;
-                    lanes_54 54;
-                    lanes_55 55;
+                    //lanes_48 48;
+                    //lanes_49 49;
+                    //lanes_50 50;
+                    //lanes_51 51;
+                    //lanes_52 52;
+                    //lanes_53 53;
+                    //lanes_54 54;
+                    //lanes_55 55;
                     lanes_56 56;
                     lanes_57 57;
-                    lanes_58 58;
-                    lanes_59 59;
-                    lanes_60 60;
-                    lanes_61 61;
-                    lanes_62 62;
+                    //lanes_58 58;
+                    //lanes_59 59;
+                    //lanes_60 60;
+                    //lanes_61 61;
+                    //lanes_62 62;
                     lanes_63 63;
+                    lanes_64 64;
                 );
             }
         )*
diff --git a/library/portable-simd/rust-toolchain.toml b/library/portable-simd/rust-toolchain.toml
new file mode 100644
index 00000000000..d17c6d2e889
--- /dev/null
+++ b/library/portable-simd/rust-toolchain.toml
@@ -0,0 +1,3 @@
+[toolchain]
+channel = "nightly-2025-01-16"
+components = ["rustfmt", "clippy", "miri", "rust-src"]
diff --git a/library/portable-simd/subtree-sync.sh b/library/portable-simd/subtree-sync.sh
new file mode 100755
index 00000000000..18360077623
--- /dev/null
+++ b/library/portable-simd/subtree-sync.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+set -eou pipefail
+
+git fetch origin
+pushd $2
+git fetch origin
+popd
+
+if [ "$(git rev-parse --show-prefix)" != "" ]; then
+    echo "Run this script from the git root" >&2
+    exit 1
+fi
+
+if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/master)" ]; then
+    echo "$(pwd) is not at origin/master" >&2
+    exit 1
+fi
+
+if [ ! -f library/portable-simd/git-subtree.sh ]; then
+    curl -sS https://raw.githubusercontent.com/bjorn3/git/tqc-subtree-portable/contrib/subtree/git-subtree.sh -o library/portable-simd/git-subtree.sh
+    chmod +x library/portable-simd/git-subtree.sh
+fi
+
+today=$(date +%Y-%m-%d)
+
+case $1 in
+    "push")
+        upstream=rust-upstream-$today
+        merge=sync-from-rust-$today
+
+        pushd $2
+        git checkout master
+        git pull
+        popd
+
+        library/portable-simd/git-subtree.sh push -P library/portable-simd $2 $upstream
+
+        pushd $2
+        git checkout -B $merge origin/master
+        git merge $upstream
+        popd
+        echo "Branch \`$merge\` created in \`$2\`. You may need to resolve merge conflicts."
+        ;;
+    "pull")
+        branch=sync-from-portable-simd-$today
+
+        git checkout -B $branch
+        echo "Creating branch \`$branch\`... You may need to resolve merge conflicts."
+        library/portable-simd/git-subtree.sh pull -P library/portable-simd $2 origin/master
+        ;;
+esac
diff --git a/library/rtstartup/rsbegin.rs b/library/rtstartup/rsbegin.rs
index d3ff5c14aa4..67b09599d9d 100644
--- a/library/rtstartup/rsbegin.rs
+++ b/library/rtstartup/rsbegin.rs
@@ -52,7 +52,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 #[cfg(all(target_os = "windows", target_arch = "x86", target_env = "gnu"))]
 pub mod eh_frames {
     #[no_mangle]
-    #[link_section = ".eh_frame"]
+    #[unsafe(link_section = ".eh_frame")]
     // Marks beginning of the stack frame unwind info section
     pub static __EH_FRAME_BEGIN__: [u8; 0] = [];
 
@@ -76,7 +76,7 @@ pub mod eh_frames {
     }
 
     // Unwind info registration/deregistration routines.
-    extern "C" {
+    unsafe extern "C" {
         fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
         fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
     }
@@ -101,10 +101,10 @@ pub mod eh_frames {
         // end of the list. Since constructors are run in reverse order, this ensures that our
         // callbacks are the first and last ones executed.
 
-        #[link_section = ".ctors.65535"] // .ctors.* : C initialization callbacks
+        #[unsafe(link_section = ".ctors.65535")] // .ctors.* : C initialization callbacks
         pub static P_INIT: unsafe extern "C" fn() = super::init;
 
-        #[link_section = ".dtors.65535"] // .dtors.* : C termination callbacks
+        #[unsafe(link_section = ".dtors.65535")] // .dtors.* : C termination callbacks
         pub static P_UNINIT: unsafe extern "C" fn() = super::uninit;
     }
 }
diff --git a/library/rtstartup/rsend.rs b/library/rtstartup/rsend.rs
index 81acfbed447..a6f7d103356 100644
--- a/library/rtstartup/rsend.rs
+++ b/library/rtstartup/rsend.rs
@@ -32,6 +32,6 @@ pub mod eh_frames {
     // Terminate the frame unwind info section with a 0 as a sentinel;
     // this would be the 'length' field in a real FDE.
     #[no_mangle]
-    #[link_section = ".eh_frame"]
+    #[unsafe(link_section = ".eh_frame")]
     pub static __EH_FRAME_END__: u32 = 0;
 }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index aa391a4b317..add5a20d179 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.145" }
+compiler_builtins = { version = "=0.1.146" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index 5d51d6a0c78..3936ed057e6 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -345,7 +345,7 @@ pub fn take_alloc_error_hook() -> fn(Layout) {
 }
 
 fn default_alloc_error_hook(layout: Layout) {
-    extern "Rust" {
+    unsafe extern "Rust" {
         // This symbol is emitted by rustc next to __rust_alloc_error_handler.
         // Its value depends on the -Zoom={panic,abort} compiler option.
         static __rust_alloc_error_handler_should_panic: u8;
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 5013826cb9b..6a0ff3a29e0 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -282,7 +282,7 @@ impl<K, V, S> HashMap<K, V, S> {
     /// manually using this function can expose a DoS attack vector.
     ///
     /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
-    /// the HashMap to be useful, see its documentation for details.
+    /// the `HashMap` to be useful, see its documentation for details.
     ///
     /// # Examples
     ///
@@ -314,7 +314,7 @@ impl<K, V, S> HashMap<K, V, S> {
     /// manually using this function can expose a DoS attack vector.
     ///
     /// The `hasher` passed should implement the [`BuildHasher`] trait for
-    /// the HashMap to be useful, see its documentation for details.
+    /// the `HashMap` to be useful, see its documentation for details.
     ///
     /// # Examples
     ///
@@ -1283,7 +1283,7 @@ impl<K, V, S> HashMap<K, V, S>
 where
     S: BuildHasher,
 {
-    /// Creates a raw entry builder for the HashMap.
+    /// Creates a raw entry builder for the `HashMap`.
     ///
     /// Raw entries provide the lowest level of control for searching and
     /// manipulating a map. They must be manually initialized with a hash and
@@ -1298,13 +1298,13 @@ where
     /// * Using custom comparison logic without newtype wrappers
     ///
     /// Because raw entries provide much more low-level control, it's much easier
-    /// to put the HashMap into an inconsistent state which, while memory-safe,
+    /// to put the `HashMap` into an inconsistent state which, while memory-safe,
     /// will cause the map to produce seemingly random results. Higher-level and
     /// more foolproof APIs like `entry` should be preferred when possible.
     ///
     /// In particular, the hash used to initialize the raw entry must still be
     /// consistent with the hash of the key that is ultimately stored in the entry.
-    /// This is because implementations of HashMap may need to recompute hashes
+    /// This is because implementations of `HashMap` may need to recompute hashes
     /// when resizing, at which point only the keys are available.
     ///
     /// Raw entries give mutable access to the keys. This must not be used
@@ -1320,7 +1320,7 @@ where
         RawEntryBuilderMut { map: self }
     }
 
-    /// Creates a raw immutable entry builder for the HashMap.
+    /// Creates a raw immutable entry builder for the `HashMap`.
     ///
     /// Raw entries provide the lowest level of control for searching and
     /// manipulating a map. They must be manually initialized with a hash and
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index bbb6ca23521..c265d42d06a 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -374,7 +374,7 @@ impl<T, S> HashSet<T, S> {
     /// manually using this function can expose a DoS attack vector.
     ///
     /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
-    /// the HashMap to be useful, see its documentation for details.
+    /// the `HashSet` to be useful, see its documentation for details.
     ///
     /// # Examples
     ///
@@ -406,7 +406,7 @@ impl<T, S> HashSet<T, S> {
     /// manually using this function can expose a DoS attack vector.
     ///
     /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
-    /// the HashMap to be useful, see its documentation for details.
+    /// the `HashSet` to be useful, see its documentation for details.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index a5b0111adfb..0871a9e22d3 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2307,8 +2307,8 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 ///
 /// # Platform-specific behavior
 ///
-/// This function currently corresponds to the `unlink` function on Unix
-/// and the `DeleteFile` function on Windows.
+/// This function currently corresponds to the `unlink` function on Unix.
+/// On Windows, `DeleteFile` is used or `CreateFileW` and `SetInformationByHandle` for readonly files.
 /// Note that, this [may change in the future][changes].
 ///
 /// [changes]: io#platform-specific-behavior
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 28f16da1ed8..8e307f57cf9 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -14,7 +14,7 @@ use crate::os::unix::fs::symlink as junction_point;
 use crate::os::windows::fs::{OpenOptionsExt, junction_point, symlink_dir, symlink_file};
 use crate::path::Path;
 use crate::sync::Arc;
-use crate::sys_common::io::test::{TempDir, tmpdir};
+use crate::test_helpers::{TempDir, tmpdir};
 use crate::time::{Duration, Instant, SystemTime};
 use crate::{env, str, thread};
 
@@ -1384,7 +1384,7 @@ fn file_try_clone() {
 }
 
 #[test]
-#[cfg(not(windows))]
+#[cfg(not(target_vendor = "win7"))]
 fn unlink_readonly() {
     let tmpdir = tmpdir();
     let path = tmpdir.join("file");
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 38b72336617..30bc0e3b088 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -83,7 +83,7 @@ impl Error {
 
     pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_error!(
         ErrorKind::NotFound,
-        "The number of hardware threads is not known for the target platform"
+        "The number of hardware threads is not known for the target platform",
     );
 
     pub(crate) const UNSUPPORTED_PLATFORM: Self =
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index cfd03b8e3d6..0ffad2c27a4 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -344,7 +344,7 @@ pub mod prelude;
 mod stdio;
 mod util;
 
-const DEFAULT_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
+const DEFAULT_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
 
 pub(crate) use stdio::cleanup;
 
diff --git a/library/std/src/io/stdio/tests.rs b/library/std/src/io/stdio/tests.rs
index bf8f3a5adfb..e68d8c29fbc 100644
--- a/library/std/src/io/stdio/tests.rs
+++ b/library/std/src/io/stdio/tests.rs
@@ -159,7 +159,8 @@ where
     assert_eq!(rx2.recv().unwrap(), Release2); // release th2
     th2.join().unwrap();
     th1.join().unwrap();
-    assert_eq!(*log.lock().unwrap(), [
-        Start1, Acquire1, Start2, Release1, Acquire2, Release2, Acquire1, Release1
-    ]);
+    assert_eq!(
+        *log.lock().unwrap(),
+        [Start1, Acquire1, Start2, Release1, Acquire2, Release2, Acquire1, Release1]
+    );
 }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 7c18226874c..954a4182fbd 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -739,27 +739,4 @@ mod sealed {
 
 #[cfg(test)]
 #[allow(dead_code)] // Not used in all configurations.
-pub(crate) mod test_helpers {
-    /// Test-only replacement for `rand::thread_rng()`, which is unusable for
-    /// us, as we want to allow running stdlib tests on tier-3 targets which may
-    /// not have `getrandom` support.
-    ///
-    /// Does a bit of a song and dance to ensure that the seed is different on
-    /// each call (as some tests sadly rely on this), but doesn't try that hard.
-    ///
-    /// This is duplicated in the `core`, `alloc` test suites (as well as
-    /// `std`'s integration tests), but figuring out a mechanism to share these
-    /// seems far more painful than copy-pasting a 7 line function a couple
-    /// times, given that even under a perma-unstable feature, I don't think we
-    /// want to expose types from `rand` from `std`.
-    #[track_caller]
-    pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
-        use core::hash::{BuildHasher, Hash, Hasher};
-        let mut hasher = crate::hash::RandomState::new().build_hasher();
-        core::panic::Location::caller().hash(&mut hasher);
-        let hc64 = hasher.finish();
-        let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
-        let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
-        rand::SeedableRng::from_seed(seed)
-    }
-}
+pub(crate) mod test_helpers;
diff --git a/library/std/src/net/test.rs b/library/std/src/net/test.rs
index d318d457f35..a5c3983cd89 100644
--- a/library/std/src/net/test.rs
+++ b/library/std/src/net/test.rs
@@ -5,14 +5,15 @@ use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToS
 use crate::sync::atomic::{AtomicUsize, Ordering};
 
 static PORT: AtomicUsize = AtomicUsize::new(0);
+const BASE_PORT: u16 = 19600;
 
 pub fn next_test_ip4() -> SocketAddr {
-    let port = PORT.fetch_add(1, Ordering::Relaxed) as u16 + base_port();
+    let port = PORT.fetch_add(1, Ordering::Relaxed) as u16 + BASE_PORT;
     SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port))
 }
 
 pub fn next_test_ip6() -> SocketAddr {
-    let port = PORT.fetch_add(1, Ordering::Relaxed) as u16 + base_port();
+    let port = PORT.fetch_add(1, Ordering::Relaxed) as u16 + BASE_PORT;
     SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), port, 0, 0))
 }
 
@@ -30,31 +31,3 @@ pub fn tsa<A: ToSocketAddrs>(a: A) -> Result<Vec<SocketAddr>, String> {
         Err(e) => Err(e.to_string()),
     }
 }
-
-// The bots run multiple builds at the same time, and these builds
-// all want to use ports. This function figures out which workspace
-// it is running in and assigns a port range based on it.
-fn base_port() -> u16 {
-    let cwd = if cfg!(target_env = "sgx") {
-        String::from("sgx")
-    } else {
-        env::current_dir().unwrap().into_os_string().into_string().unwrap()
-    };
-    let dirs = [
-        "32-opt",
-        "32-nopt",
-        "musl-64-opt",
-        "cross-opt",
-        "64-opt",
-        "64-nopt",
-        "64-opt-vg",
-        "64-debug-opt",
-        "all-opt",
-        "snap3",
-        "dist",
-        "sgx",
-    ];
-    dirs.iter().enumerate().find(|&(_, dir)| cwd.contains(dir)).map(|p| p.0).unwrap_or(0) as u16
-        * 1000
-        + 19600
-}
diff --git a/library/std/src/os/unix/fs/tests.rs b/library/std/src/os/unix/fs/tests.rs
index 67f607bd468..db9621c8c20 100644
--- a/library/std/src/os/unix/fs/tests.rs
+++ b/library/std/src/os/unix/fs/tests.rs
@@ -3,7 +3,7 @@ use super::*;
 #[test]
 fn read_vectored_at() {
     let msg = b"preadv is working!";
-    let dir = crate::sys_common::io::test::tmpdir();
+    let dir = crate::test_helpers::tmpdir();
 
     let filename = dir.join("preadv.txt");
     {
@@ -31,7 +31,7 @@ fn read_vectored_at() {
 #[test]
 fn write_vectored_at() {
     let msg = b"pwritev is not working!";
-    let dir = crate::sys_common::io::test::tmpdir();
+    let dir = crate::test_helpers::tmpdir();
 
     let filename = dir.join("preadv.txt");
     {
diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs
index 21e2176185d..0398a535eb5 100644
--- a/library/std/src/os/unix/net/tests.rs
+++ b/library/std/src/os/unix/net/tests.rs
@@ -7,7 +7,7 @@ use crate::os::android::net::{SocketAddrExt, UnixSocketExt};
 use crate::os::linux::net::{SocketAddrExt, UnixSocketExt};
 #[cfg(any(target_os = "android", target_os = "linux"))]
 use crate::os::unix::io::AsRawFd;
-use crate::sys_common::io::test::tmpdir;
+use crate::test_helpers::tmpdir;
 use crate::thread;
 use crate::time::Duration;
 
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 0277b79b8b6..201274cf03a 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -590,10 +590,10 @@ impl<'a> ProcThreadAttributeListBuilder<'a> {
         value_ptr: *const T,
         value_size: usize,
     ) -> Self {
-        self.attributes.insert(attribute, ProcThreadAttributeValue {
-            ptr: value_ptr.cast::<c_void>(),
-            size: value_size,
-        });
+        self.attributes.insert(
+            attribute,
+            ProcThreadAttributeValue { ptr: value_ptr.cast::<c_void>(), size: value_size },
+        );
         self
     }
 
diff --git a/library/std/src/os/xous/ffi/definitions.rs b/library/std/src/os/xous/ffi/definitions.rs
index 1b16849af03..345005bcc78 100644
--- a/library/std/src/os/xous/ffi/definitions.rs
+++ b/library/std/src/os/xous/ffi/definitions.rs
@@ -126,36 +126,42 @@ impl From<i32> for Error {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl core::fmt::Display for Error {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(f, "{}", match self {
-            Error::NoError => "no error occurred",
-            Error::BadAlignment => "memory was not properly aligned",
-            Error::BadAddress => "an invalid address was supplied",
-            Error::OutOfMemory => "the process or service has run out of memory",
-            Error::MemoryInUse => "the requested address is in use",
-            Error::InterruptNotFound => "the requested interrupt does not exist on this platform",
-            Error::InterruptInUse => "the requested interrupt is currently in use",
-            Error::InvalidString => "the specified string was not formatted correctly",
-            Error::ServerExists => "a server with that address already exists",
-            Error::ServerNotFound => "the requetsed server could not be found",
-            Error::ProcessNotFound => "the target process does not exist",
-            Error::ProcessNotChild => "the requested operation can only be done on child processes",
-            Error::ProcessTerminated => "the target process has crashed",
-            Error::Timeout => "the requested operation timed out",
-            Error::InternalError => "an internal error occurred",
-            Error::ServerQueueFull => "the server has too many pending messages",
-            Error::ThreadNotAvailable => "the specified thread does not exist",
-            Error::UnhandledSyscall => "the kernel did not recognize that syscall",
-            Error::InvalidSyscall => "the syscall had incorrect parameters",
-            Error::ShareViolation => "an attempt was made to share memory twice",
-            Error::InvalidThread => "tried to resume a thread that was not ready",
-            Error::InvalidPid => "kernel attempted to use a pid that was not valid",
-            Error::AccessDenied => "no permission to perform the requested operation",
-            Error::UseBeforeInit => "attempt to use a service before initialization finished",
-            Error::DoubleFree => "the requested resource was freed twice",
-            Error::DebugInProgress => "kernel attempted to activate a thread being debugged",
-            Error::InvalidLimit => "process attempted to adjust an invalid limit",
-            Error::UnknownError => "an unknown error occurred",
-        })
+        write!(
+            f,
+            "{}",
+            match self {
+                Error::NoError => "no error occurred",
+                Error::BadAlignment => "memory was not properly aligned",
+                Error::BadAddress => "an invalid address was supplied",
+                Error::OutOfMemory => "the process or service has run out of memory",
+                Error::MemoryInUse => "the requested address is in use",
+                Error::InterruptNotFound =>
+                    "the requested interrupt does not exist on this platform",
+                Error::InterruptInUse => "the requested interrupt is currently in use",
+                Error::InvalidString => "the specified string was not formatted correctly",
+                Error::ServerExists => "a server with that address already exists",
+                Error::ServerNotFound => "the requetsed server could not be found",
+                Error::ProcessNotFound => "the target process does not exist",
+                Error::ProcessNotChild =>
+                    "the requested operation can only be done on child processes",
+                Error::ProcessTerminated => "the target process has crashed",
+                Error::Timeout => "the requested operation timed out",
+                Error::InternalError => "an internal error occurred",
+                Error::ServerQueueFull => "the server has too many pending messages",
+                Error::ThreadNotAvailable => "the specified thread does not exist",
+                Error::UnhandledSyscall => "the kernel did not recognize that syscall",
+                Error::InvalidSyscall => "the syscall had incorrect parameters",
+                Error::ShareViolation => "an attempt was made to share memory twice",
+                Error::InvalidThread => "tried to resume a thread that was not ready",
+                Error::InvalidPid => "kernel attempted to use a pid that was not valid",
+                Error::AccessDenied => "no permission to perform the requested operation",
+                Error::UseBeforeInit => "attempt to use a service before initialization finished",
+                Error::DoubleFree => "the requested resource was freed twice",
+                Error::DebugInProgress => "kernel attempted to activate a thread being debugged",
+                Error::InvalidLimit => "process attempted to adjust an invalid limit",
+                Error::UnknownError => "an unknown error occurred",
+            }
+        )
     }
 }
 
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 8e50bf11dd0..b47b41d4bc5 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -54,11 +54,11 @@ pub static EMPTY_PANIC: fn(&'static str) -> ! =
 // One day this may look a little less ad-hoc with the compiler helping out to
 // hook up these functions, but it is not this day!
 #[allow(improper_ctypes)]
-extern "C" {
+unsafe extern "C" {
     fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static);
 }
 
-extern "Rust" {
+unsafe extern "Rust" {
     /// `PanicPayload` lazily performs allocation only when needed (this avoids
     /// allocations when using the "abort" panic runtime).
     fn __rust_start_panic(payload: &mut dyn PanicPayload) -> u32;
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 97e17acadea..f9f3b488f0d 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -3575,7 +3575,7 @@ impl Error for StripPrefixError {
 pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
     let path = path.as_ref();
     if path.as_os_str().is_empty() {
-        Err(io::const_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",))
+        Err(io::const_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute"))
     } else {
         sys::path::absolute(path)
     }
diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs
index 1323aba38b7..69273d863eb 100644
--- a/library/std/src/process/tests.rs
+++ b/library/std/src/process/tests.rs
@@ -391,154 +391,6 @@ fn test_interior_nul_in_env_value_is_error() {
     }
 }
 
-/// Tests that process creation flags work by debugging a process.
-/// Other creation flags make it hard or impossible to detect
-/// behavioral changes in the process.
-#[test]
-#[cfg(windows)]
-fn test_creation_flags() {
-    use crate::os::windows::process::CommandExt;
-    use crate::sys::c::{BOOL, INFINITE};
-    #[repr(C)]
-    struct DEBUG_EVENT {
-        pub event_code: u32,
-        pub process_id: u32,
-        pub thread_id: u32,
-        // This is a union in the real struct, but we don't
-        // need this data for the purposes of this test.
-        pub _junk: [u8; 164],
-    }
-
-    extern "system" {
-        fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: u32) -> BOOL;
-        fn ContinueDebugEvent(dwProcessId: u32, dwThreadId: u32, dwContinueStatus: u32) -> BOOL;
-    }
-
-    const DEBUG_PROCESS: u32 = 1;
-    const EXIT_PROCESS_DEBUG_EVENT: u32 = 5;
-    const DBG_EXCEPTION_NOT_HANDLED: u32 = 0x80010001;
-
-    let mut child = Command::new("cmd")
-        .creation_flags(DEBUG_PROCESS)
-        .stdin(Stdio::piped())
-        .stdout(Stdio::null())
-        .stderr(Stdio::null())
-        .spawn()
-        .unwrap();
-    child.stdin.take().unwrap().write_all(b"exit\r\n").unwrap();
-    let mut events = 0;
-    let mut event = DEBUG_EVENT { event_code: 0, process_id: 0, thread_id: 0, _junk: [0; 164] };
-    loop {
-        if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) } == 0 {
-            panic!("WaitForDebugEvent failed!");
-        }
-        events += 1;
-
-        if event.event_code == EXIT_PROCESS_DEBUG_EVENT {
-            break;
-        }
-
-        if unsafe {
-            ContinueDebugEvent(event.process_id, event.thread_id, DBG_EXCEPTION_NOT_HANDLED)
-        } == 0
-        {
-            panic!("ContinueDebugEvent failed!");
-        }
-    }
-    assert!(events > 0);
-}
-
-/// Tests proc thread attributes by spawning a process with a custom parent process,
-/// then comparing the parent process ID with the expected parent process ID.
-#[test]
-#[cfg(windows)]
-fn test_proc_thread_attributes() {
-    use crate::mem;
-    use crate::os::windows::io::AsRawHandle;
-    use crate::os::windows::process::{CommandExt, ProcThreadAttributeList};
-    use crate::sys::c::{BOOL, CloseHandle, HANDLE};
-    use crate::sys::cvt;
-
-    #[repr(C)]
-    #[allow(non_snake_case)]
-    struct PROCESSENTRY32W {
-        dwSize: u32,
-        cntUsage: u32,
-        th32ProcessID: u32,
-        th32DefaultHeapID: usize,
-        th32ModuleID: u32,
-        cntThreads: u32,
-        th32ParentProcessID: u32,
-        pcPriClassBase: i32,
-        dwFlags: u32,
-        szExeFile: [u16; 260],
-    }
-
-    extern "system" {
-        fn CreateToolhelp32Snapshot(dwflags: u32, th32processid: u32) -> HANDLE;
-        fn Process32First(hsnapshot: HANDLE, lppe: *mut PROCESSENTRY32W) -> BOOL;
-        fn Process32Next(hsnapshot: HANDLE, lppe: *mut PROCESSENTRY32W) -> BOOL;
-    }
-
-    const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: usize = 0x00020000;
-    const TH32CS_SNAPPROCESS: u32 = 0x00000002;
-
-    struct ProcessDropGuard(crate::process::Child);
-
-    impl Drop for ProcessDropGuard {
-        fn drop(&mut self) {
-            let _ = self.0.kill();
-        }
-    }
-
-    let mut parent = Command::new("cmd");
-    parent.stdout(Stdio::null()).stderr(Stdio::null());
-
-    let parent = ProcessDropGuard(parent.spawn().unwrap());
-
-    let mut child_cmd = Command::new("cmd");
-    child_cmd.stdout(Stdio::null()).stderr(Stdio::null());
-
-    let parent_process_handle = parent.0.as_raw_handle();
-
-    let mut attribute_list = ProcThreadAttributeList::build()
-        .attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parent_process_handle)
-        .finish()
-        .unwrap();
-
-    let child = ProcessDropGuard(child_cmd.spawn_with_attributes(&mut attribute_list).unwrap());
-
-    let h_snapshot = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };
-
-    let mut process_entry = PROCESSENTRY32W {
-        dwSize: mem::size_of::<PROCESSENTRY32W>() as u32,
-        cntUsage: 0,
-        th32ProcessID: 0,
-        th32DefaultHeapID: 0,
-        th32ModuleID: 0,
-        cntThreads: 0,
-        th32ParentProcessID: 0,
-        pcPriClassBase: 0,
-        dwFlags: 0,
-        szExeFile: [0; 260],
-    };
-
-    unsafe { cvt(Process32First(h_snapshot, &mut process_entry as *mut _)) }.unwrap();
-
-    loop {
-        if child.0.id() == process_entry.th32ProcessID {
-            break;
-        }
-        unsafe { cvt(Process32Next(h_snapshot, &mut process_entry as *mut _)) }.unwrap();
-    }
-
-    unsafe { cvt(CloseHandle(h_snapshot)) }.unwrap();
-
-    assert_eq!(parent.0.id(), process_entry.th32ParentProcessID);
-
-    drop(child)
-}
-
 #[test]
 fn test_command_implements_send_sync() {
     fn take_send_sync_type<T: Send + Sync>(_: T) {}
@@ -697,7 +549,7 @@ fn debug_print() {
 #[test]
 #[cfg(windows)]
 fn run_bat_script() {
-    let tempdir = crate::sys_common::io::test::tmpdir();
+    let tempdir = crate::test_helpers::tmpdir();
     let script_path = tempdir.join("hello.cmd");
 
     crate::fs::write(&script_path, "@echo Hello, %~1!").unwrap();
@@ -716,7 +568,7 @@ fn run_bat_script() {
 #[test]
 #[cfg(windows)]
 fn run_canonical_bat_script() {
-    let tempdir = crate::sys_common::io::test::tmpdir();
+    let tempdir = crate::test_helpers::tmpdir();
     let script_path = tempdir.join("hello.cmd");
 
     crate::fs::write(&script_path, "@echo Hello, %~1!").unwrap();
diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs
index 00966ee3ecf..8caa2dcfad9 100644
--- a/library/std/src/sync/mpmc/mod.rs
+++ b/library/std/src/sync/mpmc/mod.rs
@@ -616,9 +616,9 @@ impl<T> Sender<T> {
     #[unstable(feature = "mpmc_channel", issue = "126840")]
     pub fn same_channel(&self, other: &Sender<T>) -> bool {
         match (&self.flavor, &other.flavor) {
-            (SenderFlavor::Array(ref a), SenderFlavor::Array(ref b)) => a == b,
-            (SenderFlavor::List(ref a), SenderFlavor::List(ref b)) => a == b,
-            (SenderFlavor::Zero(ref a), SenderFlavor::Zero(ref b)) => a == b,
+            (SenderFlavor::Array(a), SenderFlavor::Array(b)) => a == b,
+            (SenderFlavor::List(a), SenderFlavor::List(b)) => a == b,
+            (SenderFlavor::Zero(a), SenderFlavor::Zero(b)) => a == b,
             _ => false,
         }
     }
diff --git a/library/std/src/sys/alloc/xous.rs b/library/std/src/sys/alloc/xous.rs
index 321d30e0b11..9d22e16fdf2 100644
--- a/library/std/src/sys/alloc/xous.rs
+++ b/library/std/src/sys/alloc/xous.rs
@@ -8,7 +8,7 @@ use crate::alloc::{GlobalAlloc, Layout, System};
 static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new();
 
 #[cfg(test)]
-extern "Rust" {
+unsafe extern "Rust" {
     #[link_name = "_ZN16__rust_internals3std3sys4xous5alloc8DLMALLOCE"]
     static mut DLMALLOC: dlmalloc::Dlmalloc;
 }
diff --git a/library/std/src/sys/cmath.rs b/library/std/src/sys/cmath.rs
index ee36127cfdf..e3f41f4fdbb 100644
--- a/library/std/src/sys/cmath.rs
+++ b/library/std/src/sys/cmath.rs
@@ -2,7 +2,7 @@
 
 // These symbols are all defined by `libm`,
 // or by `compiler-builtins` on unsupported platforms.
-extern "C" {
+unsafe extern "C" {
     pub fn acos(n: f64) -> f64;
     pub fn asin(n: f64) -> f64;
     pub fn atan(n: f64) -> f64;
diff --git a/library/std/src/sys/pal/hermit/io.rs b/library/std/src/sys/io/io_slice/iovec.rs
index 0424a1ac55a..072191315f7 100644
--- a/library/std/src/sys/pal/hermit/io.rs
+++ b/library/std/src/sys/io/io_slice/iovec.rs
@@ -1,8 +1,13 @@
-use hermit_abi::{c_void, iovec};
+#[cfg(target_os = "hermit")]
+use hermit_abi::iovec;
+#[cfg(target_family = "unix")]
+use libc::iovec;
 
+use crate::ffi::c_void;
 use crate::marker::PhantomData;
-use crate::os::hermit::io::{AsFd, AsRawFd};
 use crate::slice;
+#[cfg(target_os = "solid_asp3")]
+use crate::sys::pal::abi::sockets::iovec;
 
 #[derive(Copy, Clone)]
 #[repr(transparent)]
@@ -80,8 +85,3 @@ impl<'a> IoSliceMut<'a> {
         unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
 }
-
-pub fn is_terminal(fd: &impl AsFd) -> bool {
-    let fd = fd.as_fd();
-    hermit_abi::isatty(fd.as_raw_fd())
-}
diff --git a/library/std/src/sys/pal/unsupported/io.rs b/library/std/src/sys/io/io_slice/unsupported.rs
index 604735d32d5..1572cac6cd7 100644
--- a/library/std/src/sys/pal/unsupported/io.rs
+++ b/library/std/src/sys/io/io_slice/unsupported.rs
@@ -50,7 +50,3 @@ impl<'a> IoSliceMut<'a> {
         self.0
     }
 }
-
-pub fn is_terminal<T>(_: &T) -> bool {
-    false
-}
diff --git a/library/std/src/sys/pal/wasi/io.rs b/library/std/src/sys/io/io_slice/wasi.rs
index 57f81bc6257..87acbbd924e 100644
--- a/library/std/src/sys/pal/wasi/io.rs
+++ b/library/std/src/sys/io/io_slice/wasi.rs
@@ -1,7 +1,4 @@
-#![forbid(unsafe_op_in_unsafe_fn)]
-
 use crate::marker::PhantomData;
-use crate::os::fd::{AsFd, AsRawFd};
 use crate::slice;
 
 #[derive(Copy, Clone)]
@@ -77,8 +74,3 @@ impl<'a> IoSliceMut<'a> {
         unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) }
     }
 }
-
-pub fn is_terminal(fd: &impl AsFd) -> bool {
-    let fd = fd.as_fd();
-    unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
-}
diff --git a/library/std/src/sys/pal/solid/io.rs b/library/std/src/sys/io/io_slice/windows.rs
index 9ef4b7049b6..c3d8ec87c19 100644
--- a/library/std/src/sys/pal/solid/io.rs
+++ b/library/std/src/sys/io/io_slice/windows.rs
@@ -1,86 +1,82 @@
-use libc::c_void;
-
-use super::abi::sockets::iovec;
 use crate::marker::PhantomData;
 use crate::slice;
+use crate::sys::c;
 
 #[derive(Copy, Clone)]
 #[repr(transparent)]
 pub struct IoSlice<'a> {
-    vec: iovec,
+    vec: c::WSABUF,
     _p: PhantomData<&'a [u8]>,
 }
 
 impl<'a> IoSlice<'a> {
     #[inline]
     pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
+        assert!(buf.len() <= u32::MAX as usize);
         IoSlice {
-            vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
+            vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_ptr() as *mut u8 },
             _p: PhantomData,
         }
     }
 
     #[inline]
     pub fn advance(&mut self, n: usize) {
-        if self.vec.iov_len < n {
+        if (self.vec.len as usize) < n {
             panic!("advancing IoSlice beyond its length");
         }
 
         unsafe {
-            self.vec.iov_len -= n;
-            self.vec.iov_base = self.vec.iov_base.add(n);
+            self.vec.len -= n as u32;
+            self.vec.buf = self.vec.buf.add(n);
         }
     }
 
     #[inline]
     pub const fn as_slice(&self) -> &'a [u8] {
-        unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+        unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
     }
 }
 
 #[repr(transparent)]
 pub struct IoSliceMut<'a> {
-    vec: iovec,
+    vec: c::WSABUF,
     _p: PhantomData<&'a mut [u8]>,
 }
 
 impl<'a> IoSliceMut<'a> {
     #[inline]
     pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
+        assert!(buf.len() <= u32::MAX as usize);
         IoSliceMut {
-            vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
+            vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_mut_ptr() },
             _p: PhantomData,
         }
     }
 
     #[inline]
     pub fn advance(&mut self, n: usize) {
-        if self.vec.iov_len < n {
+        if (self.vec.len as usize) < n {
             panic!("advancing IoSliceMut beyond its length");
         }
 
         unsafe {
-            self.vec.iov_len -= n;
-            self.vec.iov_base = self.vec.iov_base.add(n);
+            self.vec.len -= n as u32;
+            self.vec.buf = self.vec.buf.add(n);
         }
     }
 
     #[inline]
     pub fn as_slice(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+        unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
     }
 
     #[inline]
     pub const fn into_slice(self) -> &'a mut [u8] {
-        unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+        unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
     }
 
     #[inline]
     pub fn as_mut_slice(&mut self) -> &mut [u8] {
-        unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+        unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
     }
 }
-
-pub fn is_terminal<T>(_: &T) -> bool {
-    false
-}
diff --git a/library/std/src/sys/io/is_terminal/hermit.rs b/library/std/src/sys/io/is_terminal/hermit.rs
new file mode 100644
index 00000000000..61bdb6f0a54
--- /dev/null
+++ b/library/std/src/sys/io/is_terminal/hermit.rs
@@ -0,0 +1,6 @@
+use crate::os::fd::{AsFd, AsRawFd};
+
+pub fn is_terminal(fd: &impl AsFd) -> bool {
+    let fd = fd.as_fd();
+    hermit_abi::isatty(fd.as_raw_fd())
+}
diff --git a/library/std/src/sys/io/is_terminal/isatty.rs b/library/std/src/sys/io/is_terminal/isatty.rs
new file mode 100644
index 00000000000..6e0b46211b9
--- /dev/null
+++ b/library/std/src/sys/io/is_terminal/isatty.rs
@@ -0,0 +1,6 @@
+use crate::os::fd::{AsFd, AsRawFd};
+
+pub fn is_terminal(fd: &impl AsFd) -> bool {
+    let fd = fd.as_fd();
+    unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
+}
diff --git a/library/std/src/sys/io/is_terminal/unsupported.rs b/library/std/src/sys/io/is_terminal/unsupported.rs
new file mode 100644
index 00000000000..cee4add32fb
--- /dev/null
+++ b/library/std/src/sys/io/is_terminal/unsupported.rs
@@ -0,0 +1,3 @@
+pub fn is_terminal<T>(_: &T) -> bool {
+    false
+}
diff --git a/library/std/src/sys/pal/windows/io.rs b/library/std/src/sys/io/is_terminal/windows.rs
index f2865d2ffc1..3ec18fb47b9 100644
--- a/library/std/src/sys/pal/windows/io.rs
+++ b/library/std/src/sys/io/is_terminal/windows.rs
@@ -1,90 +1,8 @@
-use core::ffi::c_void;
-
-use crate::marker::PhantomData;
+use crate::ffi::c_void;
 use crate::mem::size_of;
 use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle};
-use crate::slice;
 use crate::sys::c;
 
-#[derive(Copy, Clone)]
-#[repr(transparent)]
-pub struct IoSlice<'a> {
-    vec: c::WSABUF,
-    _p: PhantomData<&'a [u8]>,
-}
-
-impl<'a> IoSlice<'a> {
-    #[inline]
-    pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
-        assert!(buf.len() <= u32::MAX as usize);
-        IoSlice {
-            vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_ptr() as *mut u8 },
-            _p: PhantomData,
-        }
-    }
-
-    #[inline]
-    pub fn advance(&mut self, n: usize) {
-        if (self.vec.len as usize) < n {
-            panic!("advancing IoSlice beyond its length");
-        }
-
-        unsafe {
-            self.vec.len -= n as u32;
-            self.vec.buf = self.vec.buf.add(n);
-        }
-    }
-
-    #[inline]
-    pub const fn as_slice(&self) -> &'a [u8] {
-        unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
-    }
-}
-
-#[repr(transparent)]
-pub struct IoSliceMut<'a> {
-    vec: c::WSABUF,
-    _p: PhantomData<&'a mut [u8]>,
-}
-
-impl<'a> IoSliceMut<'a> {
-    #[inline]
-    pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
-        assert!(buf.len() <= u32::MAX as usize);
-        IoSliceMut {
-            vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_mut_ptr() },
-            _p: PhantomData,
-        }
-    }
-
-    #[inline]
-    pub fn advance(&mut self, n: usize) {
-        if (self.vec.len as usize) < n {
-            panic!("advancing IoSliceMut beyond its length");
-        }
-
-        unsafe {
-            self.vec.len -= n as u32;
-            self.vec.buf = self.vec.buf.add(n);
-        }
-    }
-
-    #[inline]
-    pub fn as_slice(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
-    }
-
-    #[inline]
-    pub const fn into_slice(self) -> &'a mut [u8] {
-        unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
-    }
-
-    #[inline]
-    pub fn as_mut_slice(&mut self) -> &mut [u8] {
-        unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
-    }
-}
-
 pub fn is_terminal(h: &impl AsHandle) -> bool {
     handle_is_console(h.as_handle())
 }
diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs
new file mode 100644
index 00000000000..e00b479109f
--- /dev/null
+++ b/library/std/src/sys/io/mod.rs
@@ -0,0 +1,44 @@
+#![forbid(unsafe_op_in_unsafe_fn)]
+
+mod io_slice {
+    cfg_if::cfg_if! {
+        if #[cfg(any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3"))] {
+            mod iovec;
+            pub use iovec::*;
+        } else if #[cfg(target_os = "windows")] {
+            mod windows;
+            pub use windows::*;
+        } else if #[cfg(target_os = "wasi")] {
+            mod wasi;
+            pub use wasi::*;
+        } else {
+            mod unsupported;
+            pub use unsupported::*;
+        }
+    }
+}
+
+mod is_terminal {
+    cfg_if::cfg_if! {
+        if #[cfg(any(target_family = "unix", target_os = "wasi"))] {
+            mod isatty;
+            pub use isatty::*;
+        } else if #[cfg(target_os = "windows")] {
+            mod windows;
+            pub use windows::*;
+        } else if #[cfg(target_os = "hermit")] {
+            mod hermit;
+            pub use hermit::*;
+        } else {
+            mod unsupported;
+            pub use unsupported::*;
+        }
+    }
+}
+
+pub use io_slice::{IoSlice, IoSliceMut};
+pub use is_terminal::is_terminal;
+
+// Bare metal platforms usually have very small amounts of RAM
+// (in the order of hundreds of KB)
+pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 };
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 39a0bc6e337..1032fcba5e2 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -12,6 +12,7 @@ pub mod anonymous_pipe;
 pub mod backtrace;
 pub mod cmath;
 pub mod exit_guard;
+pub mod io;
 pub mod net;
 pub mod os_str;
 pub mod path;
diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs
new file mode 100644
index 00000000000..87e6106468f
--- /dev/null
+++ b/library/std/src/sys/net/connection/uefi/mod.rs
@@ -0,0 +1,369 @@
+use crate::fmt;
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
+use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
+use crate::sys::unsupported;
+use crate::time::Duration;
+
+pub struct TcpStream(!);
+
+impl TcpStream {
+    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
+        unsupported()
+    }
+
+    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
+        unsupported()
+    }
+
+    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        self.0
+    }
+
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        self.0
+    }
+
+    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn is_read_vectored(&self) -> bool {
+        self.0
+    }
+
+    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn is_write_vectored(&self) -> bool {
+        self.0
+    }
+
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        self.0
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        self.0
+    }
+
+    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn duplicate(&self) -> io::Result<TcpStream> {
+        self.0
+    }
+
+    pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        self.0
+    }
+
+    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn nodelay(&self) -> io::Result<bool> {
+        self.0
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.0
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.0
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        self.0
+    }
+}
+
+impl fmt::Debug for TcpStream {
+    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0
+    }
+}
+
+pub struct TcpListener(!);
+
+impl TcpListener {
+    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
+        unsupported()
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        self.0
+    }
+
+    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
+        self.0
+    }
+
+    pub fn duplicate(&self) -> io::Result<TcpListener> {
+        self.0
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.0
+    }
+
+    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.0
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.0
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        self.0
+    }
+}
+
+impl fmt::Debug for TcpListener {
+    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0
+    }
+}
+
+pub struct UdpSocket(!);
+
+impl UdpSocket {
+    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
+        unsupported()
+    }
+
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        self.0
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        self.0
+    }
+
+    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.0
+    }
+
+    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.0
+    }
+
+    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn duplicate(&self) -> io::Result<UdpSocket> {
+        self.0
+    }
+
+    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        self.0
+    }
+
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        self.0
+    }
+
+    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn broadcast(&self) -> io::Result<bool> {
+        self.0
+    }
+
+    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
+        self.0
+    }
+
+    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
+        self.0
+    }
+
+    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
+        self.0
+    }
+
+    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.0
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.0
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
+        self.0
+    }
+
+    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
+        self.0
+    }
+}
+
+impl fmt::Debug for UdpSocket {
+    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0
+    }
+}
+
+pub struct LookupHost(!);
+
+impl LookupHost {
+    pub fn port(&self) -> u16 {
+        self.0
+    }
+}
+
+impl Iterator for LookupHost {
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> {
+        self.0
+    }
+}
+
+impl TryFrom<&str> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from(_v: &str) -> io::Result<LookupHost> {
+        unsupported()
+    }
+}
+
+impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
+        unsupported()
+    }
+}
+
+#[allow(nonstandard_style)]
+pub mod netc {
+    pub const AF_INET: u8 = 0;
+    pub const AF_INET6: u8 = 1;
+    pub type sa_family_t = u8;
+
+    #[derive(Copy, Clone)]
+    pub struct in_addr {
+        pub s_addr: u32,
+    }
+
+    #[derive(Copy, Clone)]
+    pub struct sockaddr_in {
+        #[allow(dead_code)]
+        pub sin_family: sa_family_t,
+        pub sin_port: u16,
+        pub sin_addr: in_addr,
+    }
+
+    #[derive(Copy, Clone)]
+    pub struct in6_addr {
+        pub s6_addr: [u8; 16],
+    }
+
+    #[derive(Copy, Clone)]
+    pub struct sockaddr_in6 {
+        #[allow(dead_code)]
+        pub sin6_family: sa_family_t,
+        pub sin6_port: u16,
+        pub sin6_addr: in6_addr,
+        pub sin6_flowinfo: u32,
+        pub sin6_scope_id: u32,
+    }
+}
diff --git a/library/std/src/sys/net/connection/xous/dns.rs b/library/std/src/sys/net/connection/xous/dns.rs
index ff6e49ed2d4..bb29d211fad 100644
--- a/library/std/src/sys/net/connection/xous/dns.rs
+++ b/library/std/src/sys/net/connection/xous/dns.rs
@@ -123,6 +123,6 @@ impl TryFrom<(&str, u16)> for LookupHost {
     type Error = io::Error;
 
     fn try_from(v: (&str, u16)) -> io::Result<LookupHost> {
-        lookup(v.0, v.1).map_err(|_e| io::const_error!(io::ErrorKind::InvalidInput, &"DNS failure"))
+        lookup(v.0, v.1).map_err(|_e| io::const_error!(io::ErrorKind::InvalidInput, "DNS failure"))
     }
 }
diff --git a/library/std/src/sys/net/connection/xous/tcplistener.rs b/library/std/src/sys/net/connection/xous/tcplistener.rs
index 640a02a64f5..851d2eb8178 100644
--- a/library/std/src/sys/net/connection/xous/tcplistener.rs
+++ b/library/std/src/sys/net/connection/xous/tcplistener.rs
@@ -11,7 +11,7 @@ macro_rules! unimpl {
     () => {
         return Err(io::const_error!(
             io::ErrorKind::Unsupported,
-            &"This function is not yet implemented",
+            "This function is not yet implemented",
         ));
     };
 }
@@ -71,7 +71,7 @@ impl TcpListener {
             0,
             4096,
         ) else {
-            return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, "Invalid response"));
         };
 
         // The first four bytes should be zero upon success, and will be nonzero
@@ -80,15 +80,15 @@ impl TcpListener {
         if response[0] != 0 || valid == 0 {
             let errcode = response[1];
             if errcode == NetError::SocketInUse as u8 {
-                return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use"));
+                return Err(io::const_error!(io::ErrorKind::ResourceBusy, "Socket in use"));
             } else if errcode == NetError::Invalid as u8 {
-                return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address"));
+                return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, "Invalid address"));
             } else if errcode == NetError::LibraryError as u8 {
-                return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
+                return Err(io::const_error!(io::ErrorKind::Other, "Library error"));
             } else {
                 return Err(io::const_error!(
                     io::ErrorKind::Other,
-                    &"Unable to connect or internal error"
+                    "Unable to connect or internal error",
                 ));
             }
         }
@@ -127,15 +127,13 @@ impl TcpListener {
             if receive_request.raw[0] != 0 {
                 // error case
                 if receive_request.raw[1] == NetError::TimedOut as u8 {
-                    return Err(io::const_error!(io::ErrorKind::TimedOut, &"accept timed out",));
+                    return Err(io::const_error!(io::ErrorKind::TimedOut, "accept timed out"));
                 } else if receive_request.raw[1] == NetError::WouldBlock as u8 {
-                    return Err(
-                        io::const_error!(io::ErrorKind::WouldBlock, &"accept would block",),
-                    );
+                    return Err(io::const_error!(io::ErrorKind::WouldBlock, "accept would block"));
                 } else if receive_request.raw[1] == NetError::LibraryError as u8 {
-                    return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
+                    return Err(io::const_error!(io::ErrorKind::Other, "Library error"));
                 } else {
-                    return Err(io::const_error!(io::ErrorKind::Other, &"library error",));
+                    return Err(io::const_error!(io::ErrorKind::Other, "library error"));
                 }
             } else {
                 // accept successful
@@ -159,7 +157,7 @@ impl TcpListener {
                         port,
                     )
                 } else {
-                    return Err(io::const_error!(io::ErrorKind::Other, &"library error",));
+                    return Err(io::const_error!(io::ErrorKind::Other, "library error"));
                 };
 
                 // replenish the listener
@@ -171,7 +169,7 @@ impl TcpListener {
                 Ok((TcpStream::from_listener(stream_fd, self.local.port(), port, addr), addr))
             }
         } else {
-            Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to accept"))
+            Err(io::const_error!(io::ErrorKind::InvalidInput, "Unable to accept"))
         }
     }
 
@@ -182,13 +180,13 @@ impl TcpListener {
 
     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
         if ttl > 255 {
-            return Err(io::Error::new(io::ErrorKind::InvalidInput, "TTL must be less than 256"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, "TTL must be less than 256"));
         }
         crate::os::xous::ffi::blocking_scalar(
             services::net_server(),
             services::NetBlockingScalar::StdSetTtlTcp(self.fd.load(Ordering::Relaxed), ttl).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|_| ())
     }
 
@@ -197,7 +195,7 @@ impl TcpListener {
             services::net_server(),
             services::NetBlockingScalar::StdGetTtlTcp(self.fd.load(Ordering::Relaxed)).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|res| res[0] as _)?)
     }
 
diff --git a/library/std/src/sys/net/connection/xous/tcpstream.rs b/library/std/src/sys/net/connection/xous/tcpstream.rs
index 572dd6b3b63..7f7bbfb7fed 100644
--- a/library/std/src/sys/net/connection/xous/tcpstream.rs
+++ b/library/std/src/sys/net/connection/xous/tcpstream.rs
@@ -12,7 +12,7 @@ macro_rules! unimpl {
     () => {
         return Err(io::const_error!(
             io::ErrorKind::Unsupported,
-            &"This function is not yet implemented",
+            "This function is not yet implemented",
         ));
     };
 }
@@ -96,7 +96,7 @@ impl TcpStream {
             0,
             4096,
         ) else {
-            return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, "Invalid response"));
         };
 
         // The first four bytes should be zero upon success, and will be nonzero
@@ -106,13 +106,13 @@ impl TcpStream {
             // errcode is a u8 but stuck in a u16 where the upper byte is invalid. Mask & decode accordingly.
             let errcode = response[0];
             if errcode == NetError::SocketInUse as u8 {
-                return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use",));
+                return Err(io::const_error!(io::ErrorKind::ResourceBusy, "Socket in use"));
             } else if errcode == NetError::Unaddressable as u8 {
-                return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address",));
+                return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, "Invalid address"));
             } else {
                 return Err(io::const_error!(
                     io::ErrorKind::InvalidInput,
-                    &"Unable to connect or internal error",
+                    "Unable to connect or internal error",
                 ));
             }
         }
@@ -198,7 +198,7 @@ impl TcpStream {
         ) else {
             return Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
-                &"Library failure: wrong message type or messaging error"
+                "Library failure: wrong message type or messaging error",
             ));
         };
 
@@ -212,14 +212,14 @@ impl TcpStream {
             if result[0] != 0 {
                 if result[1] == 8 {
                     // timed out
-                    return Err(io::const_error!(io::ErrorKind::TimedOut, &"Timeout",));
+                    return Err(io::const_error!(io::ErrorKind::TimedOut, "Timeout"));
                 }
                 if result[1] == 9 {
                     // would block
-                    return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",));
+                    return Err(io::const_error!(io::ErrorKind::WouldBlock, "Would block"));
                 }
             }
-            Err(io::const_error!(io::ErrorKind::Other, &"recv_slice failure"))
+            Err(io::const_error!(io::ErrorKind::Other, "recv_slice failure"))
         }
     }
 
@@ -258,20 +258,20 @@ impl TcpStream {
             self.write_timeout.load(Ordering::Relaxed) as usize,
             buf_len,
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")))?;
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Internal error")))?;
 
         if send_request.raw[0] != 0 {
             if send_request.raw[4] == 8 {
                 // timed out
                 return Err(io::const_error!(
                     io::ErrorKind::BrokenPipe,
-                    &"Timeout or connection closed",
+                    "Timeout or connection closed",
                 ));
             } else if send_request.raw[4] == 9 {
                 // would block
-                return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",));
+                return Err(io::const_error!(io::ErrorKind::WouldBlock, "Would block"));
             } else {
-                return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Error when sending",));
+                return Err(io::const_error!(io::ErrorKind::InvalidInput, "Error when sending"));
             }
         }
         Ok(u32::from_le_bytes([
@@ -304,7 +304,7 @@ impl TcpStream {
             0,
             0,
         ) else {
-            return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, "Internal error"));
         };
         let mut i = get_addr.raw.iter();
         match *i.next().unwrap() {
@@ -324,7 +324,7 @@ impl TcpStream {
                 }
                 Ok(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.local_port, 0, 0)))
             }
-            _ => Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")),
+            _ => Err(io::const_error!(io::ErrorKind::InvalidInput, "Internal error")),
         }
     }
 
@@ -333,7 +333,7 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdTcpStreamShutdown(self.fd, how).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|_| ())
     }
 
@@ -355,7 +355,7 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdSetNodelay(self.fd, enabled).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|_| ())
     }
 
@@ -364,19 +364,19 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdGetNodelay(self.fd).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|res| res[0] != 0)?)
     }
 
     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
         if ttl > 255 {
-            return Err(io::Error::new(io::ErrorKind::InvalidInput, "TTL must be less than 256"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, "TTL must be less than 256"));
         }
         crate::os::xous::ffi::blocking_scalar(
             services::net_server(),
             services::NetBlockingScalar::StdSetTtlTcp(self.fd, ttl).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|_| ())
     }
 
@@ -385,7 +385,7 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdGetTtlTcp(self.fd).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|res| res[0] as _)?)
     }
 
diff --git a/library/std/src/sys/net/connection/xous/udp.rs b/library/std/src/sys/net/connection/xous/udp.rs
index 1b7ecac6d3a..ab5bd357b61 100644
--- a/library/std/src/sys/net/connection/xous/udp.rs
+++ b/library/std/src/sys/net/connection/xous/udp.rs
@@ -13,7 +13,7 @@ macro_rules! unimpl {
     () => {
         return Err(io::const_error!(
             io::ErrorKind::Unsupported,
-            &"This function is not yet implemented",
+            "This function is not yet implemented",
         ));
     };
 }
@@ -72,18 +72,18 @@ impl UdpSocket {
             if response[0] != 0 || valid == 0 {
                 let errcode = response[1];
                 if errcode == NetError::SocketInUse as u8 {
-                    return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use"));
+                    return Err(io::const_error!(io::ErrorKind::ResourceBusy, "Socket in use"));
                 } else if errcode == NetError::Invalid as u8 {
                     return Err(io::const_error!(
                         io::ErrorKind::InvalidInput,
-                        &"Port can't be 0 or invalid address"
+                        "Port can't be 0 or invalid address",
                     ));
                 } else if errcode == NetError::LibraryError as u8 {
-                    return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
+                    return Err(io::const_error!(io::ErrorKind::Other, "Library error"));
                 } else {
                     return Err(io::const_error!(
                         io::ErrorKind::Other,
-                        &"Unable to connect or internal error"
+                        "Unable to connect or internal error",
                     ));
                 }
             }
@@ -98,13 +98,13 @@ impl UdpSocket {
                 nonblocking: Cell::new(false),
             });
         }
-        Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response"))
+        Err(io::const_error!(io::ErrorKind::InvalidInput, "Invalid response"))
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         match self.remote.get() {
             Some(dest) => Ok(dest),
-            None => Err(io::const_error!(io::ErrorKind::NotConnected, &"No peer specified")),
+            None => Err(io::const_error!(io::ErrorKind::NotConnected, "No peer specified")),
         }
     }
 
@@ -141,13 +141,13 @@ impl UdpSocket {
             if receive_request.raw[0] != 0 {
                 // error case
                 if receive_request.raw[1] == NetError::TimedOut as u8 {
-                    return Err(io::const_error!(io::ErrorKind::TimedOut, &"recv timed out",));
+                    return Err(io::const_error!(io::ErrorKind::TimedOut, "recv timed out"));
                 } else if receive_request.raw[1] == NetError::WouldBlock as u8 {
-                    return Err(io::const_error!(io::ErrorKind::WouldBlock, &"recv would block",));
+                    return Err(io::const_error!(io::ErrorKind::WouldBlock, "recv would block"));
                 } else if receive_request.raw[1] == NetError::LibraryError as u8 {
-                    return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
+                    return Err(io::const_error!(io::ErrorKind::Other, "Library error"));
                 } else {
-                    return Err(io::const_error!(io::ErrorKind::Other, &"library error",));
+                    return Err(io::const_error!(io::ErrorKind::Other, "library error"));
                 }
             } else {
                 let rr = &receive_request.raw;
@@ -170,7 +170,7 @@ impl UdpSocket {
                         port,
                     )
                 } else {
-                    return Err(io::const_error!(io::ErrorKind::Other, &"library error",));
+                    return Err(io::const_error!(io::ErrorKind::Other, "library error"));
                 };
                 for (&s, d) in rr[22..22 + rxlen as usize].iter().zip(buf.iter_mut()) {
                     *d = s;
@@ -178,7 +178,7 @@ impl UdpSocket {
                 Ok((rxlen as usize, addr))
             }
         } else {
-            Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to recv"))
+            Err(io::const_error!(io::ErrorKind::InvalidInput, "Unable to recv"))
         }
     }
 
@@ -208,7 +208,7 @@ impl UdpSocket {
         if let Some(addr) = self.remote.get() {
             self.send_to(buf, &addr)
         } else {
-            Err(io::const_error!(io::ErrorKind::NotConnected, &"No remote specified"))
+            Err(io::const_error!(io::ErrorKind::NotConnected, "No remote specified"))
         }
     }
 
@@ -281,19 +281,19 @@ impl UdpSocket {
                         if errcode == NetError::SocketInUse as u8 {
                             return Err(io::const_error!(
                                 io::ErrorKind::ResourceBusy,
-                                &"Socket in use"
+                                "Socket in use",
                             ));
                         } else if errcode == NetError::Invalid as u8 {
                             return Err(io::const_error!(
                                 io::ErrorKind::InvalidInput,
-                                &"Socket not valid"
+                                "Socket not valid",
                             ));
                         } else if errcode == NetError::LibraryError as u8 {
-                            return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
+                            return Err(io::const_error!(io::ErrorKind::Other, "Library error"));
                         } else {
                             return Err(io::const_error!(
                                 io::ErrorKind::Other,
-                                &"Unable to connect"
+                                "Unable to connect",
                             ));
                         }
                     } else {
@@ -303,16 +303,13 @@ impl UdpSocket {
                 }
                 Err(crate::os::xous::ffi::Error::ServerQueueFull) => {
                     if now.elapsed() >= write_timeout {
-                        return Err(io::const_error!(
-                            io::ErrorKind::WouldBlock,
-                            &"Write timed out"
-                        ));
+                        return Err(io::const_error!(io::ErrorKind::WouldBlock, "Write timed out"));
                     } else {
                         // question: do we want to do something a bit more gentle than immediately retrying?
                         crate::thread::yield_now();
                     }
                 }
-                _ => return Err(io::const_error!(io::ErrorKind::Other, &"Library error")),
+                _ => return Err(io::const_error!(io::ErrorKind::Other, "Library error")),
             }
         }
     }
@@ -360,13 +357,13 @@ impl UdpSocket {
 
     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
         if ttl > 255 {
-            return Err(io::Error::new(io::ErrorKind::InvalidInput, "TTL must be less than 256"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, "TTL must be less than 256"));
         }
         crate::os::xous::ffi::blocking_scalar(
             services::net_server(),
             services::NetBlockingScalar::StdSetTtlUdp(self.fd, ttl).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|_| ())
     }
 
@@ -375,7 +372,7 @@ impl UdpSocket {
             services::net_server(),
             services::NetBlockingScalar::StdGetTtlUdp(self.fd).into(),
         )
-        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value")))
         .map(|res| res[0] as _)?)
     }
 
@@ -441,7 +438,7 @@ impl UdpSocket {
 
 impl fmt::Debug for UdpSocket {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "UDP listening on {:?} to {:?}", self.local, self.remote.get(),)
+        write!(f, "UDP listening on {:?} to {:?}", self.local, self.remote.get())
     }
 }
 
diff --git a/library/std/src/sys/net/mod.rs b/library/std/src/sys/net/mod.rs
index 5aa197fbc0d..646679a1cc8 100644
--- a/library/std/src/sys/net/mod.rs
+++ b/library/std/src/sys/net/mod.rs
@@ -25,6 +25,11 @@ cfg_if::cfg_if! {
             mod xous;
             pub use xous::*;
         }
+    } else if #[cfg(target_os = "uefi")] {
+        mod connection {
+            mod uefi;
+            pub use uefi::*;
+        }
     } else {
         mod connection {
             mod unsupported;
diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs
index 783623552bb..7bc36717f34 100644
--- a/library/std/src/sys/pal/hermit/fs.rs
+++ b/library/std/src/sys/pal/hermit/fs.rs
@@ -304,16 +304,12 @@ impl OpenOptions {
             (true, false) => {}
             (false, false) => {
                 if self.truncate || self.create || self.create_new {
-                    return Err(
-                        io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",),
-                    );
+                    return Err(io::const_error!(ErrorKind::InvalidInput, "invalid creation mode"));
                 }
             }
             (_, true) => {
                 if self.truncate && !self.create_new {
-                    return Err(
-                        io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",),
-                    );
+                    return Err(io::const_error!(ErrorKind::InvalidInput, "invalid creation mode"));
                 }
             }
         }
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index 032007aa4dc..a746b853cbd 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -23,7 +23,6 @@ pub mod env;
 pub mod fd;
 pub mod fs;
 pub mod futex;
-pub mod io;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
@@ -79,7 +78,7 @@ pub unsafe extern "C" fn runtime_entry(
     argv: *const *const c_char,
     env: *const *const c_char,
 ) -> ! {
-    extern "C" {
+    unsafe extern "C" {
         fn main(argc: isize, argv: *const *const c_char) -> i32;
     }
 
diff --git a/library/std/src/sys/pal/itron/abi.rs b/library/std/src/sys/pal/itron/abi.rs
index 5eb14bb7e53..49b5251fc0e 100644
--- a/library/std/src/sys/pal/itron/abi.rs
+++ b/library/std/src/sys/pal/itron/abi.rs
@@ -132,7 +132,7 @@ pub struct T_CTSK {
     pub stk: *mut u8,
 }
 
-extern "C" {
+unsafe extern "C" {
     #[link_name = "__asp3_acre_tsk"]
     pub fn acre_tsk(pk_ctsk: *const T_CTSK) -> ER_ID;
     #[link_name = "__asp3_get_tid"]
diff --git a/library/std/src/sys/pal/itron/time/tests.rs b/library/std/src/sys/pal/itron/time/tests.rs
index 28db4f8b679..d14035d9da4 100644
--- a/library/std/src/sys/pal/itron/time/tests.rs
+++ b/library/std/src/sys/pal/itron/time/tests.rs
@@ -8,24 +8,26 @@ fn reltim2dur(t: u64) -> Duration {
 fn test_dur2reltims() {
     assert_eq!(dur2reltims(reltim2dur(0)).collect::<Vec<_>>(), vec![]);
     assert_eq!(dur2reltims(reltim2dur(42)).collect::<Vec<_>>(), vec![42]);
-    assert_eq!(dur2reltims(reltim2dur(abi::TMAX_RELTIM as u64)).collect::<Vec<_>>(), vec![
-        abi::TMAX_RELTIM
-    ]);
-    assert_eq!(dur2reltims(reltim2dur(abi::TMAX_RELTIM as u64 + 10000)).collect::<Vec<_>>(), vec![
-        abi::TMAX_RELTIM,
-        10000
-    ]);
+    assert_eq!(
+        dur2reltims(reltim2dur(abi::TMAX_RELTIM as u64)).collect::<Vec<_>>(),
+        vec![abi::TMAX_RELTIM]
+    );
+    assert_eq!(
+        dur2reltims(reltim2dur(abi::TMAX_RELTIM as u64 + 10000)).collect::<Vec<_>>(),
+        vec![abi::TMAX_RELTIM, 10000]
+    );
 }
 
 #[test]
 fn test_dur2tmos() {
     assert_eq!(dur2tmos(reltim2dur(0)).collect::<Vec<_>>(), vec![0]);
     assert_eq!(dur2tmos(reltim2dur(42)).collect::<Vec<_>>(), vec![42]);
-    assert_eq!(dur2tmos(reltim2dur(abi::TMAX_RELTIM as u64)).collect::<Vec<_>>(), vec![
-        abi::TMAX_RELTIM
-    ]);
-    assert_eq!(dur2tmos(reltim2dur(abi::TMAX_RELTIM as u64 + 10000)).collect::<Vec<_>>(), vec![
-        abi::TMAX_RELTIM,
-        10000
-    ]);
+    assert_eq!(
+        dur2tmos(reltim2dur(abi::TMAX_RELTIM as u64)).collect::<Vec<_>>(),
+        vec![abi::TMAX_RELTIM]
+    );
+    assert_eq!(
+        dur2tmos(reltim2dur(abi::TMAX_RELTIM as u64 + 10000)).collect::<Vec<_>>(),
+        vec![abi::TMAX_RELTIM, 10000]
+    );
 }
diff --git a/library/std/src/sys/pal/sgx/abi/mem.rs b/library/std/src/sys/pal/sgx/abi/mem.rs
index 18e6d5b3fa2..e6ce15bed3c 100644
--- a/library/std/src/sys/pal/sgx/abi/mem.rs
+++ b/library/std/src/sys/pal/sgx/abi/mem.rs
@@ -12,7 +12,7 @@ pub(crate) unsafe fn rel_ptr_mut<T>(offset: u64) -> *mut T {
     (image_base() + offset) as *mut T
 }
 
-extern "C" {
+unsafe extern "C" {
     static ENCLAVE_SIZE: usize;
     static HEAP_BASE: u64;
     static HEAP_SIZE: usize;
diff --git a/library/std/src/sys/pal/sgx/abi/mod.rs b/library/std/src/sys/pal/sgx/abi/mod.rs
index d8836452e75..f52acc41509 100644
--- a/library/std/src/sys/pal/sgx/abi/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/mod.rs
@@ -73,7 +73,7 @@ extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64
 
         EntryReturn(0, 0)
     } else {
-        extern "C" {
+        unsafe extern "C" {
             fn main(argc: isize, argv: *const *const u8) -> isize;
         }
 
diff --git a/library/std/src/sys/pal/sgx/abi/panic.rs b/library/std/src/sys/pal/sgx/abi/panic.rs
index c06b97ee367..67af062b0ff 100644
--- a/library/std/src/sys/pal/sgx/abi/panic.rs
+++ b/library/std/src/sys/pal/sgx/abi/panic.rs
@@ -2,7 +2,7 @@ use super::usercalls::alloc::UserRef;
 use crate::io::{self, Write};
 use crate::{cmp, mem};
 
-extern "C" {
+unsafe extern "C" {
     fn take_debug_panic_buf_ptr() -> *mut u8;
     static DEBUG: u8;
 }
diff --git a/library/std/src/sys/pal/sgx/abi/reloc.rs b/library/std/src/sys/pal/sgx/abi/reloc.rs
index 02dff0ad29f..a4f5e4a0936 100644
--- a/library/std/src/sys/pal/sgx/abi/reloc.rs
+++ b/library/std/src/sys/pal/sgx/abi/reloc.rs
@@ -11,7 +11,7 @@ struct Rela<T> {
 }
 
 pub fn relocate_elf_rela() {
-    extern "C" {
+    unsafe extern "C" {
         static RELA: u64;
         static RELACOUNT: usize;
     }
diff --git a/library/std/src/sys/pal/sgx/abi/thread.rs b/library/std/src/sys/pal/sgx/abi/thread.rs
index 2b23e368cc3..9b37e2baf36 100644
--- a/library/std/src/sys/pal/sgx/abi/thread.rs
+++ b/library/std/src/sys/pal/sgx/abi/thread.rs
@@ -6,7 +6,7 @@ use fortanix_sgx_abi::Tcs;
 /// is a one-to-one correspondence of the ID to the address of the TCS.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn current() -> Tcs {
-    extern "C" {
+    unsafe extern "C" {
         fn get_tcs_addr() -> *mut u8;
     }
     let addr = unsafe { get_tcs_addr() };
diff --git a/library/std/src/sys/pal/sgx/abi/tls/mod.rs b/library/std/src/sys/pal/sgx/abi/tls/mod.rs
index 34fc2f20d22..7131797003b 100644
--- a/library/std/src/sys/pal/sgx/abi/tls/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/tls/mod.rs
@@ -22,7 +22,7 @@ macro_rules! dup {
 #[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_DESTRUCTORE"]
 static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = dup!((* * * * * * *) (AtomicUsize::new(0)));
 
-extern "C" {
+unsafe extern "C" {
     fn get_tls_ptr() -> *const u8;
     fn set_tls_ptr(tls: *const u8);
 }
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs b/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs
index 943b771498f..28fbbc3c518 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs
@@ -9,7 +9,7 @@ use crate::ptr::NonNull;
 #[repr(C)]
 struct UsercallReturn(u64, u64);
 
-extern "C" {
+unsafe extern "C" {
     fn usercall(nr: NonZero<u64>, p1: u64, p2: u64, abort: u64, p3: u64, p4: u64)
     -> UsercallReturn;
 }
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index 0f5935d0c71..9a04fa4b97e 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -14,8 +14,6 @@ pub mod env;
 pub mod fd;
 #[path = "../unsupported/fs.rs"]
 pub mod fs;
-#[path = "../unsupported/io.rs"]
-pub mod io;
 mod libunwind_integration;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
diff --git a/library/std/src/sys/pal/sgx/stdio.rs b/library/std/src/sys/pal/sgx/stdio.rs
index 2e680e740fd..e79a3d971c6 100644
--- a/library/std/src/sys/pal/sgx/stdio.rs
+++ b/library/std/src/sys/pal/sgx/stdio.rs
@@ -62,7 +62,7 @@ impl io::Write for Stderr {
     }
 }
 
-pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
+pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
 
 pub fn is_ebadf(err: &io::Error) -> bool {
     // FIXME: Rust normally maps Unix EBADF to `Uncategorized`
diff --git a/library/std/src/sys/pal/solid/abi/fs.rs b/library/std/src/sys/pal/solid/abi/fs.rs
index 6864a3e7745..7f2b1f83e85 100644
--- a/library/std/src/sys/pal/solid/abi/fs.rs
+++ b/library/std/src/sys/pal/solid/abi/fs.rs
@@ -31,7 +31,7 @@ pub const DT_WHT: c_uchar = 14;
 
 pub type S_DIR = c_int;
 
-extern "C" {
+unsafe extern "C" {
     pub fn SOLID_FS_Open(fd: *mut c_int, path: *const c_char, mode: c_int) -> c_int;
     pub fn SOLID_FS_Close(fd: c_int) -> c_int;
     pub fn SOLID_FS_Read(fd: c_int, buf: *mut u8, size: usize, result: *mut usize) -> c_int;
diff --git a/library/std/src/sys/pal/solid/abi/mod.rs b/library/std/src/sys/pal/solid/abi/mod.rs
index 4d097057217..819f93f4074 100644
--- a/library/std/src/sys/pal/solid/abi/mod.rs
+++ b/library/std/src/sys/pal/solid/abi/mod.rs
@@ -33,27 +33,27 @@ pub struct SOLID_RTC_TIME {
     pub tm_wday: c_int,
 }
 
-extern "C" {
+unsafe extern "C" {
     pub fn SOLID_RTC_ReadTime(time: *mut SOLID_RTC_TIME) -> c_int;
 }
 
 // `solid_log.h`
-extern "C" {
+unsafe extern "C" {
     pub fn SOLID_LOG_write(s: *const u8, l: usize);
 }
 
 // `solid_mem.h`
-extern "C" {
+unsafe extern "C" {
     pub fn SOLID_TLS_AddDestructor(id: i32, dtor: unsafe extern "C" fn(*mut u8));
 }
 
 // `solid_rng.h`
-extern "C" {
+unsafe extern "C" {
     pub fn SOLID_RNG_SampleRandomBytes(buffer: *mut u8, length: usize) -> c_int;
 }
 
 // `rwlock.h`
-extern "C" {
+unsafe extern "C" {
     pub fn rwl_loc_rdl(id: ID) -> ER;
     pub fn rwl_loc_wrl(id: ID) -> ER;
     pub fn rwl_ploc_rdl(id: ID) -> ER;
diff --git a/library/std/src/sys/pal/solid/abi/sockets.rs b/library/std/src/sys/pal/solid/abi/sockets.rs
index 3c9e3f9ffb9..80802dd42e2 100644
--- a/library/std/src/sys/pal/solid/abi/sockets.rs
+++ b/library/std/src/sys/pal/solid/abi/sockets.rs
@@ -158,7 +158,7 @@ pub struct fd_set {
     pub fds: [c_int; SOLID_NET_FD_SETSIZE],
 }
 
-extern "C" {
+unsafe extern "C" {
     #[link_name = "SOLID_NET_StrError"]
     pub fn strerror(errnum: c_int) -> *const c_char;
 
diff --git a/library/std/src/sys/pal/solid/fs.rs b/library/std/src/sys/pal/solid/fs.rs
index fa2e470d6b6..c075ba53a1f 100644
--- a/library/std/src/sys/pal/solid/fs.rs
+++ b/library/std/src/sys/pal/solid/fs.rs
@@ -312,7 +312,7 @@ fn cstr(path: &Path) -> io::Result<CString> {
     let wrapped_path = [SAFE_PREFIX, &path, &[0]].concat();
 
     CString::from_vec_with_nul(wrapped_path).map_err(|_| {
-        crate::io::const_error!(io::ErrorKind::InvalidInput, "path provided contains a nul byte",)
+        crate::io::const_error!(io::ErrorKind::InvalidInput, "path provided contains a nul byte")
     })
 }
 
diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs
index caf848a4e9b..06af7bfade0 100644
--- a/library/std/src/sys/pal/solid/mod.rs
+++ b/library/std/src/sys/pal/solid/mod.rs
@@ -23,7 +23,6 @@ pub mod env;
 // `crate::sys::error`
 pub(crate) mod error;
 pub mod fs;
-pub mod io;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs
index 57c28aed3b2..e3b2e0aa50f 100644
--- a/library/std/src/sys/pal/solid/os.rs
+++ b/library/std/src/sys/pal/solid/os.rs
@@ -129,7 +129,7 @@ impl Iterator for Env {
 /// Returns a vector of (variable, value) byte-vector pairs for all the
 /// environment variables of the current process.
 pub fn env() -> Env {
-    extern "C" {
+    unsafe extern "C" {
         static mut environ: *const *const c_char;
     }
 
diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs
index a9904e66664..3632524157d 100644
--- a/library/std/src/sys/pal/teeos/mod.rs
+++ b/library/std/src/sys/pal/teeos/mod.rs
@@ -13,8 +13,6 @@ pub mod env;
 //pub mod fd;
 #[path = "../unsupported/fs.rs"]
 pub mod fs;
-#[path = "../unsupported/io.rs"]
-pub mod io;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
@@ -150,5 +148,5 @@ pub fn unsupported<T>() -> std_io::Result<T> {
 }
 
 pub fn unsupported_err() -> std_io::Error {
-    std_io::Error::new(std_io::ErrorKind::Unsupported, "operation not supported on this platform")
+    std_io::Error::UNSUPPORTED_PLATFORM
 }
diff --git a/library/std/src/sys/pal/teeos/os.rs b/library/std/src/sys/pal/teeos/os.rs
index 82cade771b5..bf6945811ab 100644
--- a/library/std/src/sys/pal/teeos/os.rs
+++ b/library/std/src/sys/pal/teeos/os.rs
@@ -107,11 +107,11 @@ pub fn getenv(_: &OsStr) -> Option<OsString> {
 }
 
 pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
-    Err(io::Error::new(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
+    Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
 }
 
 pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> {
-    Err(io::Error::new(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
+    Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
 }
 
 pub fn temp_dir() -> PathBuf {
diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs
index 15c65240ddd..c779c5f3ed8 100644
--- a/library/std/src/sys/pal/teeos/thread.rs
+++ b/library/std/src/sys/pal/teeos/thread.rs
@@ -16,7 +16,7 @@ pub struct Thread {
 unsafe impl Send for Thread {}
 unsafe impl Sync for Thread {}
 
-extern "C" {
+unsafe extern "C" {
     pub fn TEE_Wait(timeout: u32) -> u32;
 }
 
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index dccc137d6f5..ec2da4e4ee7 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -273,7 +273,7 @@ impl OwnedDevicePath {
 
         io::Result::Err(const_error!(
             io::ErrorKind::NotFound,
-            "DevicePathFromText Protocol not found"
+            "DevicePathFromText Protocol not found",
         ))
     }
 
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index 07025a304bf..14eaf8ad658 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -17,8 +17,6 @@ pub mod args;
 pub mod env;
 pub mod fs;
 pub mod helpers;
-#[path = "../unsupported/io.rs"]
-pub mod io;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
@@ -92,7 +90,7 @@ pub const fn unsupported<T>() -> std_io::Result<T> {
 
 #[inline]
 pub const fn unsupported_err() -> std_io::Error {
-    std_io::const_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",)
+    std_io::const_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI")
 }
 
 pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind {
diff --git a/library/std/src/sys/pal/uefi/stdio.rs b/library/std/src/sys/pal/uefi/stdio.rs
index 703e8ba8e57..d049d19bc83 100644
--- a/library/std/src/sys/pal/uefi/stdio.rs
+++ b/library/std/src/sys/pal/uefi/stdio.rs
@@ -71,7 +71,7 @@ impl io::Read for Stdin {
             };
 
         if ch.len() > 1 {
-            return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid utf-16 sequence"));
+            return Err(io::const_error!(io::ErrorKind::InvalidData, "invalid utf-16 sequence"));
         }
 
         match ch.pop().unwrap() {
diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs
index 8438a61e90f..1c87a79803c 100644
--- a/library/std/src/sys/pal/unix/args.rs
+++ b/library/std/src/sys/pal/unix/args.rs
@@ -147,7 +147,7 @@ mod imp {
     /// This allows `std::env::args` to work even in a `cdylib`, as it does on macOS and Windows.
     #[cfg(all(target_os = "linux", target_env = "gnu"))]
     #[used]
-    #[link_section = ".init_array.00099"]
+    #[unsafe(link_section = ".init_array.00099")]
     static ARGV_INIT_ARRAY: extern "C" fn(
         crate::os::raw::c_int,
         *const *const u8,
@@ -204,7 +204,7 @@ mod imp {
     }
 
     pub fn argc_argv() -> (isize, *const *const c_char) {
-        extern "C" {
+        unsafe extern "C" {
             // These functions are in crt_externs.h.
             fn _NSGetArgc() -> *mut c_int;
             fn _NSGetArgv() -> *mut *mut *mut c_char;
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 6c41781fe85..16fb207298d 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -9,9 +9,12 @@ use libc::c_char;
 #[cfg(any(
     all(target_os = "linux", not(target_env = "musl")),
     target_os = "android",
+    target_os = "fuchsia",
     target_os = "hurd"
 ))]
 use libc::dirfd;
+#[cfg(target_os = "fuchsia")]
+use libc::fstatat as fstatat64;
 #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))]
 use libc::fstatat64;
 #[cfg(any(
@@ -565,8 +568,7 @@ impl FileAttr {
 
         Err(io::const_error!(
             io::ErrorKind::Unsupported,
-            "creation time is not available on this platform \
-                            currently",
+            "creation time is not available on this platform currently",
         ))
     }
 
@@ -848,7 +850,6 @@ impl Drop for Dir {
             target_os = "vita",
             target_os = "hurd",
             target_os = "espidf",
-            target_os = "fuchsia",
             target_os = "horizon",
             target_os = "vxworks",
             target_os = "rtems",
@@ -880,6 +881,7 @@ impl DirEntry {
         any(
             all(target_os = "linux", not(target_env = "musl")),
             target_os = "android",
+            target_os = "fuchsia",
             target_os = "hurd"
         ),
         not(miri) // no dirfd on Miri
@@ -908,6 +910,7 @@ impl DirEntry {
         not(any(
             all(target_os = "linux", not(target_env = "musl")),
             target_os = "android",
+            target_os = "fuchsia",
             target_os = "hurd",
         )),
         miri
@@ -1211,6 +1214,7 @@ impl File {
         }
         #[cfg(any(
             target_os = "freebsd",
+            target_os = "fuchsia",
             target_os = "linux",
             target_os = "android",
             target_os = "netbsd",
@@ -1223,6 +1227,7 @@ impl File {
         }
         #[cfg(not(any(
             target_os = "android",
+            target_os = "fuchsia",
             target_os = "freebsd",
             target_os = "linux",
             target_os = "netbsd",
@@ -1238,6 +1243,7 @@ impl File {
 
     #[cfg(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1249,6 +1255,7 @@ impl File {
 
     #[cfg(not(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1259,6 +1266,7 @@ impl File {
 
     #[cfg(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1270,6 +1278,7 @@ impl File {
 
     #[cfg(not(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1280,6 +1289,7 @@ impl File {
 
     #[cfg(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1297,6 +1307,7 @@ impl File {
 
     #[cfg(not(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1307,6 +1318,7 @@ impl File {
 
     #[cfg(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1324,6 +1336,7 @@ impl File {
 
     #[cfg(not(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1334,6 +1347,7 @@ impl File {
 
     #[cfg(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1345,6 +1359,7 @@ impl File {
 
     #[cfg(not(any(
         target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "linux",
         target_os = "netbsd",
         target_vendor = "apple",
@@ -1443,11 +1458,11 @@ impl File {
             Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
             Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
-                "timestamp is too large to set as a file time"
+                "timestamp is too large to set as a file time",
             )),
             Some(_) => Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
-                "timestamp is too small to set as a file time"
+                "timestamp is too small to set as a file time",
             )),
             None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
         };
diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs
index 0fc765dc87a..d4551dd6a38 100644
--- a/library/std/src/sys/pal/unix/futex.rs
+++ b/library/std/src/sys/pal/unix/futex.rs
@@ -219,7 +219,7 @@ pub fn futex_wake_all(futex: &AtomicU32) {
 }
 
 #[cfg(target_os = "emscripten")]
-extern "C" {
+unsafe extern "C" {
     fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int;
     fn emscripten_futex_wait(
         addr: *const AtomicU32,
@@ -267,7 +267,7 @@ pub mod zircon {
     pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
     pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
 
-    extern "C" {
+    unsafe extern "C" {
         pub fn zx_clock_get_monotonic() -> zx_time_t;
         pub fn zx_futex_wait(
             value_ptr: *const zx_futex_t,
diff --git a/library/std/src/sys/pal/unix/io.rs b/library/std/src/sys/pal/unix/io.rs
deleted file mode 100644
index 0d5a152dc0d..00000000000
--- a/library/std/src/sys/pal/unix/io.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-use libc::{c_void, iovec};
-
-use crate::marker::PhantomData;
-use crate::os::fd::{AsFd, AsRawFd};
-use crate::slice;
-
-#[derive(Copy, Clone)]
-#[repr(transparent)]
-pub struct IoSlice<'a> {
-    vec: iovec,
-    _p: PhantomData<&'a [u8]>,
-}
-
-impl<'a> IoSlice<'a> {
-    #[inline]
-    pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
-        IoSlice {
-            vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
-            _p: PhantomData,
-        }
-    }
-
-    #[inline]
-    pub fn advance(&mut self, n: usize) {
-        if self.vec.iov_len < n {
-            panic!("advancing IoSlice beyond its length");
-        }
-
-        unsafe {
-            self.vec.iov_len -= n;
-            self.vec.iov_base = self.vec.iov_base.add(n);
-        }
-    }
-
-    #[inline]
-    pub const fn as_slice(&self) -> &'a [u8] {
-        unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
-    }
-}
-
-#[repr(transparent)]
-pub struct IoSliceMut<'a> {
-    vec: iovec,
-    _p: PhantomData<&'a mut [u8]>,
-}
-
-impl<'a> IoSliceMut<'a> {
-    #[inline]
-    pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
-        IoSliceMut {
-            vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
-            _p: PhantomData,
-        }
-    }
-
-    #[inline]
-    pub fn advance(&mut self, n: usize) {
-        if self.vec.iov_len < n {
-            panic!("advancing IoSliceMut beyond its length");
-        }
-
-        unsafe {
-            self.vec.iov_len -= n;
-            self.vec.iov_base = self.vec.iov_base.add(n);
-        }
-    }
-
-    #[inline]
-    pub fn as_slice(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
-    }
-
-    #[inline]
-    pub const fn into_slice(self) -> &'a mut [u8] {
-        unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
-    }
-
-    #[inline]
-    pub fn as_mut_slice(&mut self) -> &mut [u8] {
-        unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
-    }
-}
-
-pub fn is_terminal(fd: &impl AsFd) -> bool {
-    let fd = fd.as_fd();
-    unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
-}
diff --git a/library/std/src/sys/pal/unix/kernel_copy/tests.rs b/library/std/src/sys/pal/unix/kernel_copy/tests.rs
index 1350d743ff6..54d8f8ed2ed 100644
--- a/library/std/src/sys/pal/unix/kernel_copy/tests.rs
+++ b/library/std/src/sys/pal/unix/kernel_copy/tests.rs
@@ -2,7 +2,7 @@ use crate::fs::OpenOptions;
 use crate::io;
 use crate::io::{BufRead, Read, Result, Seek, SeekFrom, Write};
 use crate::os::unix::io::AsRawFd;
-use crate::sys_common::io::test::tmpdir;
+use crate::test_helpers::tmpdir;
 
 #[test]
 fn copy_specialization() -> Result<()> {
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 6862399b942..c0b56d8d2b2 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -11,7 +11,6 @@ pub mod env;
 pub mod fd;
 pub mod fs;
 pub mod futex;
-pub mod io;
 #[cfg(any(target_os = "linux", target_os = "android"))]
 pub mod kernel_copy;
 #[cfg(target_os = "linux")]
@@ -374,24 +373,24 @@ cfg_if::cfg_if! {
             cfg(target_feature = "crt-static"))]
         #[link(name = "dl", cfg(not(target_feature = "crt-static")))]
         #[link(name = "log", cfg(not(target_feature = "crt-static")))]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(target_os = "freebsd")] {
         #[link(name = "execinfo")]
         #[link(name = "pthread")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(target_os = "netbsd")] {
         #[link(name = "pthread")]
         #[link(name = "rt")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))] {
         #[link(name = "pthread")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(target_os = "solaris")] {
         #[link(name = "socket")]
         #[link(name = "posix4")]
         #[link(name = "pthread")]
         #[link(name = "resolv")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(target_os = "illumos")] {
         #[link(name = "socket")]
         #[link(name = "posix4")]
@@ -400,24 +399,24 @@ cfg_if::cfg_if! {
         #[link(name = "nsl")]
         // Use libumem for the (malloc-compatible) allocator
         #[link(name = "umem")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(target_vendor = "apple")] {
         // Link to `libSystem.dylib`.
         //
         // Don't get confused by the presence of `System.framework`,
         // it is a deprecated wrapper over the dynamic library.
         #[link(name = "System")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(target_os = "fuchsia")] {
         #[link(name = "zircon")]
         #[link(name = "fdio")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] {
         #[link(name = "dl")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(target_os = "vita")] {
         #[link(name = "pthread", kind = "static", modifiers = "-bundle")]
-        extern "C" {}
+        unsafe extern "C" {}
     }
 }
 
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index b83772e34c1..78404b4afa7 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -30,7 +30,7 @@ cfg_if::cfg_if! {
     }
 }
 
-extern "C" {
+unsafe extern "C" {
     #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
     #[cfg_attr(
         any(
@@ -82,7 +82,7 @@ pub fn errno() -> i32 {
 
 #[cfg(target_os = "rtems")]
 pub fn errno() -> i32 {
-    extern "C" {
+    unsafe extern "C" {
         #[thread_local]
         static _tls_errno: c_int;
     }
@@ -92,7 +92,7 @@ pub fn errno() -> i32 {
 
 #[cfg(target_os = "dragonfly")]
 pub fn errno() -> i32 {
-    extern "C" {
+    unsafe extern "C" {
         #[thread_local]
         static errno: c_int;
     }
@@ -103,7 +103,7 @@ pub fn errno() -> i32 {
 #[cfg(target_os = "dragonfly")]
 #[allow(dead_code)]
 pub fn set_errno(e: i32) {
-    extern "C" {
+    unsafe extern "C" {
         #[thread_local]
         static mut errno: c_int;
     }
@@ -115,7 +115,7 @@ pub fn set_errno(e: i32) {
 
 /// Gets a detailed string description for the given error number.
 pub fn error_string(errno: i32) -> String {
-    extern "C" {
+    unsafe extern "C" {
         #[cfg_attr(
             all(
                 any(target_os = "linux", target_os = "hurd", target_env = "newlib"),
@@ -260,7 +260,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
     let exe_path = env::args().next().ok_or(io::const_error!(
         ErrorKind::NotFound,
-        "an executable path was not found because no arguments were provided through argv"
+        "an executable path was not found because no arguments were provided through argv",
     ))?;
     let path = PathBuf::from(exe_path);
     if path.is_absolute() {
@@ -382,9 +382,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
         cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?;
         argv.set_len(argv_len as usize);
         if argv[0].is_null() {
-            return Err(
-                io::const_error!(io::ErrorKind::Uncategorized, "no current exe available",),
-            );
+            return Err(io::const_error!(io::ErrorKind::Uncategorized, "no current exe available"));
         }
         let argv0 = CStr::from_ptr(argv[0]).to_bytes();
         if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') {
@@ -526,7 +524,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
     let exe_path = env::args().next().ok_or(io::const_error!(
         ErrorKind::Uncategorized,
-        "an executable path was not found because no arguments were provided through argv"
+        "an executable path was not found because no arguments were provided through argv",
     ))?;
     let path = PathBuf::from(exe_path);
 
@@ -610,7 +608,7 @@ pub unsafe fn environ() -> *mut *const *const c_char {
 // Use the `environ` static which is part of POSIX.
 #[cfg(not(target_vendor = "apple"))]
 pub unsafe fn environ() -> *mut *const *const c_char {
-    extern "C" {
+    unsafe extern "C" {
         static mut environ: *const *const c_char;
     }
     &raw mut environ
@@ -847,7 +845,7 @@ pub fn getppid() -> u32 {
 
 #[cfg(all(target_os = "linux", target_env = "gnu"))]
 pub fn glibc_version() -> Option<(usize, usize)> {
-    extern "C" {
+    unsafe extern "C" {
         fn gnu_get_libc_version() -> *const libc::c_char;
     }
     let version_cstr = unsafe { CStr::from_ptr(gnu_get_libc_version()) };
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index 2bff192a5bd..aa7406dd548 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -228,7 +228,7 @@ impl Command {
         let envp = self.capture_env();
 
         if self.saw_nul() {
-            return io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data",);
+            return io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data");
         }
 
         match self.setup_io(default, true) {
@@ -1228,7 +1228,7 @@ mod linux_child_ext {
                 .as_ref()
                 // SAFETY: The os type is a transparent wrapper, therefore we can transmute references
                 .map(|fd| unsafe { mem::transmute::<&imp::PidFd, &os::PidFd>(fd) })
-                .ok_or_else(|| io::Error::new(ErrorKind::Uncategorized, "No pidfd was created."))
+                .ok_or_else(|| io::const_error!(ErrorKind::Uncategorized, "No pidfd was created."))
         }
 
         fn into_pidfd(mut self) -> Result<os::PidFd, Self> {
diff --git a/library/std/src/sys/pal/unix/process/zircon.rs b/library/std/src/sys/pal/unix/process/zircon.rs
index 4035e2370a3..7932bd26d76 100644
--- a/library/std/src/sys/pal/unix/process/zircon.rs
+++ b/library/std/src/sys/pal/unix/process/zircon.rs
@@ -75,7 +75,7 @@ pub struct zx_info_process_t {
     pub reserved1: u32,
 }
 
-extern "C" {
+unsafe extern "C" {
     pub fn zx_job_default() -> zx_handle_t;
 
     pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
@@ -115,7 +115,7 @@ pub struct fdio_spawn_action_t {
     pub reserved1: u64,
 }
 
-extern "C" {
+unsafe extern "C" {
     pub fn fdio_spawn_etc(
         job: zx_handle_t,
         flags: u32,
diff --git a/library/std/src/sys/pal/unix/stdio.rs b/library/std/src/sys/pal/unix/stdio.rs
index 97e75f1b5b6..8c2f61a40de 100644
--- a/library/std/src/sys/pal/unix/stdio.rs
+++ b/library/std/src/sys/pal/unix/stdio.rs
@@ -92,7 +92,7 @@ pub fn is_ebadf(err: &io::Error) -> bool {
     err.raw_os_error() == Some(libc::EBADF as i32)
 }
 
-pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
+pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
 
 pub fn panic_output() -> Option<impl io::Write> {
     Some(Stderr::new())
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 356669980c7..479021af040 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -23,7 +23,7 @@ mod zircon {
     type zx_status_t = i32;
     pub const ZX_PROP_NAME: u32 = 3;
 
-    extern "C" {
+    unsafe extern "C" {
         pub fn zx_object_set_property(
             handle: zx_handle_t,
             property: u32,
@@ -230,7 +230,7 @@ impl Thread {
     #[cfg(target_os = "vxworks")]
     pub fn set_name(name: &CStr) {
         // FIXME(libc): adding real STATUS, ERROR type eventually.
-        extern "C" {
+        unsafe extern "C" {
             fn taskNameSet(task_id: libc::TASK_ID, task_name: *mut libc::c_char) -> libc::c_int;
         }
 
@@ -506,7 +506,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
         } else if #[cfg(target_os = "vxworks")] {
             // Note: there is also `vxCpuConfiguredGet`, closer to _SC_NPROCESSORS_CONF
             // expectations than the actual cores availability.
-            extern "C" {
+            unsafe extern "C" {
                 fn vxCpuEnabledGet() -> libc::cpuset_t;
             }
 
diff --git a/library/std/src/sys/pal/unix/thread_parking.rs b/library/std/src/sys/pal/unix/thread_parking.rs
index 72dd2031479..bef8b4fb363 100644
--- a/library/std/src/sys/pal/unix/thread_parking.rs
+++ b/library/std/src/sys/pal/unix/thread_parking.rs
@@ -8,7 +8,7 @@ use crate::ffi::{c_int, c_void};
 use crate::ptr;
 use crate::time::Duration;
 
-extern "C" {
+unsafe extern "C" {
     fn ___lwp_park60(
         clock_id: clockid_t,
         flags: c_int,
diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs
index 35762f5a53b..5a37598f438 100644
--- a/library/std/src/sys/pal/unix/weak.rs
+++ b/library/std/src/sys/pal/unix/weak.rs
@@ -31,7 +31,7 @@ use crate::{mem, ptr};
 pub(crate) macro weak {
     (fn $name:ident($($t:ty),*) -> $ret:ty) => (
         let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
-            extern "C" {
+            unsafe extern "C" {
                 #[linkage = "extern_weak"]
                 static $name: Option<unsafe extern "C" fn($($t),*) -> $ret>;
             }
diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs
index 4941dd4918c..b1aaeb1b4c8 100644
--- a/library/std/src/sys/pal/unsupported/mod.rs
+++ b/library/std/src/sys/pal/unsupported/mod.rs
@@ -3,7 +3,6 @@
 pub mod args;
 pub mod env;
 pub mod fs;
-pub mod io;
 pub mod os;
 pub mod pipe;
 pub mod process;
diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs
index 7779d2b97d7..2f24ca97ab9 100644
--- a/library/std/src/sys/pal/wasi/fs.rs
+++ b/library/std/src/sys/pal/wasi/fs.rs
@@ -533,7 +533,7 @@ impl File {
             Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
             Some(_) => Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
-                "timestamp is too large to set as a file time"
+                "timestamp is too large to set as a file time",
             )),
             None => Ok(0),
         };
@@ -773,8 +773,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
                     }
                     let msg = format!(
                         "failed to find a pre-opened file descriptor \
-                     through which {:?} could be opened",
-                        p
+                        through which {p:?} could be opened",
                     );
                     return Err(io::Error::new(io::ErrorKind::Uncategorized, msg));
                 }
@@ -787,7 +786,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
             }
         }
 
-        extern "C" {
+        unsafe extern "C" {
             pub fn __wasilibc_find_relpath(
                 path: *const libc::c_char,
                 abs_prefix: *mut *const libc::c_char,
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index 312ad28ab51..f4588a60ea9 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -20,7 +20,6 @@ pub mod fs;
 #[allow(unused)]
 #[path = "../wasm/atomics/futex.rs"]
 pub mod futex;
-pub mod io;
 
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs
index f7701360f5a..ba2b65a1f40 100644
--- a/library/std/src/sys/pal/wasi/os.rs
+++ b/library/std/src/sys/pal/wasi/os.rs
@@ -16,7 +16,7 @@ use crate::{fmt, io, str, vec};
 mod libc {
     pub use libc::*;
 
-    extern "C" {
+    unsafe extern "C" {
         pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
         pub fn chdir(dir: *const c_char) -> c_int;
         pub fn __wasilibc_get_environ() -> *mut *mut c_char;
@@ -46,7 +46,7 @@ cfg_if::cfg_if! {
 }
 
 pub fn errno() -> i32 {
-    extern "C" {
+    unsafe extern "C" {
         #[thread_local]
         static errno: libc::c_int;
     }
diff --git a/library/std/src/sys/pal/wasi/stdio.rs b/library/std/src/sys/pal/wasi/stdio.rs
index ca49f871e19..d08b772e5fc 100644
--- a/library/std/src/sys/pal/wasi/stdio.rs
+++ b/library/std/src/sys/pal/wasi/stdio.rs
@@ -101,7 +101,7 @@ impl io::Write for Stderr {
     }
 }
 
-pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
+pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
 
 pub fn is_ebadf(err: &io::Error) -> bool {
     err.raw_os_error() == Some(wasi::ERRNO_BADF.raw().into())
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index f5e19f26bfe..0ae02369410 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -35,7 +35,7 @@ cfg_if::cfg_if! {
 
             pub const _SC_NPROCESSORS_ONLN: ffi::c_int = 84;
 
-            extern "C" {
+            unsafe extern "C" {
                 pub fn pthread_create(
                     native: *mut pthread_t,
                     attr: *const pthread_attr_t,
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index 234e946d3b8..72c9742b2e5 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -17,8 +17,6 @@ pub mod fs;
 #[allow(unused)]
 #[path = "../wasm/atomics/futex.rs"]
 pub mod futex;
-#[path = "../wasi/io.rs"]
-pub mod io;
 
 #[path = "../wasi/os.rs"]
 pub mod os;
diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs
index 1280f353200..32d59c4d0f7 100644
--- a/library/std/src/sys/pal/wasm/mod.rs
+++ b/library/std/src/sys/pal/wasm/mod.rs
@@ -21,8 +21,6 @@ pub mod args;
 pub mod env;
 #[path = "../unsupported/fs.rs"]
 pub mod fs;
-#[path = "../unsupported/io.rs"]
-pub mod io;
 #[path = "../unsupported/os.rs"]
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
diff --git a/library/std/src/sys/pal/windows/args/tests.rs b/library/std/src/sys/pal/windows/args/tests.rs
index 6d5c953cbd5..484a90ab056 100644
--- a/library/std/src/sys/pal/windows/args/tests.rs
+++ b/library/std/src/sys/pal/windows/args/tests.rs
@@ -47,10 +47,10 @@ fn whitespace_behavior() {
 fn genius_quotes() {
     chk(r#"EXE "" """#, &["EXE", "", ""]);
     chk(r#"EXE "" """"#, &["EXE", "", r#"""#]);
-    chk(r#"EXE "this is """all""" in the same argument""#, &[
-        "EXE",
-        r#"this is "all" in the same argument"#,
-    ]);
+    chk(
+        r#"EXE "this is """all""" in the same argument""#,
+        &["EXE", r#"this is "all" in the same argument"#],
+    );
     chk(r#"EXE "a"""#, &["EXE", r#"a""#]);
     chk(r#"EXE "a"" a"#, &["EXE", r#"a" a"#]);
     // quotes cannot be escaped in command names
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 9ce3e912caf..8dc61edb603 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -115,7 +115,7 @@ if #[cfg(not(target_vendor = "uwp"))] {
     link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")
 )]
 #[cfg_attr(not(target_arch = "x86"), link(name = "bcryptprimitives", kind = "raw-dylib"))]
-extern "system" {
+unsafe extern "system" {
     pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
 }
 
@@ -164,7 +164,7 @@ compat_fn_with_fallback! {
     not(target_arch = "x86"),
     link(name = "api-ms-win-core-synch-l1-2-0", kind = "raw-dylib")
 )]
-extern "system" {
+unsafe extern "system" {
     pub fn WaitOnAddress(
         address: *const c_void,
         compareaddress: *const c_void,
diff --git a/library/std/src/sys/pal/windows/compat.rs b/library/std/src/sys/pal/windows/compat.rs
index 42999da1664..2b9838437e9 100644
--- a/library/std/src/sys/pal/windows/compat.rs
+++ b/library/std/src/sys/pal/windows/compat.rs
@@ -39,7 +39,7 @@ use crate::sys::c;
 // See https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-170
 #[cfg(target_vendor = "win7")]
 #[used]
-#[link_section = ".CRT$XCT"]
+#[unsafe(link_section = ".CRT$XCT")]
 static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
 
 /// Preload some imported functions.
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index f8493c21ad4..55553b678cd 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -44,7 +44,7 @@ pub struct FileType {
 }
 
 pub struct ReadDir {
-    handle: FindNextFileHandle,
+    handle: Option<FindNextFileHandle>,
     root: Arc<PathBuf>,
     first: Option<c::WIN32_FIND_DATAW>,
 }
@@ -113,13 +113,13 @@ impl fmt::Debug for ReadDir {
 impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
-        if self.handle.0 == c::INVALID_HANDLE_VALUE {
+        let Some(handle) = self.handle.as_ref() else {
             // This iterator was initialized with an `INVALID_HANDLE_VALUE` as its handle.
             // Simply return `None` because this is only the case when `FindFirstFileExW` in
             // the construction of this iterator returns `ERROR_FILE_NOT_FOUND` which means
             // no matchhing files can be found.
             return None;
-        }
+        };
         if let Some(first) = self.first.take() {
             if let Some(e) = DirEntry::new(&self.root, &first) {
                 return Some(Ok(e));
@@ -128,7 +128,7 @@ impl Iterator for ReadDir {
         unsafe {
             let mut wfd = mem::zeroed();
             loop {
-                if c::FindNextFileW(self.handle.0, &mut wfd) == 0 {
+                if c::FindNextFileW(handle.0, &mut wfd) == 0 {
                     match api::get_last_error() {
                         WinError::NO_MORE_FILES => return None,
                         WinError { code } => {
@@ -296,6 +296,10 @@ impl OpenOptions {
 impl File {
     pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
         let path = maybe_verbatim(path)?;
+        Self::open_native(&path, opts)
+    }
+
+    fn open_native(path: &[u16], opts: &OpenOptions) -> io::Result<File> {
         let creation = opts.get_creation_mode()?;
         let handle = unsafe {
             c::CreateFileW(
@@ -1190,7 +1194,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
 
         if find_handle != c::INVALID_HANDLE_VALUE {
             Ok(ReadDir {
-                handle: FindNextFileHandle(find_handle),
+                handle: Some(FindNextFileHandle(find_handle)),
                 root: Arc::new(root),
                 first: Some(wfd),
             })
@@ -1208,11 +1212,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
             // See issue #120040: https://github.com/rust-lang/rust/issues/120040.
             let last_error = api::get_last_error();
             if last_error == WinError::FILE_NOT_FOUND {
-                return Ok(ReadDir {
-                    handle: FindNextFileHandle(find_handle),
-                    root: Arc::new(root),
-                    first: None,
-                });
+                return Ok(ReadDir { handle: None, root: Arc::new(root), first: None });
             }
 
             // Just return the error constructed from the raw OS error if the above is not the case.
@@ -1226,8 +1226,26 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
 
 pub fn unlink(p: &Path) -> io::Result<()> {
     let p_u16s = maybe_verbatim(p)?;
-    cvt(unsafe { c::DeleteFileW(p_u16s.as_ptr()) })?;
-    Ok(())
+    if unsafe { c::DeleteFileW(p_u16s.as_ptr()) } == 0 {
+        let err = api::get_last_error();
+        // if `DeleteFileW` fails with ERROR_ACCESS_DENIED then try to remove
+        // the file while ignoring the readonly attribute.
+        // This is accomplished by calling the `posix_delete` function on an open file handle.
+        if err == WinError::ACCESS_DENIED {
+            let mut opts = OpenOptions::new();
+            opts.access_mode(c::DELETE);
+            opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT);
+            if let Ok(f) = File::open_native(&p_u16s, &opts) {
+                if f.posix_delete().is_ok() {
+                    return Ok(());
+                }
+            }
+        }
+        // return the original error if any of the above fails.
+        Err(io::Error::from_raw_os_error(err.code as i32))
+    } else {
+        Ok(())
+    }
 }
 
 pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
@@ -1450,9 +1468,7 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
 
 #[cfg(target_vendor = "uwp")]
 pub fn link(_original: &Path, _link: &Path) -> io::Result<()> {
-    return Err(
-        io::const_error!(io::ErrorKind::Unsupported, "hard link are not supported on UWP",),
-    );
+    return Err(io::const_error!(io::ErrorKind::Unsupported, "hard link are not supported on UWP"));
 }
 
 pub fn stat(path: &Path) -> io::Result<FileAttr> {
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index f9aa049ca9a..1eca346b76c 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -21,7 +21,6 @@ pub mod fs;
 #[cfg(not(target_vendor = "win7"))]
 pub mod futex;
 pub mod handle;
-pub mod io;
 pub mod os;
 pub mod pipe;
 pub mod process;
diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs
index 9332c9b49ff..a41dfbfe601 100644
--- a/library/std/src/sys/pal/windows/process.rs
+++ b/library/std/src/sys/pal/windows/process.rs
@@ -435,9 +435,7 @@ fn resolve_exe<'a>(
 ) -> io::Result<Vec<u16>> {
     // Early return if there is no filename.
     if exe_path.is_empty() || path::has_trailing_slash(exe_path) {
-        return Err(
-            io::const_error!(io::ErrorKind::InvalidInput, "program path has no file name",),
-        );
+        return Err(io::const_error!(io::ErrorKind::InvalidInput, "program path has no file name"));
     }
     // Test if the file name has the `exe` extension.
     // This does a case-insensitive `ends_with`.
diff --git a/library/std/src/sys/pal/windows/process/tests.rs b/library/std/src/sys/pal/windows/process/tests.rs
index 1bcc5fa6b20..90f1157d7c4 100644
--- a/library/std/src/sys/pal/windows/process/tests.rs
+++ b/library/std/src/sys/pal/windows/process/tests.rs
@@ -33,7 +33,7 @@ fn test_thread_handle() {
     assert!(p.is_ok());
     let mut p = p.unwrap();
 
-    extern "system" {
+    unsafe extern "system" {
         fn ResumeThread(_: BorrowedHandle<'_>) -> u32;
     }
     unsafe {
@@ -158,7 +158,7 @@ fn windows_exe_resolver() {
     use super::resolve_exe;
     use crate::io;
     use crate::sys::fs::symlink;
-    use crate::sys_common::io::test::tmpdir;
+    use crate::test_helpers::tmpdir;
 
     let env_paths = || env::var_os("PATH");
 
diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs
index 8ba2b6e2f20..1bd0e67f371 100644
--- a/library/std/src/sys/pal/xous/mod.rs
+++ b/library/std/src/sys/pal/xous/mod.rs
@@ -5,8 +5,6 @@ pub mod args;
 pub mod env;
 #[path = "../unsupported/fs.rs"]
 pub mod fs;
-#[path = "../unsupported/io.rs"]
-pub mod io;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
diff --git a/library/std/src/sys/pal/xous/os.rs b/library/std/src/sys/pal/xous/os.rs
index b0ab01a6383..307623c0425 100644
--- a/library/std/src/sys/pal/xous/os.rs
+++ b/library/std/src/sys/pal/xous/os.rs
@@ -37,7 +37,7 @@ mod eh_unwinding {
 #[cfg(not(test))]
 mod c_compat {
     use crate::os::xous::ffi::exit;
-    extern "C" {
+    unsafe extern "C" {
         fn main() -> u32;
     }
 
diff --git a/library/std/src/sys/pal/zkvm/abi.rs b/library/std/src/sys/pal/zkvm/abi.rs
index 53332d90e02..d000574f684 100644
--- a/library/std/src/sys/pal/zkvm/abi.rs
+++ b/library/std/src/sys/pal/zkvm/abi.rs
@@ -18,7 +18,7 @@ pub mod fileno {
     pub const JOURNAL: u32 = 3;
 }
 
-extern "C" {
+unsafe extern "C" {
     // Wrappers around syscalls provided by risc0-zkvm-platform:
     pub fn sys_halt();
     pub fn sys_output(output_id: u32, output_value: u32);
diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs
index 9e9ae861070..054c867f90d 100644
--- a/library/std/src/sys/pal/zkvm/mod.rs
+++ b/library/std/src/sys/pal/zkvm/mod.rs
@@ -16,8 +16,6 @@ pub mod args;
 pub mod env;
 #[path = "../unsupported/fs.rs"]
 pub mod fs;
-#[path = "../unsupported/io.rs"]
-pub mod io;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
diff --git a/library/std/src/sys/pal/zkvm/stdio.rs b/library/std/src/sys/pal/zkvm/stdio.rs
index dd218c8894c..5f1d06dd1d7 100644
--- a/library/std/src/sys/pal/zkvm/stdio.rs
+++ b/library/std/src/sys/pal/zkvm/stdio.rs
@@ -54,7 +54,7 @@ impl io::Write for Stderr {
     }
 }
 
-pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
+pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
 
 pub fn is_ebadf(_err: &io::Error) -> bool {
     true
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index 88a25caeff0..cd2c7899f4b 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -194,7 +194,7 @@ cfg_if::cfg_if! {
                     }
                 }
                 // defined in libgcc
-                extern "C" {
+                unsafe extern "C" {
                     fn __gnu_unwind_frame(
                         exception_object: *mut uw::_Unwind_Exception,
                         context: *mut uw::_Unwind_Context,
diff --git a/library/std/src/sys/random/arc4random.rs b/library/std/src/sys/random/arc4random.rs
index 32467e9ebaa..e1957bceb90 100644
--- a/library/std/src/sys/random/arc4random.rs
+++ b/library/std/src/sys/random/arc4random.rs
@@ -25,7 +25,7 @@ use libc::arc4random_buf;
     target_os = "vita", // See https://github.com/vitasdk/newlib/blob/b89e5bc183b516945f9ee07eef483ecb916e45ff/newlib/libc/include/stdlib.h#L74
 ))]
 #[cfg_attr(target_os = "haiku", link(name = "bsd"))]
-extern "C" {
+unsafe extern "C" {
     fn arc4random_buf(buf: *mut core::ffi::c_void, nbytes: libc::size_t);
 }
 
diff --git a/library/std/src/sys/random/espidf.rs b/library/std/src/sys/random/espidf.rs
index fd52cb5559c..6f48f7f1f29 100644
--- a/library/std/src/sys/random/espidf.rs
+++ b/library/std/src/sys/random/espidf.rs
@@ -1,6 +1,6 @@
 use crate::ffi::c_void;
 
-extern "C" {
+unsafe extern "C" {
     fn esp_fill_random(buf: *mut c_void, len: usize);
 }
 
diff --git a/library/std/src/sys/random/fuchsia.rs b/library/std/src/sys/random/fuchsia.rs
index 77d72b3c5b7..269e0d9aeeb 100644
--- a/library/std/src/sys/random/fuchsia.rs
+++ b/library/std/src/sys/random/fuchsia.rs
@@ -4,7 +4,7 @@
 //! <https://fuchsia.dev/reference/syscalls/cprng_draw>.
 
 #[link(name = "zircon")]
-extern "C" {
+unsafe extern "C" {
     fn zx_cprng_draw(buffer: *mut u8, len: usize);
 }
 
diff --git a/library/std/src/sys/random/teeos.rs b/library/std/src/sys/random/teeos.rs
index fd6b24e19e9..6ca59cc12c9 100644
--- a/library/std/src/sys/random/teeos.rs
+++ b/library/std/src/sys/random/teeos.rs
@@ -1,4 +1,4 @@
-extern "C" {
+unsafe extern "C" {
     fn TEE_GenerateRandom(randomBuffer: *mut core::ffi::c_void, randomBufferLen: libc::size_t);
 }
 
diff --git a/library/std/src/sys/sync/thread_parking/darwin.rs b/library/std/src/sys/sync/thread_parking/darwin.rs
index 0553c5e19a9..a0d24a91e7c 100644
--- a/library/std/src/sys/sync/thread_parking/darwin.rs
+++ b/library/std/src/sys/sync/thread_parking/darwin.rs
@@ -24,7 +24,7 @@ const DISPATCH_TIME_NOW: dispatch_time_t = 0;
 const DISPATCH_TIME_FOREVER: dispatch_time_t = !0;
 
 // Contained in libSystem.dylib, which is linked by default.
-extern "C" {
+unsafe extern "C" {
     fn dispatch_time(when: dispatch_time_t, delta: i64) -> dispatch_time_t;
     fn dispatch_semaphore_create(val: isize) -> dispatch_semaphore_t;
     fn dispatch_semaphore_wait(dsema: dispatch_semaphore_t, timeout: dispatch_time_t) -> isize;
diff --git a/library/std/src/sys/thread_local/destructors/linux_like.rs b/library/std/src/sys/thread_local/destructors/linux_like.rs
index f473dc4d79d..817941229ee 100644
--- a/library/std/src/sys/thread_local/destructors/linux_like.rs
+++ b/library/std/src/sys/thread_local/destructors/linux_like.rs
@@ -27,7 +27,7 @@ pub unsafe fn register(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
     #[allow(non_camel_case_types)]
     pub struct c_int(#[allow(dead_code)] pub core::ffi::c_int);
 
-    extern "C" {
+    unsafe extern "C" {
         #[linkage = "extern_weak"]
         static __dso_handle: *mut u8;
         #[linkage = "extern_weak"]
diff --git a/library/std/src/sys/thread_local/guard/apple.rs b/library/std/src/sys/thread_local/guard/apple.rs
index fa25b116622..edcedf21e9e 100644
--- a/library/std/src/sys/thread_local/guard/apple.rs
+++ b/library/std/src/sys/thread_local/guard/apple.rs
@@ -10,7 +10,7 @@ pub fn enable() {
     #[thread_local]
     static REGISTERED: Cell<bool> = Cell::new(false);
 
-    extern "C" {
+    unsafe extern "C" {
         fn _tlv_atexit(dtor: unsafe extern "C" fn(*mut u8), arg: *mut u8);
     }
 
diff --git a/library/std/src/sys/thread_local/guard/windows.rs b/library/std/src/sys/thread_local/guard/windows.rs
index 1752b0e1208..b15a0d7c0bd 100644
--- a/library/std/src/sys/thread_local/guard/windows.rs
+++ b/library/std/src/sys/thread_local/guard/windows.rs
@@ -74,7 +74,7 @@ pub fn enable() {
     unsafe { ptr::from_ref(&CALLBACK).read_volatile() };
 }
 
-#[link_section = ".CRT$XLB"]
+#[unsafe(link_section = ".CRT$XLB")]
 #[cfg_attr(miri, used)] // Miri only considers explicitly `#[used]` statics for `lookup_link_section`
 pub static CALLBACK: unsafe extern "system" fn(*mut c_void, u32, *mut c_void) = tls_callback;
 
diff --git a/library/std/src/sys/thread_local/key/unix.rs b/library/std/src/sys/thread_local/key/unix.rs
index b4b58b34706..93bd0d1f668 100644
--- a/library/std/src/sys/thread_local/key/unix.rs
+++ b/library/std/src/sys/thread_local/key/unix.rs
@@ -8,7 +8,7 @@ mod libc {
     #[allow(non_camel_case_types)]
     pub type pthread_key_t = ffi::c_uint;
 
-    extern "C" {
+    unsafe extern "C" {
         pub fn pthread_key_create(
             key: *mut pthread_key_t,
             destructor: unsafe extern "C" fn(*mut ffi::c_void),
diff --git a/library/std/src/sys/thread_local/key/xous.rs b/library/std/src/sys/thread_local/key/xous.rs
index 2ab4bba7d8e..6c5e6447d19 100644
--- a/library/std/src/sys/thread_local/key/xous.rs
+++ b/library/std/src/sys/thread_local/key/xous.rs
@@ -59,7 +59,7 @@ static TLS_KEY_INDEX: AtomicUsize = AtomicUsize::new(1);
 static DTORS: AtomicPtr<Node> = AtomicPtr::new(ptr::null_mut());
 
 #[cfg(test)]
-extern "Rust" {
+unsafe extern "Rust" {
     #[link_name = "_ZN16__rust_internals3std3sys4xous16thread_local_key13TLS_KEY_INDEXE"]
     static TLS_KEY_INDEX: AtomicUsize;
 
diff --git a/library/std/src/sys_common/io.rs b/library/std/src/sys_common/io.rs
deleted file mode 100644
index 6f6f282d432..00000000000
--- a/library/std/src/sys_common/io.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Bare metal platforms usually have very small amounts of RAM
-// (in the order of hundreds of KB)
-pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 };
-
-#[cfg(test)]
-#[allow(dead_code)] // not used on emscripten and wasi
-pub mod test {
-    use rand::RngCore;
-
-    use crate::path::{Path, PathBuf};
-    use crate::{env, fs, thread};
-
-    pub struct TempDir(PathBuf);
-
-    impl TempDir {
-        pub fn join(&self, path: &str) -> PathBuf {
-            let TempDir(ref p) = *self;
-            p.join(path)
-        }
-
-        pub fn path(&self) -> &Path {
-            let TempDir(ref p) = *self;
-            p
-        }
-    }
-
-    impl Drop for TempDir {
-        fn drop(&mut self) {
-            // Gee, seeing how we're testing the fs module I sure hope that we
-            // at least implement this correctly!
-            let TempDir(ref p) = *self;
-            let result = fs::remove_dir_all(p);
-            // Avoid panicking while panicking as this causes the process to
-            // immediately abort, without displaying test results.
-            if !thread::panicking() {
-                result.unwrap();
-            }
-        }
-    }
-
-    #[track_caller] // for `test_rng`
-    pub fn tmpdir() -> TempDir {
-        let p = env::temp_dir();
-        let mut r = crate::test_helpers::test_rng();
-        let ret = p.join(&format!("rust-{}", r.next_u32()));
-        fs::create_dir(&ret).unwrap();
-        TempDir(ret)
-    }
-}
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 959fbd4ca0a..4dc67d26bd8 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -21,7 +21,6 @@
 mod tests;
 
 pub mod fs;
-pub mod io;
 pub mod process;
 pub mod wstr;
 pub mod wtf8;
diff --git a/library/std/src/sys_common/wtf8/tests.rs b/library/std/src/sys_common/wtf8/tests.rs
index bc06eaa2b8f..b57c99a8452 100644
--- a/library/std/src/sys_common/wtf8/tests.rs
+++ b/library/std/src/sys_common/wtf8/tests.rs
@@ -356,32 +356,32 @@ fn wtf8buf_from_iterator() {
     fn f(values: &[u32]) -> Wtf8Buf {
         values.iter().map(|&c| CodePoint::from_u32(c).unwrap()).collect::<Wtf8Buf>()
     }
-    assert_eq!(f(&[0x61, 0xE9, 0x20, 0x1F4A9]), Wtf8Buf {
-        bytes: b"a\xC3\xA9 \xF0\x9F\x92\xA9".to_vec(),
-        is_known_utf8: true
-    });
+    assert_eq!(
+        f(&[0x61, 0xE9, 0x20, 0x1F4A9]),
+        Wtf8Buf { bytes: b"a\xC3\xA9 \xF0\x9F\x92\xA9".to_vec(), is_known_utf8: true }
+    );
 
     assert_eq!(f(&[0xD83D, 0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic!
-    assert_eq!(f(&[0xD83D, 0x20, 0xDCA9]), Wtf8Buf {
-        bytes: b"\xED\xA0\xBD \xED\xB2\xA9".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(f(&[0xD800, 0xDBFF]), Wtf8Buf {
-        bytes: b"\xED\xA0\x80\xED\xAF\xBF".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(f(&[0xD800, 0xE000]), Wtf8Buf {
-        bytes: b"\xED\xA0\x80\xEE\x80\x80".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(f(&[0xD7FF, 0xDC00]), Wtf8Buf {
-        bytes: b"\xED\x9F\xBF\xED\xB0\x80".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(f(&[0x61, 0xDC00]), Wtf8Buf {
-        bytes: b"\x61\xED\xB0\x80".to_vec(),
-        is_known_utf8: false
-    });
+    assert_eq!(
+        f(&[0xD83D, 0x20, 0xDCA9]),
+        Wtf8Buf { bytes: b"\xED\xA0\xBD \xED\xB2\xA9".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        f(&[0xD800, 0xDBFF]),
+        Wtf8Buf { bytes: b"\xED\xA0\x80\xED\xAF\xBF".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        f(&[0xD800, 0xE000]),
+        Wtf8Buf { bytes: b"\xED\xA0\x80\xEE\x80\x80".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        f(&[0xD7FF, 0xDC00]),
+        Wtf8Buf { bytes: b"\xED\x9F\xBF\xED\xB0\x80".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        f(&[0x61, 0xDC00]),
+        Wtf8Buf { bytes: b"\x61\xED\xB0\x80".to_vec(), is_known_utf8: false }
+    );
     assert_eq!(f(&[0xDC00]), Wtf8Buf { bytes: b"\xED\xB0\x80".to_vec(), is_known_utf8: false });
 }
 
@@ -396,36 +396,36 @@ fn wtf8buf_extend() {
         string
     }
 
-    assert_eq!(e(&[0x61, 0xE9], &[0x20, 0x1F4A9]), Wtf8Buf {
-        bytes: b"a\xC3\xA9 \xF0\x9F\x92\xA9".to_vec(),
-        is_known_utf8: true
-    });
+    assert_eq!(
+        e(&[0x61, 0xE9], &[0x20, 0x1F4A9]),
+        Wtf8Buf { bytes: b"a\xC3\xA9 \xF0\x9F\x92\xA9".to_vec(), is_known_utf8: true }
+    );
 
     assert_eq!(e(&[0xD83D], &[0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic!
-    assert_eq!(e(&[0xD83D, 0x20], &[0xDCA9]), Wtf8Buf {
-        bytes: b"\xED\xA0\xBD \xED\xB2\xA9".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(e(&[0xD800], &[0xDBFF]), Wtf8Buf {
-        bytes: b"\xED\xA0\x80\xED\xAF\xBF".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(e(&[0xD800], &[0xE000]), Wtf8Buf {
-        bytes: b"\xED\xA0\x80\xEE\x80\x80".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(e(&[0xD7FF], &[0xDC00]), Wtf8Buf {
-        bytes: b"\xED\x9F\xBF\xED\xB0\x80".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(e(&[0x61], &[0xDC00]), Wtf8Buf {
-        bytes: b"\x61\xED\xB0\x80".to_vec(),
-        is_known_utf8: false
-    });
-    assert_eq!(e(&[], &[0xDC00]), Wtf8Buf {
-        bytes: b"\xED\xB0\x80".to_vec(),
-        is_known_utf8: false
-    });
+    assert_eq!(
+        e(&[0xD83D, 0x20], &[0xDCA9]),
+        Wtf8Buf { bytes: b"\xED\xA0\xBD \xED\xB2\xA9".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        e(&[0xD800], &[0xDBFF]),
+        Wtf8Buf { bytes: b"\xED\xA0\x80\xED\xAF\xBF".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        e(&[0xD800], &[0xE000]),
+        Wtf8Buf { bytes: b"\xED\xA0\x80\xEE\x80\x80".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        e(&[0xD7FF], &[0xDC00]),
+        Wtf8Buf { bytes: b"\xED\x9F\xBF\xED\xB0\x80".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        e(&[0x61], &[0xDC00]),
+        Wtf8Buf { bytes: b"\x61\xED\xB0\x80".to_vec(), is_known_utf8: false }
+    );
+    assert_eq!(
+        e(&[], &[0xDC00]),
+        Wtf8Buf { bytes: b"\xED\xB0\x80".to_vec(), is_known_utf8: false }
+    );
 }
 
 #[test]
@@ -556,9 +556,10 @@ fn wtf8_encode_wide() {
     let mut string = Wtf8Buf::from_str("aé ");
     string.push(CodePoint::from_u32(0xD83D).unwrap());
     string.push_char('💩');
-    assert_eq!(string.encode_wide().collect::<Vec<_>>(), vec![
-        0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9
-    ]);
+    assert_eq!(
+        string.encode_wide().collect::<Vec<_>>(),
+        vec![0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]
+    );
 }
 
 #[test]
diff --git a/library/std/src/test_helpers.rs b/library/std/src/test_helpers.rs
new file mode 100644
index 00000000000..7c20f38c863
--- /dev/null
+++ b/library/std/src/test_helpers.rs
@@ -0,0 +1,65 @@
+use rand::{RngCore, SeedableRng};
+
+use crate::hash::{BuildHasher, Hash, Hasher, RandomState};
+use crate::panic::Location;
+use crate::path::{Path, PathBuf};
+use crate::{env, fs, thread};
+
+/// Test-only replacement for `rand::thread_rng()`, which is unusable for
+/// us, as we want to allow running stdlib tests on tier-3 targets which may
+/// not have `getrandom` support.
+///
+/// Does a bit of a song and dance to ensure that the seed is different on
+/// each call (as some tests sadly rely on this), but doesn't try that hard.
+///
+/// This is duplicated in the `core`, `alloc` test suites (as well as
+/// `std`'s integration tests), but figuring out a mechanism to share these
+/// seems far more painful than copy-pasting a 7 line function a couple
+/// times, given that even under a perma-unstable feature, I don't think we
+/// want to expose types from `rand` from `std`.
+#[track_caller]
+pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
+    let mut hasher = RandomState::new().build_hasher();
+    Location::caller().hash(&mut hasher);
+    let hc64 = hasher.finish();
+    let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
+    let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
+    SeedableRng::from_seed(seed)
+}
+
+pub struct TempDir(PathBuf);
+
+impl TempDir {
+    pub fn join(&self, path: &str) -> PathBuf {
+        let TempDir(ref p) = *self;
+        p.join(path)
+    }
+
+    pub fn path(&self) -> &Path {
+        let TempDir(ref p) = *self;
+        p
+    }
+}
+
+impl Drop for TempDir {
+    fn drop(&mut self) {
+        // Gee, seeing how we're testing the fs module I sure hope that we
+        // at least implement this correctly!
+        let TempDir(ref p) = *self;
+        let result = fs::remove_dir_all(p);
+        // Avoid panicking while panicking as this causes the process to
+        // immediately abort, without displaying test results.
+        if !thread::panicking() {
+            result.unwrap();
+        }
+    }
+}
+
+#[track_caller] // for `test_rng`
+pub fn tmpdir() -> TempDir {
+    let p = env::temp_dir();
+    let mut r = test_rng();
+    let ret = p.join(&format!("rust-{}", r.next_u32()));
+    fs::create_dir(&ret).unwrap();
+    TempDir(ret)
+}
diff --git a/library/std/tests/common/mod.rs b/library/std/tests/common/mod.rs
index 7cf70c725e4..1e8e4cced6c 100644
--- a/library/std/tests/common/mod.rs
+++ b/library/std/tests/common/mod.rs
@@ -18,7 +18,7 @@ pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
     rand::SeedableRng::from_seed(seed)
 }
 
-// Copied from std::sys_common::io
+// Copied from std::test_helpers
 pub(crate) struct TempDir(PathBuf);
 
 impl TempDir {
diff --git a/library/std/tests/switch-stdout.rs b/library/std/tests/switch-stdout.rs
index 42011a9b3da..91fe0200f6c 100644
--- a/library/std/tests/switch-stdout.rs
+++ b/library/std/tests/switch-stdout.rs
@@ -14,7 +14,7 @@ use std::os::windows::io::OwnedHandle;
 fn switch_stdout_to(file: OwnedFd) -> OwnedFd {
     use std::os::unix::prelude::*;
 
-    extern "C" {
+    unsafe extern "C" {
         fn dup(old: i32) -> i32;
         fn dup2(old: i32, new: i32) -> i32;
     }
@@ -32,7 +32,7 @@ fn switch_stdout_to(file: OwnedFd) -> OwnedFd {
 fn switch_stdout_to(file: OwnedHandle) -> OwnedHandle {
     use std::os::windows::prelude::*;
 
-    extern "system" {
+    unsafe extern "system" {
         fn GetStdHandle(nStdHandle: u32) -> *mut u8;
         fn SetStdHandle(nStdHandle: u32, handle: *mut u8) -> i32;
     }
diff --git a/library/std/tests/win_delete_self.rs b/library/std/tests/win_delete_self.rs
new file mode 100644
index 00000000000..ce505de69a2
--- /dev/null
+++ b/library/std/tests/win_delete_self.rs
@@ -0,0 +1,9 @@
+#![cfg(windows)]
+
+/// Attempting to delete a running binary should return an error on Windows.
+#[test]
+#[cfg_attr(miri, ignore)] // `remove_file` does not work in Miri on Windows
+fn win_delete_self() {
+    let path = std::env::current_exe().unwrap();
+    assert!(std::fs::remove_file(path).is_err());
+}
diff --git a/library/test/src/console.rs b/library/test/src/console.rs
index 024ef48fc51..8f29f1dada5 100644
--- a/library/test/src/console.rs
+++ b/library/test/src/console.rs
@@ -314,9 +314,10 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
     let mut st = ConsoleTestState::new(opts)?;
 
     // Prevent the usage of `Instant` in some cases:
-    // - It's currently not supported for wasm targets.
+    // - It's currently not supported for wasm targets without Emscripten nor WASI.
+    // - It's currently not supported for zkvm targets.
     let is_instant_unsupported =
-        (cfg!(target_family = "wasm") && !cfg!(target_os = "wasi")) || cfg!(target_os = "zkvm");
+        (cfg!(target_family = "wasm") && cfg!(target_os = "unknown")) || cfg!(target_os = "zkvm");
 
     let start_time = (!is_instant_unsupported).then(Instant::now);
     run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs
index 57b1b0fecee..36158b0258a 100644
--- a/library/test/src/formatters/junit.rs
+++ b/library/test/src/formatters/junit.rs
@@ -39,15 +39,15 @@ fn str_to_cdata(s: &str) -> String {
 
 impl<T: Write> OutputFormatter for JunitFormatter<T> {
     fn write_discovery_start(&mut self) -> io::Result<()> {
-        Err(io::Error::new(io::ErrorKind::NotFound, "Not yet implemented!"))
+        Err(io::const_error!(io::ErrorKind::NotFound, "Not yet implemented!"))
     }
 
     fn write_test_discovered(&mut self, _desc: &TestDesc, _test_type: &str) -> io::Result<()> {
-        Err(io::Error::new(io::ErrorKind::NotFound, "Not yet implemented!"))
+        Err(io::const_error!(io::ErrorKind::NotFound, "Not yet implemented!"))
     }
 
     fn write_discovery_finish(&mut self, _state: &ConsoleTestDiscoveryState) -> io::Result<()> {
-        Err(io::Error::new(io::ErrorKind::NotFound, "Not yet implemented!"))
+        Err(io::const_error!(io::ErrorKind::NotFound, "Not yet implemented!"))
     }
 
     fn write_run_start(
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 54f7e4ae79f..7ada3f269a0 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -20,6 +20,7 @@
 #![feature(rustdoc_internals)]
 #![feature(file_buffered)]
 #![feature(internal_output_capture)]
+#![feature(io_const_error)]
 #![feature(staged_api)]
 #![feature(process_exitcode_internals)]
 #![feature(panic_can_unwind)]
@@ -184,12 +185,16 @@ pub fn test_main_static_abort(tests: &[&TestDescAndFn]) {
     // If we're being run in SpawnedSecondary mode, run the test here. run_test
     // will then exit the process.
     if let Ok(name) = env::var(SECONDARY_TEST_INVOKER_VAR) {
-        env::remove_var(SECONDARY_TEST_INVOKER_VAR);
+        unsafe {
+            env::remove_var(SECONDARY_TEST_INVOKER_VAR);
+        }
 
         // Convert benchmarks to tests if we're not benchmarking.
         let mut tests = tests.iter().map(make_owned_test).collect::<Vec<_>>();
         if env::var(SECONDARY_TEST_BENCH_BENCHMARKS_VAR).is_ok() {
-            env::remove_var(SECONDARY_TEST_BENCH_BENCHMARKS_VAR);
+            unsafe {
+                env::remove_var(SECONDARY_TEST_BENCH_BENCHMARKS_VAR);
+            }
         } else {
             tests = convert_benchmarks_to_tests(tests);
         };
diff --git a/library/test/src/term/terminfo/mod.rs b/library/test/src/term/terminfo/mod.rs
index 974b8afd598..75fa594908d 100644
--- a/library/test/src/term/terminfo/mod.rs
+++ b/library/test/src/term/terminfo/mod.rs
@@ -90,7 +90,7 @@ impl TermInfo {
 
         get_dbpath_for_term(name)
             .ok_or_else(|| {
-                Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
+                Error::IoError(io::const_error!(io::ErrorKind::NotFound, "terminfo file not found"))
             })
             .and_then(|p| TermInfo::from_path(&(*p)))
     }
diff --git a/library/test/src/term/terminfo/parser/compiled.rs b/library/test/src/term/terminfo/parser/compiled.rs
index e687b3be41f..d1dd0f10d86 100644
--- a/library/test/src/term/terminfo/parser/compiled.rs
+++ b/library/test/src/term/terminfo/parser/compiled.rs
@@ -173,7 +173,7 @@ fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> {
 fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
     match r.bytes().next() {
         Some(s) => s,
-        None => Err(io::Error::new(io::ErrorKind::Other, "end of file")),
+        None => Err(io::const_error!(io::ErrorKind::Other, "end of file")),
     }
 }
 
diff --git a/library/test/src/term/win.rs b/library/test/src/term/win.rs
index c77e6aac478..62e5c43ea27 100644
--- a/library/test/src/term/win.rs
+++ b/library/test/src/term/win.rs
@@ -52,7 +52,7 @@ struct CONSOLE_SCREEN_BUFFER_INFO {
 
 #[allow(non_snake_case)]
 #[link(name = "kernel32")]
-extern "system" {
+unsafe extern "system" {
     fn SetConsoleTextAttribute(handle: HANDLE, attr: WORD) -> BOOL;
     fn GetStdHandle(which: DWORD) -> HANDLE;
     fn GetConsoleScreenBufferInfo(handle: HANDLE, info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL;
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index e4ba2bc1ed8..2650b273a4d 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -56,15 +56,15 @@ cfg_if::cfg_if! {
         compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time");
     } else if #[cfg(feature = "llvm-libunwind")] {
         #[link(name = "unwind", kind = "static", modifiers = "-bundle")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else if #[cfg(feature = "system-llvm-libunwind")] {
         #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
         #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
-        extern "C" {}
+        unsafe extern "C" {}
     } else {
         #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
         #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
-        extern "C" {}
+        unsafe extern "C" {}
     }
 }
 
@@ -76,11 +76,11 @@ cfg_if::cfg_if! {
         compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time");
     } else if #[cfg(feature = "llvm-libunwind")] {
         #[link(name = "unwind", kind = "static", modifiers = "-bundle")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else {
         #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
         #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
-        extern "C" {}
+        unsafe extern "C" {}
     }
 }
 
@@ -91,14 +91,14 @@ cfg_if::cfg_if! {
     } else {
         #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
         #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
-        extern "C" {}
+        unsafe extern "C" {}
     }
 }
 // Android's unwinding library depends on dl_iterate_phdr in `libdl`.
 #[cfg(target_os = "android")]
 #[link(name = "dl", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
 #[link(name = "dl", cfg(not(target_feature = "crt-static")))]
-extern "C" {}
+unsafe extern "C" {}
 
 // When building with crt-static, we get `gcc_eh` from the `libc` crate, since
 // glibc needs it, and needs it listed later on the linker command line. We
@@ -110,7 +110,7 @@ extern "C" {}
     not(feature = "system-llvm-libunwind")
 ))]
 #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(all(
     target_os = "linux",
@@ -119,67 +119,67 @@ extern "C" {}
     feature = "system-llvm-libunwind"
 ))]
 #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(target_os = "redox")]
 #[link(name = "gcc_eh", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
 #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
 #[link(name = "unwind", kind = "static", modifiers = "-bundle")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(target_os = "netbsd")]
 #[link(name = "gcc_s")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(target_os = "freebsd")]
 #[link(name = "gcc", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
 #[link(name = "gcc_eh", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
 #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(all(target_os = "openbsd", target_arch = "sparc64"))]
 #[link(name = "gcc")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(all(target_os = "openbsd", not(target_arch = "sparc64")))]
 #[link(name = "c++abi")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(any(target_os = "solaris", target_os = "illumos"))]
 #[link(name = "gcc_s")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(target_os = "dragonfly")]
 #[link(name = "gcc_pic")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(target_os = "haiku")]
 #[link(name = "gcc_s")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(target_os = "aix")]
 #[link(name = "unwind")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(target_os = "nto")]
 cfg_if::cfg_if! {
     if #[cfg(target_env = "nto70")] {
         #[link(name = "gcc")]
-        extern "C" {}
+        unsafe extern "C" {}
     } else {
         #[link(name = "gcc_s")]
-        extern "C" {}
+        unsafe extern "C" {}
     }
 }
 
 #[cfg(target_os = "hurd")]
 #[link(name = "gcc_s")]
-extern "C" {}
+unsafe extern "C" {}
 
 #[cfg(all(target_os = "windows", target_env = "gnu", target_abi = "llvm"))]
 #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
 #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
-extern "C" {}
+unsafe extern "C" {}
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index 1fa9e480166..62165f8a200 100644
--- a/library/unwind/src/libunwind.rs
+++ b/library/unwind/src/libunwind.rs
@@ -108,10 +108,10 @@ pub type _Unwind_Exception_Cleanup_Fn =
     ),
     link(name = "unwind", kind = "static", modifiers = "-bundle")
 )]
-extern "C-unwind" {
+unsafe extern "C-unwind" {
     pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
 }
-extern "C" {
+unsafe extern "C" {
     pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
     pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void;
     pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
@@ -140,7 +140,7 @@ if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "a
         all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")),
         link(name = "unwind", kind = "static", modifiers = "-bundle")
     )]
-    extern "C" {
+    unsafe extern "C" {
         pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word;
         pub fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word);
         pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> _Unwind_Word;
@@ -198,7 +198,7 @@ if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "a
         all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")),
         link(name = "unwind", kind = "static", modifiers = "-bundle")
     )]
-    extern "C" {
+    unsafe extern "C" {
         fn _Unwind_VRS_Get(ctx: *mut _Unwind_Context,
                            regclass: _Unwind_VRS_RegClass,
                            regno: _Unwind_Word,
@@ -261,7 +261,7 @@ cfg_if::cfg_if! {
 if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"))] {
     // 32-bit ARM Apple (except for watchOS armv7k specifically) uses SjLj and
     // does not provide _Unwind_Backtrace()
-    extern "C-unwind" {
+    unsafe extern "C-unwind" {
         pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
     }
 
@@ -271,14 +271,14 @@ if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch =
         all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")),
         link(name = "unwind", kind = "static", modifiers = "-bundle")
     )]
-    extern "C-unwind" {
+    unsafe extern "C-unwind" {
         pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
     }
     #[cfg_attr(
         all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")),
         link(name = "unwind", kind = "static", modifiers = "-bundle")
     )]
-    extern "C" {
+    unsafe extern "C" {
         pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
                                  trace_argument: *mut c_void)
                                  -> _Unwind_Reason_Code;
@@ -302,7 +302,7 @@ if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), targ
                                               context: *mut _Unwind_Context)
                                               -> _Unwind_Reason_Code;
 
-    extern "C" {
+    unsafe extern "C" {
         pub fn _GCC_specific_handler(exceptionRecord: *mut EXCEPTION_RECORD,
                                 establisherFrame: LPVOID,
                                 contextRecord: *mut CONTEXT,
diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs
index 395cd6a4bab..e89bde8b1ab 100644
--- a/library/windows_targets/src/lib.rs
+++ b/library/windows_targets/src/lib.rs
@@ -39,4 +39,4 @@ pub macro link {
 #[link(name = "userenv")]
 #[link(name = "ws2_32")]
 #[link(name = "dbghelp")] // required for backtrace-rs symbolization
-extern "C" {}
+unsafe extern "C" {}
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp
index 42cecbf5df9..d2c0d380fb4 100644
--- a/src/bootstrap/download-ci-llvm-stamp
+++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@
 Change this file to make users of the `download-ci-llvm` configuration download
 a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
 
-Last change is for: https://github.com/rust-lang/rust/pull/129788
+Last change is for: https://github.com/rust-lang/rust/pull/134740
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index cd3558ac6a4..f6f9067b9c6 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -443,8 +443,49 @@ fn compiler_rt_for_profiler(builder: &Builder<'_>) -> PathBuf {
 /// Configure cargo to compile the standard library, adding appropriate env vars
 /// and such.
 pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) {
-    if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
-        cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
+    // rustc already ensures that it builds with the minimum deployment
+    // target, so ideally we shouldn't need to do anything here.
+    //
+    // However, `cc` currently defaults to a higher version for backwards
+    // compatibility, which means that compiler-rt, which is built via
+    // compiler-builtins' build script, gets built with a higher deployment
+    // target. This in turn causes warnings while linking, and is generally
+    // a compatibility hazard.
+    //
+    // So, at least until https://github.com/rust-lang/cc-rs/issues/1171, or
+    // perhaps https://github.com/rust-lang/cargo/issues/13115 is resolved, we
+    // explicitly set the deployment target environment variables to avoid
+    // this issue.
+    //
+    // This place also serves as an extension point if we ever wanted to raise
+    // rustc's default deployment target while keeping the prebuilt `std` at
+    // a lower version, so it's kinda nice to have in any case.
+    if target.contains("apple") && !builder.config.dry_run() {
+        // Query rustc for the deployment target, and the associated env var.
+        // The env var is one of the standard `*_DEPLOYMENT_TARGET` vars, i.e.
+        // `MACOSX_DEPLOYMENT_TARGET`, `IPHONEOS_DEPLOYMENT_TARGET`, etc.
+        let mut cmd = command(builder.rustc(cargo.compiler()));
+        cmd.arg("--target").arg(target.rustc_target_arg());
+        cmd.arg("--print=deployment-target");
+        let output = cmd.run_capture_stdout(builder).stdout();
+
+        let (env_var, value) = output.split_once('=').unwrap();
+        // Unconditionally set the env var (if it was set in the environment
+        // already, rustc should've picked that up).
+        cargo.env(env_var.trim(), value.trim());
+
+        // Allow CI to override the deployment target for `std` on macOS.
+        //
+        // This is useful because we might want the host tooling LLVM, `rustc`
+        // and Cargo to have a different deployment target than `std` itself
+        // (currently, these two versions are the same, but in the past, we
+        // supported macOS 10.7 for user code and macOS 10.8 in host tooling).
+        //
+        // It is not necessary on the other platforms, since only macOS has
+        // support for host tooling.
+        if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
+            cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
+        }
     }
 
     // Paths needed by `library/profiler_builtins/build.rs`.
@@ -1049,12 +1090,12 @@ pub fn rustc_cargo(
     // <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Internal.20lint.20for.20raw.20.60print!.60.20and.20.60println!.60.3F>.
     cargo.rustflag("-Zon-broken-pipe=kill");
 
-    // We temporarily disable linking here as part of some refactoring.
-    // This way, people can manually use -Z llvm-plugins and -C passes=enzyme for now.
-    // In a follow-up PR, we will re-enable linking here and load the pass for them.
-    //if builder.config.llvm_enzyme {
-    //    cargo.rustflag("-l").rustflag("Enzyme-19");
-    //}
+    // We want to link against registerEnzyme and in the future we want to use additional
+    // functionality from Enzyme core. For that we need to link against Enzyme.
+    // FIXME(ZuseZ4): Get the LLVM version number automatically instead of hardcoding it.
+    if builder.config.llvm_enzyme {
+        cargo.rustflag("-l").rustflag("Enzyme-19");
+    }
 
     // Building with protected visibility reduces the number of dynamic relocations needed, giving
     // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object
@@ -1234,6 +1275,9 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect
     if builder.is_rust_llvm(target) {
         cargo.env("LLVM_RUSTLLVM", "1");
     }
+    if builder.config.llvm_enzyme {
+        cargo.env("LLVM_ENZYME", "1");
+    }
     let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target });
     cargo.env("LLVM_CONFIG", &llvm_config);
 
@@ -1544,7 +1588,8 @@ pub fn compiler_file(
         return PathBuf::new();
     }
     let mut cmd = command(compiler);
-    cmd.args(builder.cflags(target, GitRepo::Rustc, c));
+    cmd.args(builder.cc_handled_clags(target, c));
+    cmd.args(builder.cc_unhandled_cflags(target, GitRepo::Rustc, c));
     cmd.arg(format!("-print-file-name={file}"));
     let out = cmd.run_capture_stdout(builder).stdout();
     PathBuf::from(out.trim())
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 0eb4080c053..dedcc139ae1 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -830,7 +830,8 @@ impl Step for Rustc {
         cargo.rustdocflag("--show-type-layout");
         // FIXME: `--generate-link-to-definition` tries to resolve cfged out code
         // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222
-        // cargo.rustdocflag("--generate-link-to-definition");
+        // If there is any bug, please comment out the next line.
+        cargo.rustdocflag("--generate-link-to-definition");
 
         compile::rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
         cargo.arg("-Zskip-rustdoc-fingerprint");
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 82779dc6306..9dd35057062 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -54,6 +54,14 @@ impl LlvmBuildStatus {
             LlvmBuildStatus::ShouldBuild(_) => true,
         }
     }
+
+    #[cfg(test)]
+    pub fn llvm_result(&self) -> &LlvmResult {
+        match self {
+            LlvmBuildStatus::AlreadyBuilt(res) => res,
+            LlvmBuildStatus::ShouldBuild(meta) => &meta.res,
+        }
+    }
 }
 
 /// Linker flags to pass to LLVM's CMake invocation.
@@ -120,9 +128,19 @@ pub fn prebuilt_llvm_config(
     let root = "src/llvm-project/llvm";
     let out_dir = builder.llvm_out(target);
 
-    let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
-    llvm_config_ret_dir.push("bin");
-    let build_llvm_config = llvm_config_ret_dir.join(exe("llvm-config", builder.config.build));
+    let build_llvm_config = if let Some(build_llvm_config) = builder
+        .config
+        .target_config
+        .get(&builder.config.build)
+        .and_then(|config| config.llvm_config.clone())
+    {
+        build_llvm_config
+    } else {
+        let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
+        llvm_config_ret_dir.push("bin");
+        llvm_config_ret_dir.join(exe("llvm-config", builder.config.build))
+    };
+
     let llvm_cmake_dir = out_dir.join("lib/cmake/llvm");
     let res = LlvmResult { llvm_config: build_llvm_config, llvm_cmake_dir };
 
@@ -157,12 +175,16 @@ pub fn prebuilt_llvm_config(
 /// This retrieves the LLVM sha we *want* to use, according to git history.
 pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
     let llvm_sha = if is_git {
-        get_closest_merge_commit(Some(&config.src), &config.git_config(), &[
-            config.src.join("src/llvm-project"),
-            config.src.join("src/bootstrap/download-ci-llvm-stamp"),
-            // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
-            config.src.join("src/version"),
-        ])
+        get_closest_merge_commit(
+            Some(&config.src),
+            &config.git_config(),
+            &[
+                config.src.join("src/llvm-project"),
+                config.src.join("src/bootstrap/download-ci-llvm-stamp"),
+                // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
+                config.src.join("src/version"),
+            ],
+        )
         .unwrap()
     } else if let Some(info) = crate::utils::channel::read_commit_info_file(&config.src) {
         info.sha.trim().to_owned()
@@ -331,7 +353,7 @@ impl Step for Llvm {
         let llvm_targets = match &builder.config.llvm_targets {
             Some(s) => s,
             None => {
-                "AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\
+                "AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\
                      Sparc;SystemZ;WebAssembly;X86"
             }
         };
@@ -757,9 +779,15 @@ fn configure_cmake(
     }
 
     cfg.build_arg("-j").build_arg(builder.jobs().to_string());
+    // FIXME(madsmtm): Allow `cmake-rs` to select flags by itself by passing
+    // our flags via `.cflag`/`.cxxflag` instead.
+    //
+    // Needs `suppressed_compiler_flag_prefixes` to be gone, and hence
+    // https://github.com/llvm/llvm-project/issues/88780 to be fixed.
     let mut cflags: OsString = builder
-        .cflags(target, GitRepo::Llvm, CLang::C)
+        .cc_handled_clags(target, CLang::C)
         .into_iter()
+        .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::C))
         .filter(|flag| {
             !suppressed_compiler_flag_prefixes
                 .iter()
@@ -778,8 +806,9 @@ fn configure_cmake(
     }
     cfg.define("CMAKE_C_FLAGS", cflags);
     let mut cxxflags: OsString = builder
-        .cflags(target, GitRepo::Llvm, CLang::Cxx)
+        .cc_handled_clags(target, CLang::Cxx)
         .into_iter()
+        .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::Cxx))
         .filter(|flag| {
             !suppressed_compiler_flag_prefixes
                 .iter()
@@ -964,6 +993,7 @@ impl Step for Enzyme {
             .env("LLVM_CONFIG_REAL", &llvm_config)
             .define("LLVM_ENABLE_ASSERTIONS", "ON")
             .define("ENZYME_EXTERNAL_SHARED_LIB", "ON")
+            .define("ENZYME_RUNPASS", "ON")
             .define("LLVM_DIR", builder.llvm_out(target));
 
         cfg.build();
diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs
index 5b83080a326..98c63a41e76 100644
--- a/src/bootstrap/src/core/build_steps/perf.rs
+++ b/src/bootstrap/src/core/build_steps/perf.rs
@@ -1,35 +1,231 @@
+use std::fmt::{Display, Formatter};
+
 use crate::core::build_steps::compile::{Std, Sysroot};
-use crate::core::build_steps::tool::{RustcPerf, Tool};
+use crate::core::build_steps::tool::{RustcPerf, Rustdoc};
 use crate::core::builder::Builder;
 use crate::core::config::DebuginfoLevel;
+use crate::utils::exec::{BootstrapCommand, command};
+
+#[derive(Debug, Clone, clap::Parser)]
+pub struct PerfArgs {
+    #[clap(subcommand)]
+    cmd: PerfCommand,
+}
+
+#[derive(Debug, Clone, clap::Parser)]
+enum PerfCommand {
+    /// Run `profile_local eprintln`.
+    /// This executes the compiler on the given benchmarks and stores its stderr output.
+    Eprintln {
+        #[clap(flatten)]
+        opts: SharedOpts,
+    },
+    /// Run `profile_local samply`
+    /// This executes the compiler on the given benchmarks and profiles it with `samply`.
+    /// You need to install `samply`, e.g. using `cargo install samply`.
+    Samply {
+        #[clap(flatten)]
+        opts: SharedOpts,
+    },
+    /// Run `profile_local cachegrind`.
+    /// This executes the compiler on the given benchmarks under `Cachegrind`.
+    Cachegrind {
+        #[clap(flatten)]
+        opts: SharedOpts,
+    },
+    /// Run compile benchmarks with a locally built compiler.
+    Benchmark {
+        /// Identifier to associate benchmark results with
+        #[clap(name = "benchmark-id")]
+        id: String,
+
+        #[clap(flatten)]
+        opts: SharedOpts,
+    },
+    /// Compare the results of two previously executed benchmark runs.
+    Compare {
+        /// The name of the base artifact to be compared.
+        base: String,
+
+        /// The name of the modified artifact to be compared.
+        modified: String,
+    },
+}
+
+impl PerfCommand {
+    fn shared_opts(&self) -> Option<&SharedOpts> {
+        match self {
+            PerfCommand::Eprintln { opts, .. }
+            | PerfCommand::Samply { opts, .. }
+            | PerfCommand::Cachegrind { opts, .. }
+            | PerfCommand::Benchmark { opts, .. } => Some(opts),
+            PerfCommand::Compare { .. } => None,
+        }
+    }
+}
+
+#[derive(Debug, Clone, clap::Parser)]
+struct SharedOpts {
+    /// Select the benchmarks that you want to run (separated by commas).
+    /// If unspecified, all benchmarks will be executed.
+    #[clap(long, global = true, value_delimiter = ',')]
+    include: Vec<String>,
+
+    /// Select the benchmarks matching a prefix in this comma-separated list that you don't want to run.
+    #[clap(long, global = true, value_delimiter = ',')]
+    exclude: Vec<String>,
+
+    /// Select the scenarios that should be benchmarked.
+    #[clap(
+        long,
+        global = true,
+        value_delimiter = ',',
+        default_value = "Full,IncrFull,IncrUnchanged,IncrPatched"
+    )]
+    scenarios: Vec<Scenario>,
+    /// Select the profiles that should be benchmarked.
+    #[clap(long, global = true, value_delimiter = ',', default_value = "Check,Debug,Opt")]
+    profiles: Vec<Profile>,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, clap::ValueEnum)]
+#[value(rename_all = "PascalCase")]
+pub enum Profile {
+    Check,
+    Debug,
+    Doc,
+    Opt,
+    Clippy,
+}
+
+impl Display for Profile {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        let name = match self {
+            Profile::Check => "Check",
+            Profile::Debug => "Debug",
+            Profile::Doc => "Doc",
+            Profile::Opt => "Opt",
+            Profile::Clippy => "Clippy",
+        };
+        f.write_str(name)
+    }
+}
+
+#[derive(Clone, Copy, Debug, clap::ValueEnum)]
+#[value(rename_all = "PascalCase")]
+pub enum Scenario {
+    Full,
+    IncrFull,
+    IncrUnchanged,
+    IncrPatched,
+}
+
+impl Display for Scenario {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        let name = match self {
+            Scenario::Full => "Full",
+            Scenario::IncrFull => "IncrFull",
+            Scenario::IncrUnchanged => "IncrUnchanged",
+            Scenario::IncrPatched => "IncrPatched",
+        };
+        f.write_str(name)
+    }
+}
 
 /// Performs profiling using `rustc-perf` on a built version of the compiler.
-pub fn perf(builder: &Builder<'_>) {
+pub fn perf(builder: &Builder<'_>, args: &PerfArgs) {
     let collector = builder.ensure(RustcPerf {
         compiler: builder.compiler(0, builder.config.build),
         target: builder.config.build,
     });
 
-    if builder.build.config.rust_debuginfo_level_rustc == DebuginfoLevel::None {
+    let is_profiling = match &args.cmd {
+        PerfCommand::Eprintln { .. }
+        | PerfCommand::Samply { .. }
+        | PerfCommand::Cachegrind { .. } => true,
+        PerfCommand::Benchmark { .. } | PerfCommand::Compare { .. } => false,
+    };
+    if is_profiling && builder.build.config.rust_debuginfo_level_rustc == DebuginfoLevel::None {
         builder.info(r#"WARNING: You are compiling rustc without debuginfo, this will make profiling less useful.
 Consider setting `rust.debuginfo-level = 1` in `config.toml`."#);
     }
 
     let compiler = builder.compiler(builder.top_stage, builder.config.build);
     builder.ensure(Std::new(compiler, builder.config.build));
+
+    if let Some(opts) = args.cmd.shared_opts() {
+        if opts.profiles.contains(&Profile::Doc) {
+            builder.ensure(Rustdoc { compiler });
+        }
+    }
+
     let sysroot = builder.ensure(Sysroot::new(compiler));
     let rustc = sysroot.join("bin/rustc");
 
     let rustc_perf_dir = builder.build.tempdir().join("rustc-perf");
-    let profile_results_dir = rustc_perf_dir.join("results");
+    let results_dir = rustc_perf_dir.join("results");
+    builder.create_dir(&results_dir);
+
+    let mut cmd = command(collector);
+
+    // We need to set the working directory to `src/tools/rustc-perf`, so that it can find the directory
+    // with compile-time benchmarks.
+    cmd.current_dir(builder.src.join("src/tools/rustc-perf"));
+
+    let db_path = results_dir.join("results.db");
+
+    match &args.cmd {
+        PerfCommand::Eprintln { opts }
+        | PerfCommand::Samply { opts }
+        | PerfCommand::Cachegrind { opts } => {
+            cmd.arg("profile_local");
+            cmd.arg(match &args.cmd {
+                PerfCommand::Eprintln { .. } => "eprintln",
+                PerfCommand::Samply { .. } => "samply",
+                PerfCommand::Cachegrind { .. } => "cachegrind",
+                _ => unreachable!(),
+            });
 
-    // We need to take args passed after `--` and pass them to `rustc-perf-wrapper`
-    let args = std::env::args().skip_while(|a| a != "--").skip(1);
+            cmd.arg("--out-dir").arg(&results_dir);
+            cmd.arg(rustc);
 
-    let mut cmd = builder.tool_cmd(Tool::RustcPerfWrapper);
-    cmd.env("RUSTC_REAL", rustc)
-        .env("PERF_COLLECTOR", collector)
-        .env("PERF_RESULT_DIR", profile_results_dir)
-        .args(args);
-    cmd.run(builder);
+            apply_shared_opts(&mut cmd, opts);
+            cmd.run(builder);
+
+            println!("You can find the results at `{}`", &results_dir.display());
+        }
+        PerfCommand::Benchmark { id, opts } => {
+            cmd.arg("bench_local");
+            cmd.arg("--db").arg(&db_path);
+            cmd.arg("--id").arg(id);
+            cmd.arg(rustc);
+
+            apply_shared_opts(&mut cmd, opts);
+            cmd.run(builder);
+        }
+        PerfCommand::Compare { base, modified } => {
+            cmd.arg("bench_cmp");
+            cmd.arg("--db").arg(&db_path);
+            cmd.arg(base).arg(modified);
+
+            cmd.run(builder);
+        }
+    }
+}
+
+fn apply_shared_opts(cmd: &mut BootstrapCommand, opts: &SharedOpts) {
+    if !opts.include.is_empty() {
+        cmd.arg("--include").arg(opts.include.join(","));
+    }
+    if !opts.exclude.is_empty() {
+        cmd.arg("--exclude").arg(opts.exclude.join(","));
+    }
+    if !opts.profiles.is_empty() {
+        cmd.arg("--profiles")
+            .arg(opts.profiles.iter().map(|p| p.to_string()).collect::<Vec<_>>().join(","));
+    }
+    if !opts.scenarios.is_empty() {
+        cmd.arg("--scenarios")
+            .arg(opts.scenarios.iter().map(|p| p.to_string()).collect::<Vec<_>>().join(","));
+    }
 }
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 825e5452f0e..c452f4cd6ae 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1648,16 +1648,17 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         // bootstrap compiler.
         // NOTE: Only stage 1 is special cased because we need the rustc_private artifacts to match the
         // running compiler in stage 2 when plugins run.
-        let stage_id = if suite == "ui-fulldeps" && compiler.stage == 1 {
-            // At stage 0 (stage - 1) we are using the beta compiler. Using `self.target` can lead finding
-            // an incorrect compiler path on cross-targets, as the stage 0 beta compiler is always equal
-            // to `build.build` in the configuration.
+        let (stage, stage_id) = if suite == "ui-fulldeps" && compiler.stage == 1 {
+            // At stage 0 (stage - 1) we are using the beta compiler. Using `self.target` can lead
+            // finding an incorrect compiler path on cross-targets, as the stage 0 beta compiler is
+            // always equal to `build.build` in the configuration.
             let build = builder.build.build;
-
             compiler = builder.compiler(compiler.stage - 1, build);
-            format!("stage{}-{}", compiler.stage + 1, build)
+            let test_stage = compiler.stage + 1;
+            (test_stage, format!("stage{}-{}", test_stage, build))
         } else {
-            format!("stage{}-{}", compiler.stage, target)
+            let stage = compiler.stage;
+            (stage, format!("stage{}-{}", stage, target))
         };
 
         if suite.ends_with("fulldeps") {
@@ -1699,6 +1700,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         // compiletest currently has... a lot of arguments, so let's just pass all
         // of them!
 
+        cmd.arg("--stage").arg(stage.to_string());
+        cmd.arg("--stage-id").arg(stage_id);
+
         cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler));
         cmd.arg("--run-lib-path").arg(builder.sysroot_target_libdir(compiler, target));
         cmd.arg("--rustc-path").arg(builder.rustc(compiler));
@@ -1767,8 +1771,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         } else {
             builder.sysroot(compiler).to_path_buf()
         };
+
         cmd.arg("--sysroot-base").arg(sysroot);
-        cmd.arg("--stage-id").arg(stage_id);
+
         cmd.arg("--suite").arg(suite);
         cmd.arg("--mode").arg(mode);
         cmd.arg("--target").arg(target.rustc_target_arg());
@@ -2006,14 +2011,18 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         // Only pass correct values for these flags for the `run-make` suite as it
         // requires that a C++ compiler was configured which isn't always the case.
         if !builder.config.dry_run() && mode == "run-make" {
+            let mut cflags = builder.cc_handled_clags(target, CLang::C);
+            cflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C));
+            let mut cxxflags = builder.cc_handled_clags(target, CLang::Cxx);
+            cxxflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx));
             cmd.arg("--cc")
                 .arg(builder.cc(target))
                 .arg("--cxx")
                 .arg(builder.cxx(target).unwrap())
                 .arg("--cflags")
-                .arg(builder.cflags(target, GitRepo::Rustc, CLang::C).join(" "))
+                .arg(cflags.join(" "))
                 .arg("--cxxflags")
-                .arg(builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" "));
+                .arg(cxxflags.join(" "));
             copts_passed = true;
             if let Some(ar) = builder.ar(target) {
                 cmd.arg("--ar").arg(ar);
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 75fac88252b..793fa24991b 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -362,7 +362,6 @@ bootstrap_tool!(
     GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys";
     RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = "test";
     CoverageDump, "src/tools/coverage-dump", "coverage-dump";
-    RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper";
     WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
     UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator";
     FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump";
@@ -582,7 +581,7 @@ impl Step for Rustdoc {
             if !target_compiler.is_snapshot(builder) {
                 panic!("rustdoc in stage 0 must be snapshot rustdoc");
             }
-            return builder.initial_rustc.with_file_name(exe("rustdoc", target_compiler.host));
+            return builder.initial_rustdoc.clone();
         }
         let target = target_compiler.host;
 
diff --git a/src/bootstrap/src/core/build_steps/toolstate.rs b/src/bootstrap/src/core/build_steps/toolstate.rs
index 84871331bd5..668133f05cb 100644
--- a/src/bootstrap/src/core/build_steps/toolstate.rs
+++ b/src/bootstrap/src/core/build_steps/toolstate.rs
@@ -42,11 +42,15 @@ pub enum ToolState {
 
 impl fmt::Display for ToolState {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", match self {
-            ToolState::TestFail => "test-fail",
-            ToolState::TestPass => "test-pass",
-            ToolState::BuildFail => "build-fail",
-        })
+        write!(
+            f,
+            "{}",
+            match self {
+                ToolState::TestFail => "test-fail",
+                ToolState::TestPass => "test-pass",
+                ToolState::BuildFail => "build-fail",
+            }
+        )
     }
 }
 
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 2ecab262413..205649b12bb 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -323,8 +323,15 @@ impl Cargo {
             let cc = ccacheify(&builder.cc(target));
             self.command.env(format!("CC_{triple_underscored}"), &cc);
 
-            let cflags = builder.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
-            self.command.env(format!("CFLAGS_{triple_underscored}"), &cflags);
+            // Extend `CXXFLAGS_$TARGET` with our extra flags.
+            let env = format!("CFLAGS_{triple_underscored}");
+            let mut cflags =
+                builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C).join(" ");
+            if let Ok(var) = std::env::var(&env) {
+                cflags.push(' ');
+                cflags.push_str(&var);
+            }
+            self.command.env(env, &cflags);
 
             if let Some(ar) = builder.ar(target) {
                 let ranlib = format!("{} s", ar.display());
@@ -335,10 +342,17 @@ impl Cargo {
 
             if let Ok(cxx) = builder.cxx(target) {
                 let cxx = ccacheify(&cxx);
-                let cxxflags = builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
-                self.command
-                    .env(format!("CXX_{triple_underscored}"), &cxx)
-                    .env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
+                self.command.env(format!("CXX_{triple_underscored}"), &cxx);
+
+                // Extend `CXXFLAGS_$TARGET` with our extra flags.
+                let env = format!("CXXFLAGS_{triple_underscored}");
+                let mut cxxflags =
+                    builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
+                if let Ok(var) = std::env::var(&env) {
+                    cxxflags.push(' ');
+                    cxxflags.push_str(&var);
+                }
+                self.command.env(&env, cxxflags);
             }
         }
 
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 08421dc1f5b..8e767a8dcc6 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -315,29 +315,32 @@ const PATH_REMAP: &[(&str, &[&str])] = &[
     // actual path is `proc-macro-srv-cli`
     ("rust-analyzer-proc-macro-srv", &["src/tools/rust-analyzer/crates/proc-macro-srv-cli"]),
     // Make `x test tests` function the same as `x t tests/*`
-    ("tests", &[
-        // tidy-alphabetical-start
-        "tests/assembly",
-        "tests/codegen",
-        "tests/codegen-units",
-        "tests/coverage",
-        "tests/coverage-run-rustdoc",
-        "tests/crashes",
-        "tests/debuginfo",
-        "tests/incremental",
-        "tests/mir-opt",
-        "tests/pretty",
-        "tests/run-make",
-        "tests/rustdoc",
-        "tests/rustdoc-gui",
-        "tests/rustdoc-js",
-        "tests/rustdoc-js-std",
-        "tests/rustdoc-json",
-        "tests/rustdoc-ui",
-        "tests/ui",
-        "tests/ui-fulldeps",
-        // tidy-alphabetical-end
-    ]),
+    (
+        "tests",
+        &[
+            // tidy-alphabetical-start
+            "tests/assembly",
+            "tests/codegen",
+            "tests/codegen-units",
+            "tests/coverage",
+            "tests/coverage-run-rustdoc",
+            "tests/crashes",
+            "tests/debuginfo",
+            "tests/incremental",
+            "tests/mir-opt",
+            "tests/pretty",
+            "tests/run-make",
+            "tests/rustdoc",
+            "tests/rustdoc-gui",
+            "tests/rustdoc-js",
+            "tests/rustdoc-js-std",
+            "tests/rustdoc-json",
+            "tests/rustdoc-ui",
+            "tests/ui",
+            "tests/ui-fulldeps",
+            // tidy-alphabetical-end
+        ],
+    ),
 ];
 
 fn remap_paths(paths: &mut Vec<PathBuf>) {
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 0c27597083d..994975ed5a8 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -1,5 +1,7 @@
 use std::thread;
 
+use llvm::prebuilt_llvm_config;
+
 use super::*;
 use crate::Flags;
 use crate::core::build_steps::doc::DocumentationFormat;
@@ -114,11 +116,14 @@ fn test_intersection() {
     ];
     let subset = library_set.intersection_removing_matches(&mut command_paths, Kind::Build);
     assert_eq!(subset, set(&["library/core", "library/alloc"]),);
-    assert_eq!(command_paths, vec![
-        CLIStepPath::from(PathBuf::from("library/core")).will_be_executed(true),
-        CLIStepPath::from(PathBuf::from("library/alloc")).will_be_executed(true),
-        CLIStepPath::from(PathBuf::from("library/stdarch")).will_be_executed(false),
-    ]);
+    assert_eq!(
+        command_paths,
+        vec![
+            CLIStepPath::from(PathBuf::from("library/core")).will_be_executed(true),
+            CLIStepPath::from(PathBuf::from("library/alloc")).will_be_executed(true),
+            CLIStepPath::from(PathBuf::from("library/stdarch")).will_be_executed(false),
+        ]
+    );
 }
 
 #[test]
@@ -135,10 +140,13 @@ fn test_resolve_parent_and_subpaths() {
     let library_set = set(&["src/tools/miri", "src/tools/miri/cargo-miri"]);
     library_set.intersection_removing_matches(&mut command_paths, Kind::Build);
 
-    assert_eq!(command_paths, vec![
-        CLIStepPath::from(PathBuf::from("src/tools/miri")).will_be_executed(true),
-        CLIStepPath::from(PathBuf::from("src/tools/miri/cargo-miri")).will_be_executed(true),
-    ]);
+    assert_eq!(
+        command_paths,
+        vec![
+            CLIStepPath::from(PathBuf::from("src/tools/miri")).will_be_executed(true),
+            CLIStepPath::from(PathBuf::from("src/tools/miri/cargo-miri")).will_be_executed(true),
+        ]
+    );
 }
 
 #[test]
@@ -212,18 +220,22 @@ fn alias_and_path_for_library() {
         &["library".into(), "core".into()],
         configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]),
     );
-    assert_eq!(first(cache.all::<compile::Std>()), &[
-        std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-        std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1)
-    ]);
+    assert_eq!(
+        first(cache.all::<compile::Std>()),
+        &[
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1)
+        ]
+    );
 
     let mut cache = run_build(
         &["library".into(), "core".into()],
         configure("doc", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]),
     );
-    assert_eq!(first(cache.all::<doc::Std>()), &[
-        doc_std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)
-    ]);
+    assert_eq!(
+        first(cache.all::<doc::Std>()),
+        &[doc_std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)]
+    );
 }
 
 #[test]
@@ -271,10 +283,13 @@ mod defaults {
         let mut cache = run_build(&[], configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]));
 
         let a = TargetSelection::from_user(TEST_TRIPLE_1);
-        assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-        ]);
+        assert_eq!(
+            first(cache.all::<compile::Std>()),
+            &[
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+            ]
+        );
         assert!(!cache.all::<compile::Assemble>().is_empty());
         // Make sure rustdoc is only built once.
         assert_eq!(
@@ -283,9 +298,10 @@ mod defaults {
             // - this is the compiler it's _linked_ to, not built with.
             &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }],
         );
-        assert_eq!(first(cache.all::<compile::Rustc>()), &[
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)
-        ],);
+        assert_eq!(
+            first(cache.all::<compile::Rustc>()),
+            &[rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)],
+        );
     }
 
     #[test]
@@ -294,9 +310,10 @@ mod defaults {
         let mut cache = run_build(&[], config);
 
         let a = TargetSelection::from_user(TEST_TRIPLE_1);
-        assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)
-        ]);
+        assert_eq!(
+            first(cache.all::<compile::Std>()),
+            &[std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)]
+        );
         assert!(!cache.all::<compile::Assemble>().is_empty());
         assert_eq!(
             first(cache.all::<tool::Rustdoc>()),
@@ -323,25 +340,37 @@ mod defaults {
         // there's not really a need for us to build for target A in this case
         // (since we're producing stage 1 libraries/binaries).  But currently
         // bootstrap is just a bit buggy here; this should be fixed though.
-        assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
-        ]);
-        assert_eq!(first(cache.all::<compile::Assemble>()), &[
-            compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
-            compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
-            compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } },
-        ]);
-        assert_eq!(first(cache.all::<tool::Rustdoc>()), &[
-            tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
-            tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } },
-        ],);
-        assert_eq!(first(cache.all::<compile::Rustc>()), &[
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0),
-        ]);
+        assert_eq!(
+            first(cache.all::<compile::Std>()),
+            &[
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+            ]
+        );
+        assert_eq!(
+            first(cache.all::<compile::Assemble>()),
+            &[
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
+                compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } },
+            ]
+        );
+        assert_eq!(
+            first(cache.all::<tool::Rustdoc>()),
+            &[
+                tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
+                tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } },
+            ],
+        );
+        assert_eq!(
+            first(cache.all::<compile::Rustc>()),
+            &[
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0),
+            ]
+        );
     }
 
     #[test]
@@ -355,15 +384,17 @@ mod defaults {
         // error_index_generator uses stage 0 to share rustdoc artifacts with the
         // rustdoc tool.
         assert_eq!(first(cache.all::<doc::ErrorIndex>()), &[doc::ErrorIndex { target: a },]);
-        assert_eq!(first(cache.all::<tool::ErrorIndex>()), &[tool::ErrorIndex {
-            compiler: Compiler { host: a, stage: 0 }
-        }]);
+        assert_eq!(
+            first(cache.all::<tool::ErrorIndex>()),
+            &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }]
+        );
         // docs should be built with the beta compiler, not with the stage0 artifacts.
         // recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to,
         // not the one it was built by.
-        assert_eq!(first(cache.all::<tool::Rustdoc>()), &[tool::Rustdoc {
-            compiler: Compiler { host: a, stage: 0 }
-        },]);
+        assert_eq!(
+            first(cache.all::<tool::Rustdoc>()),
+            &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },]
+        );
     }
 }
 
@@ -385,18 +416,20 @@ mod dist {
 
         assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a },]);
         assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]);
-        assert_eq!(first(cache.all::<dist::Rustc>()), &[dist::Rustc {
-            compiler: Compiler { host: a, stage: 2 }
-        },]);
-        assert_eq!(first(cache.all::<dist::Std>()), &[dist::Std {
-            compiler: Compiler { host: a, stage: 1 },
-            target: a
-        },]);
+        assert_eq!(
+            first(cache.all::<dist::Rustc>()),
+            &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Std>()),
+            &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },]
+        );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
         // Make sure rustdoc is only built once.
-        assert_eq!(first(cache.all::<tool::Rustdoc>()), &[tool::Rustdoc {
-            compiler: Compiler { host: a, stage: 2 }
-        },]);
+        assert_eq!(
+            first(cache.all::<tool::Rustdoc>()),
+            &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
+        );
     }
 
     #[test]
@@ -407,19 +440,25 @@ mod dist {
         let a = TargetSelection::from_user(TEST_TRIPLE_1);
         let b = TargetSelection::from_user(TEST_TRIPLE_2);
 
-        assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs {
-            host: b
-        },]);
-        assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a }, dist::Mingw {
-            host: b
-        },]);
-        assert_eq!(first(cache.all::<dist::Rustc>()), &[dist::Rustc {
-            compiler: Compiler { host: a, stage: 2 }
-        },]);
-        assert_eq!(first(cache.all::<dist::Std>()), &[
-            dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
-            dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
-        ]);
+        assert_eq!(
+            first(cache.all::<dist::Docs>()),
+            &[dist::Docs { host: a }, dist::Docs { host: b },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Mingw>()),
+            &[dist::Mingw { host: a }, dist::Mingw { host: b },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Rustc>()),
+            &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Std>()),
+            &[
+                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
+                dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
+            ]
+        );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
     }
 
@@ -433,27 +472,38 @@ mod dist {
         let a = TargetSelection::from_user(TEST_TRIPLE_1);
         let b = TargetSelection::from_user(TEST_TRIPLE_2);
 
-        assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs {
-            host: b
-        },]);
-        assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a }, dist::Mingw {
-            host: b
-        },]);
-        assert_eq!(first(cache.all::<dist::Rustc>()), &[
-            dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
-            dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
-        ]);
-        assert_eq!(first(cache.all::<dist::Std>()), &[
-            dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
-            dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
-        ]);
-        assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
-        ],);
+        assert_eq!(
+            first(cache.all::<dist::Docs>()),
+            &[dist::Docs { host: a }, dist::Docs { host: b },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Mingw>()),
+            &[dist::Mingw { host: a }, dist::Mingw { host: b },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Rustc>()),
+            &[
+                dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
+                dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
+            ]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Std>()),
+            &[
+                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
+                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
+            ]
+        );
+        assert_eq!(
+            first(cache.all::<compile::Std>()),
+            &[
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
+            ],
+        );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
     }
 
@@ -467,49 +517,56 @@ mod dist {
         config.hosts = vec![b];
         let mut cache = run_build(&[], config);
 
-        assert_eq!(first(cache.all::<dist::Rustc>()), &[dist::Rustc {
-            compiler: Compiler { host: b, stage: 2 }
-        },]);
-        assert_eq!(first(cache.all::<compile::Rustc>()), &[
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
-        ]);
+        assert_eq!(
+            first(cache.all::<dist::Rustc>()),
+            &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },]
+        );
+        assert_eq!(
+            first(cache.all::<compile::Rustc>()),
+            &[
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+            ]
+        );
     }
 
     #[test]
     fn dist_with_targets_and_hosts() {
         let mut cache = run_build(
             &[],
-            configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[
-                TEST_TRIPLE_1,
-                TEST_TRIPLE_2,
-                TEST_TRIPLE_3,
-            ]),
+            configure(
+                &[TEST_TRIPLE_1, TEST_TRIPLE_2],
+                &[TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3],
+            ),
         );
 
         let a = TargetSelection::from_user(TEST_TRIPLE_1);
         let b = TargetSelection::from_user(TEST_TRIPLE_2);
         let c = TargetSelection::from_user(TEST_TRIPLE_3);
 
-        assert_eq!(first(cache.all::<dist::Docs>()), &[
-            dist::Docs { host: a },
-            dist::Docs { host: b },
-            dist::Docs { host: c },
-        ]);
-        assert_eq!(first(cache.all::<dist::Mingw>()), &[
-            dist::Mingw { host: a },
-            dist::Mingw { host: b },
-            dist::Mingw { host: c },
-        ]);
-        assert_eq!(first(cache.all::<dist::Rustc>()), &[
-            dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
-            dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
-        ]);
-        assert_eq!(first(cache.all::<dist::Std>()), &[
-            dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
-            dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
-            dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
-        ]);
+        assert_eq!(
+            first(cache.all::<dist::Docs>()),
+            &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Mingw>()),
+            &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Rustc>()),
+            &[
+                dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
+                dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
+            ]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Std>()),
+            &[
+                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
+                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
+                dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
+            ]
+        );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
     }
 
@@ -523,10 +580,10 @@ mod dist {
 
         assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: c },]);
         assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: c },]);
-        assert_eq!(first(cache.all::<dist::Std>()), &[dist::Std {
-            compiler: Compiler { host: a, stage: 2 },
-            target: c
-        },]);
+        assert_eq!(
+            first(cache.all::<dist::Std>()),
+            &[dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },]
+        );
     }
 
     #[test]
@@ -539,65 +596,84 @@ mod dist {
         let a = TargetSelection::from_user(TEST_TRIPLE_1);
         let b = TargetSelection::from_user(TEST_TRIPLE_2);
 
-        assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs {
-            host: b
-        },]);
-        assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a }, dist::Mingw {
-            host: b
-        },]);
-        assert_eq!(first(cache.all::<dist::Rustc>()), &[
-            dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
-            dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
-        ]);
-        assert_eq!(first(cache.all::<dist::Std>()), &[
-            dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
-            dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
-        ]);
+        assert_eq!(
+            first(cache.all::<dist::Docs>()),
+            &[dist::Docs { host: a }, dist::Docs { host: b },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Mingw>()),
+            &[dist::Mingw { host: a }, dist::Mingw { host: b },]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Rustc>()),
+            &[
+                dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
+                dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
+            ]
+        );
+        assert_eq!(
+            first(cache.all::<dist::Std>()),
+            &[
+                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
+                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
+            ]
+        );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
-        assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
-        ]);
-        assert_eq!(first(cache.all::<compile::Assemble>()), &[
-            compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
-            compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
-            compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
-            compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } },
-        ]);
+        assert_eq!(
+            first(cache.all::<compile::Std>()),
+            &[
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
+            ]
+        );
+        assert_eq!(
+            first(cache.all::<compile::Assemble>()),
+            &[
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
+                compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } },
+            ]
+        );
     }
 
     #[test]
     fn build_all() {
-        let build = Build::new(configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[
-            TEST_TRIPLE_1,
-            TEST_TRIPLE_2,
-            TEST_TRIPLE_3,
-        ]));
+        let build = Build::new(configure(
+            &[TEST_TRIPLE_1, TEST_TRIPLE_2],
+            &[TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3],
+        ));
         let mut builder = Builder::new(&build);
-        builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[
-            "compiler/rustc".into(),
-            "library".into(),
-        ]);
+        builder.run_step_descriptions(
+            &Builder::get_step_descriptions(Kind::Build),
+            &["compiler/rustc".into(), "library".into()],
+        );
 
-        assert_eq!(first(builder.cache.all::<compile::Std>()), &[
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2),
-        ]);
+        assert_eq!(
+            first(builder.cache.all::<compile::Std>()),
+            &[
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2),
+            ]
+        );
         assert_eq!(builder.cache.all::<compile::Assemble>().len(), 5);
-        assert_eq!(first(builder.cache.all::<compile::Rustc>()), &[
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
-        ]);
+        assert_eq!(
+            first(builder.cache.all::<compile::Rustc>()),
+            &[
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
+            ]
+        );
     }
 
     #[test]
@@ -626,20 +702,29 @@ mod dist {
 
         let a = TargetSelection::from_user(TEST_TRIPLE_1);
 
-        assert_eq!(first(builder.cache.all::<compile::Std>()), &[
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-            std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2),
-        ]);
-        assert_eq!(first(builder.cache.all::<compile::Assemble>()), &[
-            compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
-            compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
-            compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
-        ]);
-        assert_eq!(first(builder.cache.all::<compile::Rustc>()), &[
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-        ]);
+        assert_eq!(
+            first(builder.cache.all::<compile::Std>()),
+            &[
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+                std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2),
+            ]
+        );
+        assert_eq!(
+            first(builder.cache.all::<compile::Assemble>()),
+            &[
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
+            ]
+        );
+        assert_eq!(
+            first(builder.cache.all::<compile::Rustc>()),
+            &[
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+            ]
+        );
     }
 
     #[test]
@@ -669,18 +754,22 @@ mod dist {
 
         let host = TargetSelection::from_user(TEST_TRIPLE_1);
 
-        builder.run_step_descriptions(&[StepDescription::from::<test::Crate>(Kind::Test)], &[
-            "library/std".into(),
-        ]);
+        builder.run_step_descriptions(
+            &[StepDescription::from::<test::Crate>(Kind::Test)],
+            &["library/std".into()],
+        );
 
         // Ensure we don't build any compiler artifacts.
         assert!(!builder.cache.contains::<compile::Rustc>());
-        assert_eq!(first(builder.cache.all::<test::Crate>()), &[test::Crate {
-            compiler: Compiler { host, stage: 0 },
-            target: host,
-            mode: crate::Mode::Std,
-            crates: vec!["std".to_owned()],
-        },]);
+        assert_eq!(
+            first(builder.cache.all::<test::Crate>()),
+            &[test::Crate {
+                compiler: Compiler { host, stage: 0 },
+                target: host,
+                mode: crate::Mode::Std,
+                crates: vec!["std".to_owned()],
+            },]
+        );
     }
 
     #[test]
@@ -699,14 +788,16 @@ mod dist {
             first(builder.cache.all::<doc::ErrorIndex>()),
             &[doc::ErrorIndex { target: a },]
         );
-        assert_eq!(first(builder.cache.all::<tool::ErrorIndex>()), &[tool::ErrorIndex {
-            compiler: Compiler { host: a, stage: 1 }
-        }]);
+        assert_eq!(
+            first(builder.cache.all::<tool::ErrorIndex>()),
+            &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
+        );
         // This is actually stage 1, but Rustdoc::run swaps out the compiler with
         // stage minus 1 if --stage is not 0. Very confusing!
-        assert_eq!(first(builder.cache.all::<tool::Rustdoc>()), &[tool::Rustdoc {
-            compiler: Compiler { host: a, stage: 2 }
-        },]);
+        assert_eq!(
+            first(builder.cache.all::<tool::Rustdoc>()),
+            &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
+        );
     }
 
     #[test]
@@ -743,9 +834,10 @@ mod dist {
             first(builder.cache.all::<doc::ErrorIndex>()),
             &[doc::ErrorIndex { target: a },]
         );
-        assert_eq!(first(builder.cache.all::<tool::ErrorIndex>()), &[tool::ErrorIndex {
-            compiler: Compiler { host: a, stage: 1 }
-        }]);
+        assert_eq!(
+            first(builder.cache.all::<tool::ErrorIndex>()),
+            &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
+        );
         // Unfortunately rustdoc is built twice. Once from stage1 for compiletest
         // (and other things), and once from stage0 for std crates. Ideally it
         // would only be built once. If someone wants to fix this, it might be
@@ -757,11 +849,14 @@ mod dist {
         // The stage 0 copy is the one downloaded for bootstrapping. It is
         // (currently) needed to run "cargo test" on the linkchecker, and
         // should be relatively "free".
-        assert_eq!(first(builder.cache.all::<tool::Rustdoc>()), &[
-            tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },
-            tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
-            tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },
-        ]);
+        assert_eq!(
+            first(builder.cache.all::<tool::Rustdoc>()),
+            &[
+                tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },
+                tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
+                tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },
+            ]
+        );
     }
 }
 
@@ -861,3 +956,112 @@ fn test_test_coverage() {
         assert_eq!(modes, expected);
     }
 }
+
+#[test]
+fn test_prebuilt_llvm_config_path_resolution() {
+    fn configure(config: &str) -> Config {
+        Config::parse_inner(
+            Flags::parse(&[
+                "build".to_string(),
+                "--dry-run".to_string(),
+                "--config=/does/not/exist".to_string(),
+            ]),
+            |&_| toml::from_str(&config),
+        )
+    }
+
+    // Removes Windows disk prefix if present
+    fn drop_win_disk_prefix_if_present(path: PathBuf) -> PathBuf {
+        let path_str = path.to_str().unwrap();
+        if let Some((_, without_prefix)) = path_str.split_once(":/") {
+            return PathBuf::from(format!("/{}", without_prefix));
+        }
+
+        path
+    }
+
+    let config = configure(
+        r#"
+            [llvm]
+            download-ci-llvm = false
+
+            [build]
+            build = "x86_64-unknown-linux-gnu"
+            host = ["arm-unknown-linux-gnueabihf"]
+            target = ["arm-unknown-linux-gnueabihf"]
+
+            [target.x86_64-unknown-linux-gnu]
+            llvm-config = "/some/path/to/llvm-config"
+
+            [target.arm-unknown-linux-gnueabihf]
+            cc = "arm-linux-gnueabihf-gcc"
+            cxx = "arm-linux-gnueabihf-g++"
+        "#,
+    );
+
+    let build = Build::new(config);
+    let builder = Builder::new(&build);
+
+    let expected = PathBuf::from("/some/path/to/llvm-config");
+
+    let actual = prebuilt_llvm_config(
+        &builder,
+        TargetSelection::from_user("arm-unknown-linux-gnueabihf"),
+        false,
+    )
+    .llvm_result()
+    .llvm_config
+    .clone();
+    let actual = drop_win_disk_prefix_if_present(actual);
+    assert_eq!(expected, actual);
+
+    let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+        .llvm_result()
+        .llvm_config
+        .clone();
+    let actual = drop_win_disk_prefix_if_present(actual);
+    assert_eq!(expected, actual);
+    assert_eq!(expected, actual);
+
+    let config = configure(
+        r#"
+            [llvm]
+            download-ci-llvm = false
+        "#,
+    );
+
+    let build = Build::new(config.clone());
+    let builder = Builder::new(&build);
+
+    let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+        .llvm_result()
+        .llvm_config
+        .clone();
+    let expected = builder
+        .out
+        .join(builder.config.build)
+        .join("llvm/bin")
+        .join(exe("llvm-config", builder.config.build));
+    assert_eq!(expected, actual);
+
+    let config = configure(
+        r#"
+            [llvm]
+            download-ci-llvm = true
+        "#,
+    );
+
+    let build = Build::new(config.clone());
+    let builder = Builder::new(&build);
+
+    let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+        .llvm_result()
+        .llvm_config
+        .clone();
+    let expected = builder
+        .out
+        .join(builder.config.build)
+        .join("ci-llvm/bin")
+        .join(exe("llvm-config", builder.config.build));
+    assert_eq!(expected, actual);
+}
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 4694dd2ca4e..d3ed7ecddd3 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1928,11 +1928,14 @@ impl Config {
             config.rustc_default_linker = default_linker;
             config.musl_root = musl_root.map(PathBuf::from);
             config.save_toolstates = save_toolstates.map(PathBuf::from);
-            set(&mut config.deny_warnings, match flags.warnings {
-                Warnings::Deny => Some(true),
-                Warnings::Warn => Some(false),
-                Warnings::Default => deny_warnings,
-            });
+            set(
+                &mut config.deny_warnings,
+                match flags.warnings {
+                    Warnings::Deny => Some(true),
+                    Warnings::Warn => Some(false),
+                    Warnings::Default => deny_warnings,
+                },
+            );
             set(&mut config.backtrace_on_ice, backtrace_on_ice);
             set(&mut config.rust_verify_llvm_ir, verify_llvm_ir);
             config.rust_thin_lto_import_instr_limit = thin_lto_import_instr_limit;
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 27fb00cb06e..c08a041ebcd 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -9,6 +9,7 @@ use clap::{CommandFactory, Parser, ValueEnum};
 #[cfg(feature = "tracing")]
 use tracing::instrument;
 
+use crate::core::build_steps::perf::PerfArgs;
 use crate::core::build_steps::setup::Profile;
 use crate::core::builder::{Builder, Kind};
 use crate::core::config::{Config, TargetSelectionList, target_selection_list};
@@ -481,11 +482,8 @@ Arguments:
         #[arg(long)]
         versioned_dirs: bool,
     },
-    /// Perform profiling and benchmarking of the compiler using the
-    /// `rustc-perf-wrapper` tool.
-    ///
-    /// You need to pass arguments after `--`, e.g.`x perf -- cachegrind`.
-    Perf {},
+    /// Perform profiling and benchmarking of the compiler using `rustc-perf`.
+    Perf(PerfArgs),
 }
 
 impl Subcommand {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 2dd83d5938e..e564a4b9751 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -154,6 +154,7 @@ pub struct Build {
     targets: Vec<TargetSelection>,
 
     initial_rustc: PathBuf,
+    initial_rustdoc: PathBuf,
     initial_cargo: PathBuf,
     initial_lld: PathBuf,
     initial_relative_libdir: PathBuf,
@@ -248,6 +249,7 @@ impl Mode {
     }
 }
 
+#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub enum CLang {
     C,
     Cxx,
@@ -354,6 +356,7 @@ impl Build {
             initial_lld,
             initial_relative_libdir,
             initial_rustc: config.initial_rustc.clone(),
+            initial_rustdoc: config.initial_rustc.with_file_name(exe("rustdoc", config.build)),
             initial_cargo: config.initial_cargo.clone(),
             initial_sysroot: config.initial_sysroot.clone(),
             local_rebuild: config.local_rebuild,
@@ -571,8 +574,8 @@ impl Build {
                 Subcommand::Suggest { run } => {
                     return core::build_steps::suggest::suggest(&builder::Builder::new(self), *run);
                 }
-                Subcommand::Perf { .. } => {
-                    return core::build_steps::perf::perf(&builder::Builder::new(self));
+                Subcommand::Perf(args) => {
+                    return core::build_steps::perf::perf(&builder::Builder::new(self), args);
                 }
                 _cmd => {
                     debug!(cmd = ?_cmd, "not a hardcoded subcommand; returning to normal handling");
@@ -1176,9 +1179,9 @@ Executed at: {executed_at}"#,
         self.cc.borrow()[&target].path().into()
     }
 
-    /// Returns a list of flags to pass to the C compiler for the target
-    /// specified.
-    fn cflags(&self, target: TargetSelection, which: GitRepo, c: CLang) -> Vec<String> {
+    /// Returns C flags that `cc-rs` thinks should be enabled for the
+    /// specified target by default.
+    fn cc_handled_clags(&self, target: TargetSelection, c: CLang) -> Vec<String> {
         if self.config.dry_run() {
             return Vec::new();
         }
@@ -1187,14 +1190,23 @@ Executed at: {executed_at}"#,
             CLang::Cxx => self.cxx.borrow()[&target].clone(),
         };
 
-        // Filter out -O and /O (the optimization flags) that we picked up from
-        // cc-rs because the build scripts will determine that for themselves.
-        let mut base = base
-            .args()
+        // Filter out -O and /O (the optimization flags) that we picked up
+        // from cc-rs, that's up to the caller to figure out.
+        base.args()
             .iter()
             .map(|s| s.to_string_lossy().into_owned())
             .filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
-            .collect::<Vec<String>>();
+            .collect::<Vec<String>>()
+    }
+
+    /// Returns extra C flags that `cc-rs` doesn't handle.
+    fn cc_unhandled_cflags(
+        &self,
+        target: TargetSelection,
+        which: GitRepo,
+        c: CLang,
+    ) -> Vec<String> {
+        let mut base = Vec::new();
 
         // If we're compiling C++ on macOS then we add a flag indicating that
         // we want libc++ (more filled out than libstdc++), ensuring that
diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs
index 4aec554b432..f6afd50afce 100644
--- a/src/bootstrap/src/utils/cc_detect.rs
+++ b/src/bootstrap/src/utils/cc_detect.rs
@@ -142,7 +142,8 @@ pub fn find_target(build: &Build, target: TargetSelection) {
     };
 
     build.cc.borrow_mut().insert(target, compiler.clone());
-    let cflags = build.cflags(target, GitRepo::Rustc, CLang::C);
+    let mut cflags = build.cc_handled_clags(target, CLang::C);
+    cflags.extend(build.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C));
 
     // If we use llvm-libunwind, we will need a C++ compiler as well for all targets
     // We'll need one anyways if the target triple is also a host triple
@@ -168,7 +169,8 @@ pub fn find_target(build: &Build, target: TargetSelection) {
     build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target)));
     build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple));
     if let Ok(cxx) = build.cxx(target) {
-        let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
+        let mut cxxflags = build.cc_handled_clags(target, CLang::Cxx);
+        cxxflags.extend(build.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx));
         build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple));
         build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
     }
diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs
index 60216395c2f..1902dcd3962 100644
--- a/src/bootstrap/src/utils/exec.rs
+++ b/src/bootstrap/src/utils/exec.rs
@@ -1,3 +1,8 @@
+//! Command Execution Module
+//!
+//! This module provides a structured way to execute and manage commands efficiently,
+//! ensuring controlled failure handling and output management.
+
 use std::ffi::OsStr;
 use std::fmt::{Debug, Formatter};
 use std::path::Path;
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
index 71eb72686b0..e3f23149284 100644
--- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
@@ -3,8 +3,8 @@ FROM ubuntu:22.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-COPY scripts/crosstool-ng-git.sh /scripts/
-RUN sh /scripts/crosstool-ng-git.sh
+COPY scripts/crosstool-ng.sh /scripts/
+RUN sh /scripts/crosstool-ng.sh
 
 COPY scripts/rustbuild-setup.sh /scripts/
 RUN sh /scripts/rustbuild-setup.sh
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile
index 5081f25e567..2c33b5526ee 100644
--- a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile
@@ -3,8 +3,8 @@ FROM ubuntu:22.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-COPY scripts/crosstool-ng-git.sh /scripts/
-RUN sh /scripts/crosstool-ng-git.sh
+COPY scripts/crosstool-ng.sh /scripts/
+RUN sh /scripts/crosstool-ng.sh
 
 COPY scripts/rustbuild-setup.sh /scripts/
 RUN sh /scripts/rustbuild-setup.sh
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
index 9d3be51d037..cb20f43cff7 100644
--- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
@@ -3,8 +3,8 @@ FROM ubuntu:22.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-COPY scripts/crosstool-ng-git.sh /scripts/
-RUN sh /scripts/crosstool-ng-git.sh
+COPY scripts/crosstool-ng.sh /scripts/
+RUN sh /scripts/crosstool-ng.sh
 
 COPY scripts/rustbuild-setup.sh /scripts/
 RUN sh /scripts/rustbuild-setup.sh
diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh
deleted file mode 100644
index e86810ae613..00000000000
--- a/src/ci/docker/scripts/crosstool-ng-git.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-set -ex
-
-URL=https://github.com/crosstool-ng/crosstool-ng
-REV=ed12fa68402f58e171a6f79500f73f4781fdc9e5
-
-mkdir crosstool-ng
-cd crosstool-ng
-git init
-git fetch --depth=1 ${URL} ${REV}
-git reset --hard FETCH_HEAD
-./bootstrap
-./configure --prefix=/usr/local
-make -j$(nproc)
-make install
-cd ..
-rm -rf crosstool-ng
diff --git a/src/ci/docker/scripts/crosstool-ng.sh b/src/ci/docker/scripts/crosstool-ng.sh
index c3ee19b8d2c..eee912b0d75 100644
--- a/src/ci/docker/scripts/crosstool-ng.sh
+++ b/src/ci/docker/scripts/crosstool-ng.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 set -ex
 
-CT_NG=1.26.0
+CT_NG=1.27.0
 
 url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-$CT_NG.tar.gz"
 curl -Lf $url | tar xzf -
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 92458bfaa34..8ae6d543bc5 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -59,6 +59,7 @@ envs:
     SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact
     RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc
     RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
+    # Ensure that host tooling is tested on our minimum supported macOS version.
     MACOSX_DEPLOYMENT_TARGET: 10.12
     MACOSX_STD_DEPLOYMENT_TARGET: 10.12
     SELECT_XCODE: /Applications/Xcode_15.2.app
@@ -167,10 +168,10 @@ auto:
     <<: *job-linux-4c
 
   - name: dist-loongarch64-linux
-    <<: *job-linux-4c
+    <<: *job-linux-4c-largedisk
 
   - name: dist-loongarch64-musl
-    <<: *job-linux-4c
+    <<: *job-linux-4c-largedisk
 
   - name: dist-ohos
     <<: *job-linux-4c
@@ -370,7 +371,9 @@ auto:
       SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin
       RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1
       RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
+      # Ensure that host tooling is built to support our minimum support macOS version.
       MACOSX_DEPLOYMENT_TARGET: 10.12
+      MACOSX_STD_DEPLOYMENT_TARGET: 10.12
       SELECT_XCODE: /Applications/Xcode_15.2.app
       NO_LLVM_ASSERTIONS: 1
       NO_DEBUG_ASSERTIONS: 1
@@ -386,7 +389,10 @@ auto:
       # https://github.com/rust-lang/rust/issues/129069
       RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc --set target.aarch64-apple-ios-macabi.sanitizers=false --set target.x86_64-apple-ios-macabi.sanitizers=false
       RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
+      # Ensure that host tooling is built to support our minimum support macOS version.
+      # FIXME(madsmtm): This might be redundant, as we're not building host tooling here (?)
       MACOSX_DEPLOYMENT_TARGET: 10.12
+      MACOSX_STD_DEPLOYMENT_TARGET: 10.12
       SELECT_XCODE: /Applications/Xcode_15.2.app
       NO_LLVM_ASSERTIONS: 1
       NO_DEBUG_ASSERTIONS: 1
@@ -404,7 +410,6 @@ auto:
       <<: *env-x86_64-apple-tests
     <<: *job-macos-xl
 
-  # This target only needs to support 11.0 and up as nothing else supports the hardware
   - name: dist-aarch64-apple
     env:
       SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin
@@ -419,6 +424,8 @@ auto:
       RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
       SELECT_XCODE: /Applications/Xcode_15.4.app
       USE_XCODE_CLANG: 1
+      # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else
+      # supports the hardware.
       MACOSX_DEPLOYMENT_TARGET: 11.0
       MACOSX_STD_DEPLOYMENT_TARGET: 11.0
       NO_LLVM_ASSERTIONS: 1
@@ -428,7 +435,6 @@ auto:
       CODEGEN_BACKENDS: llvm,cranelift
     <<: *job-macos-m1
 
-  # This target only needs to support 11.0 and up as nothing else supports the hardware
   - name: aarch64-apple
     env:
       SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin
@@ -439,6 +445,8 @@ auto:
       RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
       SELECT_XCODE: /Applications/Xcode_15.4.app
       USE_XCODE_CLANG: 1
+      # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else
+      # supports the hardware, so only need to test it there.
       MACOSX_DEPLOYMENT_TARGET: 11.0
       MACOSX_STD_DEPLOYMENT_TARGET: 11.0
       NO_LLVM_ASSERTIONS: 1
diff --git a/src/ci/scripts/free-disk-space.sh b/src/ci/scripts/free-disk-space.sh
index 8850e168145..32d55806b56 100755
--- a/src/ci/scripts/free-disk-space.sh
+++ b/src/ci/scripts/free-disk-space.sh
@@ -110,6 +110,9 @@ execAndMeasureSpaceChange() {
 # Remove large packages
 # REF: https://github.com/apache/flink/blob/master/tools/azure-pipelines/free_disk_space.sh
 cleanPackages() {
+    # Stop services to avoid issues when removing their packages.
+    sudo systemctl stop mysql
+
     local packages=(
         '^aspnetcore-.*'
         '^dotnet-.*'
diff --git a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
index 87d205d9ebe..eda8c3a179c 100644
--- a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
+++ b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
@@ -7,9 +7,7 @@ However, using the suite manually can be a bit cumbersome. To make this easier f
 the compiler build system (`bootstrap`) also provides built-in integration with the benchmarking suite,
 which will download and build the suite for you, build a local compiler toolchain and let you profile it using a simplified command-line interface.
 
-You can use the `./x perf -- <command> [options]` command to use this integration.
-
-> Note that you need to specify arguments after `--` in the `x perf` command! You will not be able to pass arguments without the double dashes.
+You can use the `./x perf <command> [options]` command to use this integration.
 
 You can use normal bootstrap flags for this command, such as `--stage 1` or `--stage 2`, for example to modify the stage of the created sysroot. It might also be useful to configure `config.toml` to better support profiling, e.g. set `rust.debuginfo-level = 1` to add source line information to the built compiler.
 
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 670e4bd1be6..f78d3d4aee8 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -29,6 +29,7 @@
     - [\*-apple-watchos](platform-support/apple-watchos.md)
     - [\*-apple-visionos](platform-support/apple-visionos.md)
     - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
+    - [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md)
     - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md)
     - [arm-none-eabi](platform-support/arm-none-eabi.md)
       - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 3b6abdd8483..bb89d97a798 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -101,7 +101,7 @@ target | notes
 [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29)
 [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3)
 [`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2, glibc 2.17)
-[`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit amd64 FreeBSD
+[`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit x86 FreeBSD
 [`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos
 `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3
 [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64
@@ -272,6 +272,7 @@ target | std | host | notes
 `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
 `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
 [`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian)
+[`amdgcn-amd-amdhsa`](platform-support/amdgcn-amd-amdhsa.md) | * |  | `-Ctarget-cpu=gfx...` to specify [the AMD GPU] to compile for
 [`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | Arm Apple WatchOS 64-bit with 32-bit pointers
 [`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md)  | ✓ | ✓ | ARM64e Apple Darwin
 [`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS
@@ -312,7 +313,7 @@ target | std | host | notes
 [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ |  | 32-bit x86 (original Pentium) [^x86_32-floats-x87]
 [`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI]
 `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI]
-[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (PentiumPro) [^x86_32-floats-x87]
+[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (Pentium 4) [^x86_32-floats-x87]
 [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI]
 [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD (Pentium 4) [^x86_32-floats-return-ABI]
 [`i686-unknown-redox`](platform-support/redox.md) | ✓ |  | i686 Redox OS (PentiumPro) [^x86_32-floats-x87]
@@ -432,3 +433,4 @@ target | std | host | notes
 [`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * |  | Xtensa ESP32-S3
 
 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets
+[the AMD GPU]: https://llvm.org/docs/AMDGPUUsage.html#processors
diff --git a/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md
new file mode 100644
index 00000000000..0b2f798e66d
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md
@@ -0,0 +1,111 @@
+# `amdgcn-amd-amdhsa`
+
+**Tier: 3**
+
+AMD GPU target for compute/HSA (Heterogeneous System Architecture).
+
+## Target maintainers
+
+- [@Flakebi](https://github.com/Flakebi)
+
+## Requirements
+
+AMD GPUs can be targeted via cross-compilation.
+Supported GPUs depend on the LLVM version that is used by Rust.
+In general, most GPUs starting from gfx7 (Sea Islands/CI) are supported as compilation targets, though older GPUs are not supported by the latest host runtime.
+Details about supported GPUs can be found in [LLVM’s documentation] and [ROCm documentation].
+
+Binaries can be loaded by [HIP] or by the HSA runtime implemented in [ROCR-Runtime].
+The format of binaries is a linked ELF.
+
+Binaries must be built with no-std.
+They can use `core` and `alloc` (`alloc` only if an allocator is supplied).
+At least one function needs to use the `"gpu-kernel"` calling convention and should be marked with `no_mangle` for simplicity.
+Functions using the `"gpu-kernel"` calling convention are kernel entrypoints and can be used from the host runtime.
+
+## Building the target
+
+The target is included in rustc.
+
+## Building Rust programs
+
+The amdgpu target supports many hardware generations, which need different binaries.
+The generations are exposed as different target-cpus in the backend.
+As there are many, Rust does not ship pre-compiled libraries for this target.
+Therefore, you have to build your own copy of `core` by using `cargo -Zbuild-std=core` or similar.
+
+To build a binary, create a no-std library:
+```rust,ignore (platform-specific)
+// src/lib.rs
+#![feature(abi_gpu_kernel)]
+#![no_std]
+
+#[panic_handler]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
+
+#[no_mangle]
+pub extern "gpu-kernel" fn kernel(/* Arguments */) {
+    // Code
+}
+```
+
+Build the library as `cdylib`:
+```toml
+# Cargo.toml
+[lib]
+crate-type = ["cdylib"]
+
+[profile.dev]
+lto = true # LTO must be explicitly enabled for now
+[profile.release]
+lto = true
+```
+
+The target-cpu must be from the list [supported by LLVM] (or printed with `rustc --target amdgcn-amd-amdhsa --print target-cpus`).
+The GPU version on the current system can be found e.g. with [`rocminfo`].
+
+Example `.cargo/config.toml` file to set the target and GPU generation:
+```toml
+# .cargo/config.toml
+[build]
+target = "amdgcn-amd-amdhsa"
+rustflags = ["-Ctarget-cpu=gfx1100"]
+
+[unstable]
+build-std = ["core"] # Optional: "alloc"
+```
+
+## Running Rust programs
+
+To run a binary on an AMD GPU, a host runtime is needed.
+On Linux and Windows, [HIP] can be used to load and run binaries.
+Example code on how to load a compiled binary and run it is available in [ROCm examples].
+
+On Linux, binaries can also run through the HSA runtime as implemented in [ROCR-Runtime].
+
+<!-- Mention an allocator once a suitable one exists for amdgpu -->
+
+<!--
+## Testing
+
+Does the target support running binaries, or do binaries have varying
+expectations that prevent having a standard way to run them? If users can run
+binaries, can they do so in some common emulator, or do they need native
+hardware? Does the target support running the Rust testsuite?
+
+-->
+
+## Additional information
+
+More information can be found on the [LLVM page for amdgpu].
+
+[LLVM’s documentation]: https://llvm.org/docs/AMDGPUUsage.html#processors
+[ROCm documentation]: https://rocmdocs.amd.com
+[HIP]: https://rocm.docs.amd.com/projects/HIP/
+[ROCR-Runtime]: https://github.com/ROCm/ROCR-Runtime
+[supported by LLVM]: https://llvm.org/docs/AMDGPUUsage.html#processors
+[LLVM page for amdgpu]: https://llvm.org/docs/AMDGPUUsage.html
+[`rocminfo`]: https://github.com/ROCm/rocminfo
+[ROCm examples]: https://github.com/ROCm/rocm-examples/tree/ca8ef5b6f1390176616cd1c18fbc98785cbc73f6/HIP-Basic/module_api
diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish
index 49fe10a4ea2..933557ab0d7 100644
--- a/src/etc/completions/x.fish
+++ b/src/etc/completions/x.fish
@@ -73,7 +73,7 @@ complete -c x -n "__fish_x_needs_command" -a "run" -d 'Run tools contained in th
 complete -c x -n "__fish_x_needs_command" -a "setup" -d 'Set up the environment for development'
 complete -c x -n "__fish_x_needs_command" -a "suggest" -d 'Suggest a subset of tests to run, based on modified files'
 complete -c x -n "__fish_x_needs_command" -a "vendor" -d 'Vendor dependencies'
-complete -c x -n "__fish_x_needs_command" -a "perf" -d 'Perform profiling and benchmarking of the compiler using the `rustc-perf-wrapper` tool'
+complete -c x -n "__fish_x_needs_command" -a "perf" -d 'Perform profiling and benchmarking of the compiler using `rustc-perf`'
 complete -c x -n "__fish_x_using_subcommand build" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
 complete -c x -n "__fish_x_using_subcommand build" -l build -d 'build target of the stage0 compiler' -r -f
@@ -638,36 +638,218 @@ complete -c x -n "__fish_x_using_subcommand vendor" -l llvm-profile-generate -d
 complete -c x -n "__fish_x_using_subcommand vendor" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
 complete -c x -n "__fish_x_using_subcommand vendor" -s h -l help -d 'Print help (see more with \'--help\')'
-complete -c x -n "__fish_x_using_subcommand perf" -l config -d 'TOML configuration file for build' -r -F
-complete -c x -n "__fish_x_using_subcommand perf" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
-complete -c x -n "__fish_x_using_subcommand perf" -l build -d 'build target of the stage0 compiler' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l host -d 'host targets to build' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l target -d 'target targets to build' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l exclude -d 'build paths to exclude' -r -F
-complete -c x -n "__fish_x_using_subcommand perf" -l skip -d 'build paths to skip' -r -F
-complete -c x -n "__fish_x_using_subcommand perf" -l rustc-error-format -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
-complete -c x -n "__fish_x_using_subcommand perf" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
-complete -c x -n "__fish_x_using_subcommand perf" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
-complete -c x -n "__fish_x_using_subcommand perf" -l error-format -d 'rustc error format' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
-complete -c x -n "__fish_x_using_subcommand perf" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
-complete -c x -n "__fish_x_using_subcommand perf" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
-complete -c x -n "__fish_x_using_subcommand perf" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
-complete -c x -n "__fish_x_using_subcommand perf" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
-complete -c x -n "__fish_x_using_subcommand perf" -l set -d 'override options in config.toml' -r -f
-complete -c x -n "__fish_x_using_subcommand perf" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
-complete -c x -n "__fish_x_using_subcommand perf" -s i -l incremental -d 'use incremental compilation'
-complete -c x -n "__fish_x_using_subcommand perf" -l include-default-paths -d 'include default paths in addition to the provided ones'
-complete -c x -n "__fish_x_using_subcommand perf" -l dry-run -d 'dry run; don\'t build anything'
-complete -c x -n "__fish_x_using_subcommand perf" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
-complete -c x -n "__fish_x_using_subcommand perf" -l json-output -d 'use message-format=json'
-complete -c x -n "__fish_x_using_subcommand perf" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
-complete -c x -n "__fish_x_using_subcommand perf" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
-complete -c x -n "__fish_x_using_subcommand perf" -l enable-bolt-settings -d 'Enable BOLT link flags'
-complete -c x -n "__fish_x_using_subcommand perf" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
-complete -c x -n "__fish_x_using_subcommand perf" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l config -d 'TOML configuration file for build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l host -d 'host targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l target -d 'target targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l exclude -d 'build paths to exclude' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l skip -d 'build paths to skip' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l rustc-error-format -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l error-format -d 'rustc error format' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l set -d 'override options in config.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s i -l incremental -d 'use incremental compilation'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l json-output -d 'use message-format=json'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "eprintln" -d 'Run `profile_local eprintln`. This executes the compiler on the given benchmarks and stores its stderr output'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "samply" -d 'Run `profile_local samply` This executes the compiler on the given benchmarks and profiles it with `samply`. You need to install `samply`, e.g. using `cargo install samply`'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "cachegrind" -d 'Run `profile_local cachegrind`. This executes the compiler on the given benchmarks under `Cachegrind`'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "benchmark" -d 'Run compile benchmarks with a locally built compiler'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "compare" -d 'Compare the results of two previously executed benchmark runs'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l config -d 'TOML configuration file for build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l host -d 'host targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l target -d 'target targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l skip -d 'build paths to skip' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l rustc-error-format -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l error-format -d 'rustc error format' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l set -d 'override options in config.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s i -l incremental -d 'use incremental compilation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l json-output -d 'use message-format=json'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l config -d 'TOML configuration file for build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l host -d 'host targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l target -d 'target targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l skip -d 'build paths to skip' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l rustc-error-format -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l error-format -d 'rustc error format' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l set -d 'override options in config.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s i -l incremental -d 'use incremental compilation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l json-output -d 'use message-format=json'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l config -d 'TOML configuration file for build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l host -d 'host targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l target -d 'target targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l skip -d 'build paths to skip' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l rustc-error-format -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l error-format -d 'rustc error format' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l set -d 'override options in config.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s i -l incremental -d 'use incremental compilation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l json-output -d 'use message-format=json'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l config -d 'TOML configuration file for build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l host -d 'host targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l target -d 'target targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip -d 'build paths to skip' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l rustc-error-format -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l error-format -d 'rustc error format' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l set -d 'override options in config.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s i -l incremental -d 'use incremental compilation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l json-output -d 'use message-format=json'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l config -d 'TOML configuration file for build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l host -d 'host targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l target -d 'target targets to build' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l exclude -d 'build paths to exclude' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l skip -d 'build paths to skip' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l rustc-error-format -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l error-format -d 'rustc error format' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l set -d 'override options in config.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s i -l incremental -d 'use incremental compilation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l json-output -d 'use message-format=json'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s h -l help -d 'Print help (see more with \'--help\')'
diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1
index fa833b6876a..b848b95d88f 100644
--- a/src/etc/completions/x.ps1
+++ b/src/etc/completions/x.ps1
@@ -74,7 +74,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development')
             [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files')
             [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies')
-            [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using the `rustc-perf-wrapper` tool')
+            [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using `rustc-perf`')
             break
         }
         'x;build' {
@@ -791,6 +791,223 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('eprintln', 'eprintln', [CompletionResultType]::ParameterValue, 'Run `profile_local eprintln`. This executes the compiler on the given benchmarks and stores its stderr output')
+            [CompletionResult]::new('samply', 'samply', [CompletionResultType]::ParameterValue, 'Run `profile_local samply` This executes the compiler on the given benchmarks and profiles it with `samply`. You need to install `samply`, e.g. using `cargo install samply`')
+            [CompletionResult]::new('cachegrind', 'cachegrind', [CompletionResultType]::ParameterValue, 'Run `profile_local cachegrind`. This executes the compiler on the given benchmarks under `Cachegrind`')
+            [CompletionResult]::new('benchmark', 'benchmark', [CompletionResultType]::ParameterValue, 'Run compile benchmarks with a locally built compiler')
+            [CompletionResult]::new('compare', 'compare', [CompletionResultType]::ParameterValue, 'Compare the results of two previously executed benchmark runs')
+            break
+        }
+        'x;perf;eprintln' {
+            [CompletionResult]::new('--include', '--include', [CompletionResultType]::ParameterName, 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run')
+            [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked')
+            [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked')
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
+        'x;perf;samply' {
+            [CompletionResult]::new('--include', '--include', [CompletionResultType]::ParameterName, 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run')
+            [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked')
+            [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked')
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
+        'x;perf;cachegrind' {
+            [CompletionResult]::new('--include', '--include', [CompletionResultType]::ParameterName, 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run')
+            [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked')
+            [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked')
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
+        'x;perf;benchmark' {
+            [CompletionResult]::new('--include', '--include', [CompletionResultType]::ParameterName, 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run')
+            [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked')
+            [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked')
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
+        'x;perf;compare' {
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
         }
     })
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 07144ad22d1..ff4f7425da6 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -73,7 +73,7 @@ complete -c x.py -n "__fish_x.py_needs_command" -a "run" -d 'Run tools contained
 complete -c x.py -n "__fish_x.py_needs_command" -a "setup" -d 'Set up the environment for development'
 complete -c x.py -n "__fish_x.py_needs_command" -a "suggest" -d 'Suggest a subset of tests to run, based on modified files'
 complete -c x.py -n "__fish_x.py_needs_command" -a "vendor" -d 'Vendor dependencies'
-complete -c x.py -n "__fish_x.py_needs_command" -a "perf" -d 'Perform profiling and benchmarking of the compiler using the `rustc-perf-wrapper` tool'
+complete -c x.py -n "__fish_x.py_needs_command" -a "perf" -d 'Perform profiling and benchmarking of the compiler using `rustc-perf`'
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l build -d 'build target of the stage0 compiler' -r -f
@@ -638,36 +638,218 @@ complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l llvm-profile-genera
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -s h -l help -d 'Print help (see more with \'--help\')'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l config -d 'TOML configuration file for build' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l build -d 'build target of the stage0 compiler' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l host -d 'host targets to build' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l target -d 'target targets to build' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l exclude -d 'build paths to exclude' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l skip -d 'build paths to skip' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l rustc-error-format -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l error-format -d 'rustc error format' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l set -d 'override options in config.toml' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -s i -l incremental -d 'use incremental compilation'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l include-default-paths -d 'include default paths in addition to the provided ones'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l dry-run -d 'dry run; don\'t build anything'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l json-output -d 'use message-format=json'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l enable-bolt-settings -d 'Enable BOLT link flags'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
-complete -c x.py -n "__fish_x.py_using_subcommand perf" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l skip -d 'build paths to skip' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l set -d 'override options in config.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "eprintln" -d 'Run `profile_local eprintln`. This executes the compiler on the given benchmarks and stores its stderr output'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "samply" -d 'Run `profile_local samply` This executes the compiler on the given benchmarks and profiles it with `samply`. You need to install `samply`, e.g. using `cargo install samply`'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "cachegrind" -d 'Run `profile_local cachegrind`. This executes the compiler on the given benchmarks under `Cachegrind`'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "benchmark" -d 'Run compile benchmarks with a locally built compiler'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "compare" -d 'Compare the results of two previously executed benchmark runs'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l skip -d 'build paths to skip' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l set -d 'override options in config.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l skip -d 'build paths to skip' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l set -d 'override options in config.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l skip -d 'build paths to skip' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l set -d 'override options in config.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip -d 'build paths to skip' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l set -d 'override options in config.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l skip -d 'build paths to skip' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l set -d 'override options in config.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s h -l help -d 'Print help (see more with \'--help\')'
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 7d5bd3c9632..e5ee174f4ca 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -74,7 +74,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development')
             [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files')
             [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies')
-            [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using the `rustc-perf-wrapper` tool')
+            [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using `rustc-perf`')
             break
         }
         'x.py;build' {
@@ -791,6 +791,223 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('eprintln', 'eprintln', [CompletionResultType]::ParameterValue, 'Run `profile_local eprintln`. This executes the compiler on the given benchmarks and stores its stderr output')
+            [CompletionResult]::new('samply', 'samply', [CompletionResultType]::ParameterValue, 'Run `profile_local samply` This executes the compiler on the given benchmarks and profiles it with `samply`. You need to install `samply`, e.g. using `cargo install samply`')
+            [CompletionResult]::new('cachegrind', 'cachegrind', [CompletionResultType]::ParameterValue, 'Run `profile_local cachegrind`. This executes the compiler on the given benchmarks under `Cachegrind`')
+            [CompletionResult]::new('benchmark', 'benchmark', [CompletionResultType]::ParameterValue, 'Run compile benchmarks with a locally built compiler')
+            [CompletionResult]::new('compare', 'compare', [CompletionResultType]::ParameterValue, 'Compare the results of two previously executed benchmark runs')
+            break
+        }
+        'x.py;perf;eprintln' {
+            [CompletionResult]::new('--include', '--include', [CompletionResultType]::ParameterName, 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run')
+            [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked')
+            [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked')
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
+        'x.py;perf;samply' {
+            [CompletionResult]::new('--include', '--include', [CompletionResultType]::ParameterName, 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run')
+            [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked')
+            [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked')
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
+        'x.py;perf;cachegrind' {
+            [CompletionResult]::new('--include', '--include', [CompletionResultType]::ParameterName, 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run')
+            [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked')
+            [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked')
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
+        'x.py;perf;benchmark' {
+            [CompletionResult]::new('--include', '--include', [CompletionResultType]::ParameterName, 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run')
+            [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked')
+            [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked')
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
+        'x.py;perf;compare' {
+            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', '--error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
         }
     })
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index 5c5e4ef0c15..4952b57b8ab 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -63,6 +63,21 @@ _x.py() {
             x.py,vendor)
                 cmd="x.py__vendor"
                 ;;
+            x.py__perf,benchmark)
+                cmd="x.py__perf__benchmark"
+                ;;
+            x.py__perf,cachegrind)
+                cmd="x.py__perf__cachegrind"
+                ;;
+            x.py__perf,compare)
+                cmd="x.py__perf__compare"
+                ;;
+            x.py__perf,eprintln)
+                cmd="x.py__perf__eprintln"
+                ;;
+            x.py__perf,samply)
+                cmd="x.py__perf__samply"
+                ;;
             *)
                 ;;
         esac
@@ -2359,7 +2374,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2547,6 +2562,999 @@ _x.py() {
             COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
             return 0
             ;;
+        x.py__perf__benchmark)
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help <benchmark-id> [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --include)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --scenarios)
+                    COMPREPLY=($(compgen -W "Full IncrFull IncrUnchanged IncrPatched" -- "${cur}"))
+                    return 0
+                    ;;
+                --profiles)
+                    COMPREPLY=($(compgen -W "Check Debug Doc Opt Clippy" -- "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        x.py__perf__cachegrind)
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --include)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --scenarios)
+                    COMPREPLY=($(compgen -W "Full IncrFull IncrUnchanged IncrPatched" -- "${cur}"))
+                    return 0
+                    ;;
+                --profiles)
+                    COMPREPLY=($(compgen -W "Check Debug Doc Opt Clippy" -- "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        x.py__perf__compare)
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        x.py__perf__eprintln)
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --include)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --scenarios)
+                    COMPREPLY=($(compgen -W "Full IncrFull IncrUnchanged IncrPatched" -- "${cur}"))
+                    return 0
+                    ;;
+                --profiles)
+                    COMPREPLY=($(compgen -W "Check Debug Doc Opt Clippy" -- "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        x.py__perf__samply)
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --include)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --scenarios)
+                    COMPREPLY=($(compgen -W "Full IncrFull IncrUnchanged IncrPatched" -- "${cur}"))
+                    return 0
+                    ;;
+                --profiles)
+                    COMPREPLY=($(compgen -W "Check Debug Doc Opt Clippy" -- "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
         x.py__run)
             opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index dd71ec00edf..71afd5e73ca 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -811,9 +811,247 @@ _arguments "${_arguments_options[@]}" : \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
+'::paths -- paths for the subcommand:_files' \
+'::free_args -- arguments passed to subcommands:_default' \
+":: :_x.py__perf_commands" \
+"*::: :->perf" \
+&& ret=0
+
+    case $state in
+    (perf)
+        words=($line[3] "${words[@]}")
+        (( CURRENT += 1 ))
+        curcontext="${curcontext%:*:*}:x.py-perf-command-$line[3]:"
+        case $line[3] in
+            (eprintln)
+_arguments "${_arguments_options[@]}" : \
+'*--include=[Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed]:INCLUDE:_default' \
+'*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \
+'*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \
+'*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
+(samply)
+_arguments "${_arguments_options[@]}" : \
+'*--include=[Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed]:INCLUDE:_default' \
+'*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \
+'*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \
+'*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
 && ret=0
 ;;
+(cachegrind)
+_arguments "${_arguments_options[@]}" : \
+'*--include=[Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed]:INCLUDE:_default' \
+'*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \
+'*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \
+'*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
+(benchmark)
+_arguments "${_arguments_options[@]}" : \
+'*--include=[Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed]:INCLUDE:_default' \
+'*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \
+'*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \
+'*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+':benchmark-id -- Identifier to associate benchmark results with:_default' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
+(compare)
+_arguments "${_arguments_options[@]}" : \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--exclude=[build paths to exclude]:PATH:_files' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+':base -- The name of the base artifact to be compared:_default' \
+':modified -- The name of the modified artifact to be compared:_default' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
+        esac
+    ;;
+esac
+;;
         esac
     ;;
 esac
@@ -838,7 +1076,7 @@ _x.py_commands() {
 'setup:Set up the environment for development' \
 'suggest:Suggest a subset of tests to run, based on modified files' \
 'vendor:Vendor dependencies' \
-'perf:Perform profiling and benchmarking of the compiler using the \`rustc-perf-wrapper\` tool' \
+'perf:Perform profiling and benchmarking of the compiler using \`rustc-perf\`' \
     )
     _describe -t commands 'x.py commands' commands "$@"
 }
@@ -899,9 +1137,40 @@ _x.py__miri_commands() {
 }
 (( $+functions[_x.py__perf_commands] )) ||
 _x.py__perf_commands() {
-    local commands; commands=()
+    local commands; commands=(
+'eprintln:Run \`profile_local eprintln\`. This executes the compiler on the given benchmarks and stores its stderr output' \
+'samply:Run \`profile_local samply\` This executes the compiler on the given benchmarks and profiles it with \`samply\`. You need to install \`samply\`, e.g. using \`cargo install samply\`' \
+'cachegrind:Run \`profile_local cachegrind\`. This executes the compiler on the given benchmarks under \`Cachegrind\`' \
+'benchmark:Run compile benchmarks with a locally built compiler' \
+'compare:Compare the results of two previously executed benchmark runs' \
+    )
     _describe -t commands 'x.py perf commands' commands "$@"
 }
+(( $+functions[_x.py__perf__benchmark_commands] )) ||
+_x.py__perf__benchmark_commands() {
+    local commands; commands=()
+    _describe -t commands 'x.py perf benchmark commands' commands "$@"
+}
+(( $+functions[_x.py__perf__cachegrind_commands] )) ||
+_x.py__perf__cachegrind_commands() {
+    local commands; commands=()
+    _describe -t commands 'x.py perf cachegrind commands' commands "$@"
+}
+(( $+functions[_x.py__perf__compare_commands] )) ||
+_x.py__perf__compare_commands() {
+    local commands; commands=()
+    _describe -t commands 'x.py perf compare commands' commands "$@"
+}
+(( $+functions[_x.py__perf__eprintln_commands] )) ||
+_x.py__perf__eprintln_commands() {
+    local commands; commands=()
+    _describe -t commands 'x.py perf eprintln commands' commands "$@"
+}
+(( $+functions[_x.py__perf__samply_commands] )) ||
+_x.py__perf__samply_commands() {
+    local commands; commands=()
+    _describe -t commands 'x.py perf samply commands' commands "$@"
+}
 (( $+functions[_x.py__run_commands] )) ||
 _x.py__run_commands() {
     local commands; commands=()
diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh
index 057af1ffc6d..26a44b3ff2f 100644
--- a/src/etc/completions/x.sh
+++ b/src/etc/completions/x.sh
@@ -63,6 +63,21 @@ _x() {
             x,vendor)
                 cmd="x__vendor"
                 ;;
+            x__perf,benchmark)
+                cmd="x__perf__benchmark"
+                ;;
+            x__perf,cachegrind)
+                cmd="x__perf__cachegrind"
+                ;;
+            x__perf,compare)
+                cmd="x__perf__compare"
+                ;;
+            x__perf,eprintln)
+                cmd="x__perf__eprintln"
+                ;;
+            x__perf,samply)
+                cmd="x__perf__samply"
+                ;;
             *)
                 ;;
         esac
@@ -2359,7 +2374,7 @@ _x() {
             return 0
             ;;
         x__perf)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2547,6 +2562,999 @@ _x() {
             COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
             return 0
             ;;
+        x__perf__benchmark)
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help <benchmark-id> [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --include)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --scenarios)
+                    COMPREPLY=($(compgen -W "Full IncrFull IncrUnchanged IncrPatched" -- "${cur}"))
+                    return 0
+                    ;;
+                --profiles)
+                    COMPREPLY=($(compgen -W "Check Debug Doc Opt Clippy" -- "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        x__perf__cachegrind)
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --include)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --scenarios)
+                    COMPREPLY=($(compgen -W "Full IncrFull IncrUnchanged IncrPatched" -- "${cur}"))
+                    return 0
+                    ;;
+                --profiles)
+                    COMPREPLY=($(compgen -W "Check Debug Doc Opt Clippy" -- "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        x__perf__compare)
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        x__perf__eprintln)
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --include)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --scenarios)
+                    COMPREPLY=($(compgen -W "Full IncrFull IncrUnchanged IncrPatched" -- "${cur}"))
+                    return 0
+                    ;;
+                --profiles)
+                    COMPREPLY=($(compgen -W "Check Debug Doc Opt Clippy" -- "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        x__perf__samply)
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --include)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --scenarios)
+                    COMPREPLY=($(compgen -W "Full IncrFull IncrUnchanged IncrPatched" -- "${cur}"))
+                    return 0
+                    ;;
+                --profiles)
+                    COMPREPLY=($(compgen -W "Check Debug Doc Opt Clippy" -- "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=()
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o plusdirs
+                    fi
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    local oldifs
+                    if [ -n "${IFS+x}" ]; then
+                        oldifs="$IFS"
+                    fi
+                    IFS=$'\n'
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    if [ -n "${oldifs+x}" ]; then
+                        IFS="$oldifs"
+                    fi
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o filenames
+                    fi
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
+                        compopt -o nospace
+                    fi
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
         x__run)
             opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh
index 6215f9af833..b08eb06f8e6 100644
--- a/src/etc/completions/x.zsh
+++ b/src/etc/completions/x.zsh
@@ -811,9 +811,247 @@ _arguments "${_arguments_options[@]}" : \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
+'::paths -- paths for the subcommand:_files' \
+'::free_args -- arguments passed to subcommands:_default' \
+":: :_x__perf_commands" \
+"*::: :->perf" \
+&& ret=0
+
+    case $state in
+    (perf)
+        words=($line[3] "${words[@]}")
+        (( CURRENT += 1 ))
+        curcontext="${curcontext%:*:*}:x-perf-command-$line[3]:"
+        case $line[3] in
+            (eprintln)
+_arguments "${_arguments_options[@]}" : \
+'*--include=[Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed]:INCLUDE:_default' \
+'*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \
+'*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \
+'*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
+(samply)
+_arguments "${_arguments_options[@]}" : \
+'*--include=[Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed]:INCLUDE:_default' \
+'*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \
+'*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \
+'*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
 && ret=0
 ;;
+(cachegrind)
+_arguments "${_arguments_options[@]}" : \
+'*--include=[Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed]:INCLUDE:_default' \
+'*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \
+'*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \
+'*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
+(benchmark)
+_arguments "${_arguments_options[@]}" : \
+'*--include=[Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed]:INCLUDE:_default' \
+'*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \
+'*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \
+'*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+':benchmark-id -- Identifier to associate benchmark results with:_default' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
+(compare)
+_arguments "${_arguments_options[@]}" : \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
+'*--exclude=[build paths to exclude]:PATH:_files' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+':base -- The name of the base artifact to be compared:_default' \
+':modified -- The name of the modified artifact to be compared:_default' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
+        esac
+    ;;
+esac
+;;
         esac
     ;;
 esac
@@ -838,7 +1076,7 @@ _x_commands() {
 'setup:Set up the environment for development' \
 'suggest:Suggest a subset of tests to run, based on modified files' \
 'vendor:Vendor dependencies' \
-'perf:Perform profiling and benchmarking of the compiler using the \`rustc-perf-wrapper\` tool' \
+'perf:Perform profiling and benchmarking of the compiler using \`rustc-perf\`' \
     )
     _describe -t commands 'x commands' commands "$@"
 }
@@ -899,9 +1137,40 @@ _x__miri_commands() {
 }
 (( $+functions[_x__perf_commands] )) ||
 _x__perf_commands() {
-    local commands; commands=()
+    local commands; commands=(
+'eprintln:Run \`profile_local eprintln\`. This executes the compiler on the given benchmarks and stores its stderr output' \
+'samply:Run \`profile_local samply\` This executes the compiler on the given benchmarks and profiles it with \`samply\`. You need to install \`samply\`, e.g. using \`cargo install samply\`' \
+'cachegrind:Run \`profile_local cachegrind\`. This executes the compiler on the given benchmarks under \`Cachegrind\`' \
+'benchmark:Run compile benchmarks with a locally built compiler' \
+'compare:Compare the results of two previously executed benchmark runs' \
+    )
     _describe -t commands 'x perf commands' commands "$@"
 }
+(( $+functions[_x__perf__benchmark_commands] )) ||
+_x__perf__benchmark_commands() {
+    local commands; commands=()
+    _describe -t commands 'x perf benchmark commands' commands "$@"
+}
+(( $+functions[_x__perf__cachegrind_commands] )) ||
+_x__perf__cachegrind_commands() {
+    local commands; commands=()
+    _describe -t commands 'x perf cachegrind commands' commands "$@"
+}
+(( $+functions[_x__perf__compare_commands] )) ||
+_x__perf__compare_commands() {
+    local commands; commands=()
+    _describe -t commands 'x perf compare commands' commands "$@"
+}
+(( $+functions[_x__perf__eprintln_commands] )) ||
+_x__perf__eprintln_commands() {
+    local commands; commands=()
+    _describe -t commands 'x perf eprintln commands' commands "$@"
+}
+(( $+functions[_x__perf__samply_commands] )) ||
+_x__perf__samply_commands() {
+    local commands; commands=()
+    _describe -t commands 'x perf samply commands' commands "$@"
+}
 (( $+functions[_x__run_commands] )) ||
 _x__run_commands() {
     local commands; commands=()
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index d9bd11267da..c593cdcbcd2 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -13,7 +13,7 @@ rinja = { version = "0.3", default-features = false, features = ["config"] }
 base64 = "0.21.7"
 itertools = "0.12"
 indexmap = "2"
-minifier = { version = "0.3.2", default-features = false }
+minifier = { version = "0.3.4", default-features = false }
 pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false }
 regex = "1"
 rustdoc-json-types = { path = "../rustdoc-json-types" }
diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs
index 2c62e12c96d..26dc101e4b5 100644
--- a/src/librustdoc/clean/cfg/tests.rs
+++ b/src/librustdoc/clean/cfg/tests.rs
@@ -276,10 +276,13 @@ fn test_parse_ok() {
         let mi = dummy_meta_item_list!(not, [a]);
         assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a")));
 
-        let mi = dummy_meta_item_list!(not, [dummy_meta_item_list!(any, [
-            dummy_meta_item_word("a"),
-            dummy_meta_item_list!(all, [b, c]),
-        ]),]);
+        let mi = dummy_meta_item_list!(
+            not,
+            [dummy_meta_item_list!(
+                any,
+                [dummy_meta_item_word("a"), dummy_meta_item_list!(all, [b, c]),]
+            ),]
+        );
         assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c")))));
 
         let mi = dummy_meta_item_list!(all, [a, b, c]);
@@ -302,18 +305,16 @@ fn test_parse_err() {
         let mi = dummy_meta_item_list!(foo, []);
         assert!(Cfg::parse(&mi).is_err());
 
-        let mi =
-            dummy_meta_item_list!(
-                all,
-                [dummy_meta_item_list!(foo, []), dummy_meta_item_word("b"),]
-            );
+        let mi = dummy_meta_item_list!(
+            all,
+            [dummy_meta_item_list!(foo, []), dummy_meta_item_word("b"),]
+        );
         assert!(Cfg::parse(&mi).is_err());
 
-        let mi =
-            dummy_meta_item_list!(
-                any,
-                [dummy_meta_item_word("a"), dummy_meta_item_list!(foo, []),]
-            );
+        let mi = dummy_meta_item_list!(
+            any,
+            [dummy_meta_item_word("a"), dummy_meta_item_list!(foo, []),]
+        );
         assert!(Cfg::parse(&mi).is_err());
 
         let mi = dummy_meta_item_list!(not, [dummy_meta_item_list!(foo, []),]);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index b14381c0c40..1d62a93e723 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -544,14 +544,18 @@ fn clean_generic_param_def(
             } else {
                 None
             };
-            (def.name, GenericParamDefKind::Type {
-                bounds: ThinVec::new(), // These are filled in from the where-clauses.
-                default: default.map(Box::new),
-                synthetic,
-            })
+            (
+                def.name,
+                GenericParamDefKind::Type {
+                    bounds: ThinVec::new(), // These are filled in from the where-clauses.
+                    default: default.map(Box::new),
+                    synthetic,
+                },
+            )
         }
-        ty::GenericParamDefKind::Const { has_default, synthetic } => {
-            (def.name, GenericParamDefKind::Const {
+        ty::GenericParamDefKind::Const { has_default, synthetic } => (
+            def.name,
+            GenericParamDefKind::Const {
                 ty: Box::new(clean_middle_ty(
                     ty::Binder::dummy(
                         cx.tcx
@@ -573,8 +577,8 @@ fn clean_generic_param_def(
                     None
                 },
                 synthetic,
-            })
-        }
+            },
+        ),
     };
 
     GenericParamDef { name, def_id: def.def_id, kind }
@@ -619,21 +623,25 @@ fn clean_generic_param<'tcx>(
             } else {
                 ThinVec::new()
             };
-            (param.name.ident().name, GenericParamDefKind::Type {
-                bounds,
-                default: default.map(|t| clean_ty(t, cx)).map(Box::new),
-                synthetic,
-            })
+            (
+                param.name.ident().name,
+                GenericParamDefKind::Type {
+                    bounds,
+                    default: default.map(|t| clean_ty(t, cx)).map(Box::new),
+                    synthetic,
+                },
+            )
         }
-        hir::GenericParamKind::Const { ty, default, synthetic } => {
-            (param.name.ident().name, GenericParamDefKind::Const {
+        hir::GenericParamKind::Const { ty, default, synthetic } => (
+            param.name.ident().name,
+            GenericParamDefKind::Const {
                 ty: Box::new(clean_ty(ty, cx)),
                 default: default.map(|ct| {
                     Box::new(lower_const_arg_for_rustdoc(cx.tcx, ct, FeedConstTy::No).to_string())
                 }),
                 synthetic,
-            })
-        }
+            },
+        ),
     };
 
     GenericParamDef { name, def_id: param.def_id.to_def_id(), kind }
@@ -653,9 +661,10 @@ fn is_impl_trait(param: &hir::GenericParam<'_>) -> bool {
 ///
 /// See `lifetime_to_generic_param` in `rustc_ast_lowering` for more information.
 fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool {
-    matches!(param.kind, hir::GenericParamKind::Lifetime {
-        kind: hir::LifetimeParamKind::Elided(_)
-    })
+    matches!(
+        param.kind,
+        hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided(_) }
+    )
 }
 
 pub(crate) fn clean_generics<'tcx>(
@@ -1055,11 +1064,10 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib
                         ..
                     } = param
                     {
-                        func.decl.inputs.values.insert(a.get() as _, Argument {
-                            name,
-                            type_: *ty,
-                            is_const: true,
-                        });
+                        func.decl
+                            .inputs
+                            .values
+                            .insert(a.get() as _, Argument { name, type_: *ty, is_const: true });
                     } else {
                         panic!("unexpected non const in position {pos}");
                     }
@@ -1422,11 +1430,11 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
                 let bounds = tcx.explicit_item_bounds(assoc_item.def_id).iter_identity_copied();
                 predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied()));
             }
-            let mut generics =
-                clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), ty::GenericPredicates {
-                    parent: None,
-                    predicates,
-                });
+            let mut generics = clean_ty_generics(
+                cx,
+                tcx.generics_of(assoc_item.def_id),
+                ty::GenericPredicates { parent: None, predicates },
+            );
             simplify::move_bounds_to_generic_parameters(&mut generics);
 
             if let ty::AssocItemContainer::Trait = assoc_item.container {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 583cd404dca..5f7c30a33ab 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1253,10 +1253,13 @@ impl GenericBound {
     }
 
     pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
-        Self::sized_with(cx, hir::TraitBoundModifiers {
-            polarity: hir::BoundPolarity::Maybe(DUMMY_SP),
-            constness: hir::BoundConstness::Never,
-        })
+        Self::sized_with(
+            cx,
+            hir::TraitBoundModifiers {
+                polarity: hir::BoundPolarity::Maybe(DUMMY_SP),
+                constness: hir::BoundConstness::Never,
+            },
+        )
     }
 
     fn sized_with(cx: &mut DocContext<'_>, modifiers: hir::TraitBoundModifiers) -> GenericBound {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 7b2aee4b4a5..8c91cae4931 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -65,26 +65,34 @@ fn write_header(
     tooltip: Tooltip,
     extra_classes: &[String],
 ) {
-    write!(out, "<div class=\"example-wrap{}\">", match tooltip {
-        Tooltip::Ignore => " ignore",
-        Tooltip::CompileFail => " compile_fail",
-        Tooltip::ShouldPanic => " should_panic",
-        Tooltip::Edition(_) => " edition",
-        Tooltip::None => "",
-    },);
+    write!(
+        out,
+        "<div class=\"example-wrap{}\">",
+        match tooltip {
+            Tooltip::Ignore => " ignore",
+            Tooltip::CompileFail => " compile_fail",
+            Tooltip::ShouldPanic => " should_panic",
+            Tooltip::Edition(_) => " edition",
+            Tooltip::None => "",
+        },
+    );
 
     if tooltip != Tooltip::None {
         let edition_code;
-        write!(out, "<a href=\"#\" class=\"tooltip\" title=\"{}\">ⓘ</a>", match tooltip {
-            Tooltip::Ignore => "This example is not tested",
-            Tooltip::CompileFail => "This example deliberately fails to compile",
-            Tooltip::ShouldPanic => "This example panics",
-            Tooltip::Edition(edition) => {
-                edition_code = format!("This example runs with edition {edition}");
-                &edition_code
-            }
-            Tooltip::None => unreachable!(),
-        },);
+        write!(
+            out,
+            "<a href=\"#\" class=\"tooltip\" title=\"{}\">ⓘ</a>",
+            match tooltip {
+                Tooltip::Ignore => "This example is not tested",
+                Tooltip::CompileFail => "This example deliberately fails to compile",
+                Tooltip::ShouldPanic => "This example panics",
+                Tooltip::Edition(edition) => {
+                    edition_code = format!("This example runs with edition {edition}");
+                    &edition_code
+                }
+                Tooltip::None => unreachable!(),
+            },
+        );
     }
 
     if let Some(extra) = extra_content {
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index 2001a763c09..bb42b877a2c 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -275,14 +275,14 @@ fn test_lang_string_tokenizer() {
     case("foo", &[LangStringToken::LangToken("foo")]);
     case("foo,bar", &[LangStringToken::LangToken("foo"), LangStringToken::LangToken("bar")]);
     case(".foo,.bar", &[]);
-    case("{.foo,.bar}", &[
-        LangStringToken::ClassAttribute("foo"),
-        LangStringToken::ClassAttribute("bar"),
-    ]);
-    case("  {.foo,.bar}  ", &[
-        LangStringToken::ClassAttribute("foo"),
-        LangStringToken::ClassAttribute("bar"),
-    ]);
+    case(
+        "{.foo,.bar}",
+        &[LangStringToken::ClassAttribute("foo"), LangStringToken::ClassAttribute("bar")],
+    );
+    case(
+        "  {.foo,.bar}  ",
+        &[LangStringToken::ClassAttribute("foo"), LangStringToken::ClassAttribute("bar")],
+    );
     case("foo bar", &[LangStringToken::LangToken("foo"), LangStringToken::LangToken("bar")]);
     case("foo\tbar", &[LangStringToken::LangToken("foo"), LangStringToken::LangToken("bar")]);
     case("foo\t, bar", &[LangStringToken::LangToken("foo"), LangStringToken::LangToken("bar")]);
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index 8ac8b3a1f84..95f617c9839 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -1265,13 +1265,14 @@ fn simplify_fn_type<'a, 'tcx>(
                                 *stored_bounds = type_bounds;
                             }
                         }
-                        ty_constraints.push((RenderTypeId::AssociatedType(name), vec![
-                            RenderType {
+                        ty_constraints.push((
+                            RenderTypeId::AssociatedType(name),
+                            vec![RenderType {
                                 id: Some(RenderTypeId::Index(idx)),
                                 generics: None,
                                 bindings: None,
-                            },
-                        ]))
+                            }],
+                        ))
                     }
                 }
             }
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 789a5614967..6f8cf25554f 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -268,11 +268,14 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                 .iter()
                 .chain(&self.cache.external_paths)
                 .map(|(&k, &(ref path, kind))| {
-                    (self.id_from_item_default(k.into()), types::ItemSummary {
-                        crate_id: k.krate.as_u32(),
-                        path: path.iter().map(|s| s.to_string()).collect(),
-                        kind: kind.into_json(self),
-                    })
+                    (
+                        self.id_from_item_default(k.into()),
+                        types::ItemSummary {
+                            crate_id: k.krate.as_u32(),
+                            path: path.iter().map(|s| s.to_string()).collect(),
+                            kind: kind.into_json(self),
+                        },
+                    )
                 })
                 .collect(),
             external_crates: self
@@ -281,13 +284,16 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                 .iter()
                 .map(|(crate_num, external_location)| {
                     let e = ExternalCrate { crate_num: *crate_num };
-                    (crate_num.as_u32(), types::ExternalCrate {
-                        name: e.name(self.tcx).to_string(),
-                        html_root_url: match external_location {
-                            ExternalLocation::Remote(s) => Some(s.clone()),
-                            _ => None,
+                    (
+                        crate_num.as_u32(),
+                        types::ExternalCrate {
+                            name: e.name(self.tcx).to_string(),
+                            html_root_url: match external_location {
+                                ExternalLocation::Remote(s) => Some(s.clone()),
+                                _ => None,
+                            },
                         },
-                    })
+                    )
                 })
                 .collect(),
             format_version: types::FORMAT_VERSION,
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
index 77d7cf5772d..1e07277d38e 100644
--- a/src/librustdoc/passes/lint/bare_urls.rs
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -77,9 +77,10 @@ fn find_raw_urls(
     // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
     for match_ in URL_REGEX.find_iter(text) {
         let url_range = match_.range();
-        f(cx, "this URL is not a hyperlink", Range {
-            start: range.start + url_range.start,
-            end: range.start + url_range.end,
-        });
+        f(
+            cx,
+            "this URL is not a hyperlink",
+            Range { start: range.start + url_range.start, end: range.start + url_range.end },
+        );
     }
 }
diff --git a/src/stage0 b/src/stage0
index bd9a753c211..5c3e3a7cebc 100644
--- a/src/stage0
+++ b/src/stage0
@@ -14,468 +14,468 @@ nightly_branch=master
 # All changes below this comment will be overridden the next time the
 # tool is executed.
             
-compiler_date=2025-01-08
+compiler_date=2025-02-08
 compiler_version=beta
-rustfmt_date=2025-01-08
+rustfmt_date=2025-02-08
 rustfmt_version=nightly
 
-dist/2025-01-08/rustc-beta-aarch64-apple-darwin.tar.gz=8869795c998e9d39a7093bf53917291b066e35964059298cb1cc2ee2f1088b2e
-dist/2025-01-08/rustc-beta-aarch64-apple-darwin.tar.xz=1397b1ee764dd51d8a082a063b6b13a2d5609b1e1a6e1dbbc0368f24e7830e85
-dist/2025-01-08/rustc-beta-aarch64-pc-windows-msvc.tar.gz=68719c1f92c6aa4251c27910c9f788472166444a9295cfa0af6450bc6b5e6555
-dist/2025-01-08/rustc-beta-aarch64-pc-windows-msvc.tar.xz=56fca9013ab1646263f043898346dfe206f4b264c37d1cf39fc61807e47c072d
-dist/2025-01-08/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=7acc2b71f759f098c542f0ff4f3705e73112dfb3b8e85bb9158d1ce10d858efe
-dist/2025-01-08/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=0d21e19b284d2053879ee55353f0d601e3b359530cfb9c747f6cc4ad9b67ade9
-dist/2025-01-08/rustc-beta-aarch64-unknown-linux-musl.tar.gz=25a5b2cf16fb51056c208e5899c9843bc3a902ae2f4148ac53f0b9043727e321
-dist/2025-01-08/rustc-beta-aarch64-unknown-linux-musl.tar.xz=31b1dead28d88897fcb2ccdaf72021faba9febe50d797e70ff5c29ae82179618
-dist/2025-01-08/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=fa8d3c93890425c9a0d130a652d3a4ecd018cb3098efe243a3ce8422539cb9ce
-dist/2025-01-08/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=15344286d365042d9bd8cced1268eed508aaa6152d5e3e289fbd5ebc87788e75
-dist/2025-01-08/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=c5ed0dd8c2a3b609d9fdd88b027a1d628517107af8b5488a74bce9a3a4dbebcb
-dist/2025-01-08/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=ff5eb5bc42dcfedaae86bf31af37c6c2bdb6210e98cbdd780c4e1a63ba37eaeb
-dist/2025-01-08/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=6108711c53f07920a9afd0e749ff4228396220ec2eeacab2310e5b32af7a5e91
-dist/2025-01-08/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=7bd41663ab83aa4bef55f3c44e4e4cd3c4291c967573cf8b2ba3d60eda9d06f7
-dist/2025-01-08/rustc-beta-i686-pc-windows-gnu.tar.gz=12ba512d2dece4f9be9ac08f3270bfa6663aa28a3443f1cbd7f852ab052f12ab
-dist/2025-01-08/rustc-beta-i686-pc-windows-gnu.tar.xz=834cd8f4962401dc522a5a0ac866561a62c646614a6ce4b99e91619098538861
-dist/2025-01-08/rustc-beta-i686-pc-windows-msvc.tar.gz=9915fde0d52fcc41eb5f5eb19c06be447187aaf3e5b4f438f7c20d92b364527e
-dist/2025-01-08/rustc-beta-i686-pc-windows-msvc.tar.xz=e4e79679d6f90b5de5c64a534ff150416e48aed276d7426a1d4b1fc2e517cefe
-dist/2025-01-08/rustc-beta-i686-unknown-linux-gnu.tar.gz=e394e8f0361f0f8a8a9653cab3ade57de10622651675e27c137cef2b06114a6d
-dist/2025-01-08/rustc-beta-i686-unknown-linux-gnu.tar.xz=756965d724f5389a3cb63374b4287ea48e18d38827ac3af61a127fc6561ab865
-dist/2025-01-08/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=4e3483a31356c4c7c0a7041d318b36e02bcd25ac25c396e4dd139ff4ecad5af5
-dist/2025-01-08/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=9fcc0531f285832f5333762317ff64dd2506bc263e447f1931d361b15430d0f8
-dist/2025-01-08/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=780ab392bd8d879efc593ec9f87c1ff927e750fea4fdaae23d327fc363f8078f
-dist/2025-01-08/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=bfad2585877df4fc99fe708187336631140a8170d21159a6deb7cd8f8ed20248
-dist/2025-01-08/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=30659e0526394f50ada52ce228cbe342e7ad9f6db2f0e1dfe6c8c63eb7ec3dd4
-dist/2025-01-08/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=e59cbdad42098b5f402f612c957113e7f7b8f4b4f37292079187f44d1753360e
-dist/2025-01-08/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=adc19d38f3927cd2c09e2b4bc5e31b1b2473d45027b839abab1837ef22b6cb31
-dist/2025-01-08/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=35b15e40ea3b382d67e98dabbb93916abecb7d18977652760e081c1a112300d5
-dist/2025-01-08/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=31477a7164f8b3658bdf192bcb1383bb77f93e684887fc7b06e55bb469e7e25a
-dist/2025-01-08/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=67f4e6f541e16eafa55e803e2c41fef1c892e7408f61228bdaabfb3a4cb41ade
-dist/2025-01-08/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=2f4b8b12fc8bd7bd5783cc77e9b798de3ecd4a17f5a09d6fd4f3a528e1a243a5
-dist/2025-01-08/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=474f1a2b2f3a2379da02ba24c59a160a7ab0a2bdb4290b0b277d8aea8e441a53
-dist/2025-01-08/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=6be8f141e0a3f00abade77cde91405ac107d729f24b946c89831baa674c210d9
-dist/2025-01-08/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=897be1e29a2b67a9dc2d69195ec1f41439903dd3ad8a7b57eb339344ca6ec5da
-dist/2025-01-08/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b58ebbaeb5474f577329f4d48991222621d4f30f6411a00973951917586e2cf6
-dist/2025-01-08/rustc-beta-s390x-unknown-linux-gnu.tar.xz=215384ed943e173fcb4e10baa69d6929c99e8eeb4790365f1067bf20d5417b32
-dist/2025-01-08/rustc-beta-x86_64-apple-darwin.tar.gz=40a3d42489eb77cc7912af5580632f8f6f27373b0f691d24b7d249ca9bc84a41
-dist/2025-01-08/rustc-beta-x86_64-apple-darwin.tar.xz=6f8c83b96ba2d9bdb623af0f09b6227532d8c0c0f6ac19fb4b0c5f5145d2ee9c
-dist/2025-01-08/rustc-beta-x86_64-pc-windows-gnu.tar.gz=1f76fb03cca2d0fe466c995467f209c28a68d8ad69e7b2fce521f4ace94106f8
-dist/2025-01-08/rustc-beta-x86_64-pc-windows-gnu.tar.xz=5bed9303cb18b7c5d78875b11463b945c9c9583c5b377efb69462bda0f92b190
-dist/2025-01-08/rustc-beta-x86_64-pc-windows-msvc.tar.gz=a64fedbd98a9d2e8ca6d21018abf627367e2c81a028d38fb850253a6c94ef45b
-dist/2025-01-08/rustc-beta-x86_64-pc-windows-msvc.tar.xz=471c040fe9f119e3ddf74fb8887d03cecc415109577a85c14917c00ab3348d0c
-dist/2025-01-08/rustc-beta-x86_64-unknown-freebsd.tar.gz=468f89e4f6b7e72cfeeb19eeb723e723673487f3d1cf333d860623bf454e4ff9
-dist/2025-01-08/rustc-beta-x86_64-unknown-freebsd.tar.xz=c9e699c5fdbf0af0434354caf8745796db42a931669e733b3a7432baabf81974
-dist/2025-01-08/rustc-beta-x86_64-unknown-illumos.tar.gz=e0dbd7d05f74a1d444efb849700f98bbe6b00f870036e5cf6f065fc2d0b982b7
-dist/2025-01-08/rustc-beta-x86_64-unknown-illumos.tar.xz=1936046fd441ed9bf8331f77ac9ba930640523ded0674831912d28f9f7ae90c1
-dist/2025-01-08/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=c6dbeb9017e7f9694ddb05c4658250945e1d6c2b6de656306a3686d499653029
-dist/2025-01-08/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=adec507e847d746ef1bdb0464b23ef7fd840d17e7bff787a198fae239b69a77d
-dist/2025-01-08/rustc-beta-x86_64-unknown-linux-musl.tar.gz=32714ed814213cc64fb1721c919c43a877286f625289bf5d526e247de0941e05
-dist/2025-01-08/rustc-beta-x86_64-unknown-linux-musl.tar.xz=fdebe84ac7370ca3cfa66cff6974c00e506aab6fb3ecb6b70e8e2c3ef92025f3
-dist/2025-01-08/rustc-beta-x86_64-unknown-netbsd.tar.gz=6443e8f6c2cd4d5f4a0b7f38e1c741061f42c454d006afc06ab87968425a8f44
-dist/2025-01-08/rustc-beta-x86_64-unknown-netbsd.tar.xz=c12851a0437c7ba6edf08d9ec89f2ccd22f05a5de661664142bf4f15d2a658a2
-dist/2025-01-08/rust-std-beta-aarch64-apple-darwin.tar.gz=e88734bd578a36ca396032144b25717e18ff51c519ff9490b193117516b299be
-dist/2025-01-08/rust-std-beta-aarch64-apple-darwin.tar.xz=60f5672d8759ccf632e072cce922dd9d079a8e2325098b278afc4fa829943a2f
-dist/2025-01-08/rust-std-beta-aarch64-apple-ios.tar.gz=bfd63a92d85035bdd4b4d445427c68483a34b41f647b09390de2ac9342ad6b54
-dist/2025-01-08/rust-std-beta-aarch64-apple-ios.tar.xz=9e9b941612bb29e317e4dd10ced4cdaec502526fa964b3aa29cd4fc2af070451
-dist/2025-01-08/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=2dc9ed6bbb9fd1d576bc78321a78f7997928a6a94625d90a613286e1a5bec758
-dist/2025-01-08/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=ecb686e8f201952f1e3475a88de73eb264a11c74961967bd1ba7eee87a248bfb
-dist/2025-01-08/rust-std-beta-aarch64-apple-ios-sim.tar.gz=b481a6f88b8696b86160541083e608ef811f1ec0d9b1455325fd48efdaca6f01
-dist/2025-01-08/rust-std-beta-aarch64-apple-ios-sim.tar.xz=584d7a1cd7be4af3c747269de3466a312e541dfa17b1614ad355b32b74ea1ad8
-dist/2025-01-08/rust-std-beta-aarch64-linux-android.tar.gz=c91990c99c5687216320bb82e9e2f8f7b2242fafd534cbb0ae88a287880c2dab
-dist/2025-01-08/rust-std-beta-aarch64-linux-android.tar.xz=c3a4a168393d0a8222b8ebdb6b5495a8896788156af4c454e35d349d1ab63109
-dist/2025-01-08/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=5a7c5b256b41a9ee01387da8ffaa49a3914737c827113beba081f34671568e84
-dist/2025-01-08/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=d0343608f884db1579847539eb6346ad3cb7b85072bf698598db61dee720793d
-dist/2025-01-08/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=6cf78705518f865a7c6d3c9c4566b0dca6197338d5d88dc0037c721261e5dc3c
-dist/2025-01-08/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=c8c81ffc20538dea3050a7b7ba89cab620423e66a10931befba354e2c4572ea1
-dist/2025-01-08/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=966f512ab3d23e303f7162d03bc619aff54b0af25bab86bedc0c96e130c89545
-dist/2025-01-08/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=fba9f964d8fb51753435c300319870a3b4530e385887a16d31975597cfde3ca7
-dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=997d422eedd7b6adfd175ef6a13b5ae7a83530d633f834e7ca0d94851ed29ed6
-dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=5ff49e69e9b549494542c9306c1fc82f6221b8d9e9fe25ec5021fe46f7c8cb28
-dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=2181081deaa27438f420df53847b8108f96ad215369cae81947f0688b1906cc2
-dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=f8b28aeeae9973c1dddbea684eec9a6a136fda3f850b4ffaa10e53914e1037e0
-dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=a49eeccef00269063a10b1e623a54b0b500afbc2dd8e1db4ff8ae4a6844de943
-dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=32fa668c9d3d703adbf6910ef358dbcab344d37fd3ce4e81ba43a820d8a8792e
-dist/2025-01-08/rust-std-beta-aarch64-unknown-none.tar.gz=95c6a6a65ede296e8b4183a1271dd6cb1c61299f3966a8e2a6180867752a2988
-dist/2025-01-08/rust-std-beta-aarch64-unknown-none.tar.xz=a44fa8ccbc73899c013526ca32866f63e1165e7f3b14455b91b37e3865c9e1c0
-dist/2025-01-08/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=31448ceb30ff86b5d8b4e7fa8fe5871665115d561e6377f73e164d8f11652b6e
-dist/2025-01-08/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=bd71a90489b9ed6134d0fd05fd22c58b20c271422628a552d04bbc2bfd1bd29e
-dist/2025-01-08/rust-std-beta-aarch64-unknown-uefi.tar.gz=0cc22881954c661d2ae01058ca04db10912289812e9cfdbca3c066227e38566a
-dist/2025-01-08/rust-std-beta-aarch64-unknown-uefi.tar.xz=439e6cda62ca17f124ed788ed8c3882c2999362067214ed911aa362b8d4d22b8
-dist/2025-01-08/rust-std-beta-arm-linux-androideabi.tar.gz=c62e75f3754b04b3594189de953ca6a8703679b29e8da3935ee5a7370ee0e03c
-dist/2025-01-08/rust-std-beta-arm-linux-androideabi.tar.xz=dd23a5df6353aa01271f0d1206f927dc0f532203fbf66258b2771155e543b86f
-dist/2025-01-08/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=2cf5fee1c6cc0e2ee099c8687126b11861e12b098dd4ac99397a2ad026596350
-dist/2025-01-08/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=d3a946d098ca9991b4dbdc4ba3b53e37535e62815f76f81bdf7e4562f3534943
-dist/2025-01-08/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=2eed53b995d0ac0c2856c39815ea08f40c074165c3814336af591adcd9f8b571
-dist/2025-01-08/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=3848bae0dfc660d40486ee56589fd0d6ee558f051a14b5efd9d55cd03d10f709
-dist/2025-01-08/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=b40192daf614574f7ef2f7785f6b66d99c0876f3f3cdc30990f8545d41ba0fba
-dist/2025-01-08/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=9e23ebe3062f38791cd23cfa58d9fbd796553bceff7a5a041d3cb78278915c99
-dist/2025-01-08/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=1b47d8f88a4496a8c7604aa2b6b0a2a810266825c385df5e29d313d5635eab6f
-dist/2025-01-08/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=613dba102c8e8aed939ce3f1c43382d3d5d74a1baf911b7f68867ce0abaddbf6
-dist/2025-01-08/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=6afea3865efe25d2675c6e988c09c1fdfc052b27d996f893d9e5fe8a5aee10c3
-dist/2025-01-08/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=285ce1584fca2d0701baffb3228801c88212c20df1a6ee76bcc6e8a392de8739
-dist/2025-01-08/rust-std-beta-armebv7r-none-eabi.tar.gz=8bee2bdb49b1b8781b016b0b1032663e20d135d23b7d9de898e7dee0732a8ce2
-dist/2025-01-08/rust-std-beta-armebv7r-none-eabi.tar.xz=d0e2b1d1a095bb02866048e6286fcf762cffb69f437031ba3e7f330ec1ddaf07
-dist/2025-01-08/rust-std-beta-armebv7r-none-eabihf.tar.gz=c9a13d7fe85291c560786835a0531a407459f07cbfe4b652d9497a581e4bff09
-dist/2025-01-08/rust-std-beta-armebv7r-none-eabihf.tar.xz=be5e9534e88732ca700315d8a4517de3701201d74a0344e962faa9e9c64cf035
-dist/2025-01-08/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=9a48d8e2247f3f70c85e8a5fd39c9f1302d56aa94fbac6b431bff5a4c74f64ad
-dist/2025-01-08/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=5e210bb961e6f73869671298ae1172a3a6f61b1b4ab08baad81e0e32e0a25245
-dist/2025-01-08/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=fc842d5db2778c0f3fff7602e8056795a0c33880a29ba0d29941fec2d2174d8f
-dist/2025-01-08/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=cf473390797976ca153701dcd3ee41a4c2ba314cb180a06ee51e242f5f93047f
-dist/2025-01-08/rust-std-beta-armv7-linux-androideabi.tar.gz=2cf80485cb303b44d48f6555ca33ea25fde6daa7f5fc9e6a2acdc23697c810a2
-dist/2025-01-08/rust-std-beta-armv7-linux-androideabi.tar.xz=625e57d27f5b4bc198598df7b2ae6ac8416951060eda7dd08ef9d319e97b2b9c
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=170d6999f1f9185d48df161023e527826ad72019c37ee11a4e3ad25fa1667e81
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=724bf705fdfd23aa4065ec9128d6d34beaa8285b02f36c2a68d83b1f537c5186
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=21a6727b7bee42a9ed22167600a5c9e8346db3e10133c88a07acca89a3513140
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=f6234d0030296bb13cd8b075a6b2637b5f8c1c9454ff764a168755686fff4b5c
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=09479a598b1fe96eead29bc72f007a130b374b53d06be22282ad94ef7b4e4bce
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=7e67daa06adad6878ea5d3cd9626baf370188fde3e14b2459347665118173c5f
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=92d63ffb8ef0c274ff6138032e0df849b7d10668035ec3a20304ab31bafad495
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=1c2e84999fb5282b6ed7bb31bac0f4c979483696453f3c797dce2e52b7bb848f
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=3a5e0748561fb981acdcfdc2037b12cdfb51d4fd3336172f6be74a78eeaca6b3
-dist/2025-01-08/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=9bd198313fe8e4d0d3b4f999841ad6310884f6a0ba9f1582e072108e38fbda0c
-dist/2025-01-08/rust-std-beta-armv7a-none-eabi.tar.gz=45cdec4bacb8c1cb67e73c26499fa789fffebc981a33472f6b84d8752554e7c9
-dist/2025-01-08/rust-std-beta-armv7a-none-eabi.tar.xz=5222471cb625865c8a2594e88a3adbf529a866164e98f77a315953d5e3494c54
-dist/2025-01-08/rust-std-beta-armv7r-none-eabi.tar.gz=32159e59a8c11c032ab900f77ab7b25827409be390c62bfee8e28d9cd733c13d
-dist/2025-01-08/rust-std-beta-armv7r-none-eabi.tar.xz=45c7ba589c6f092ada1a0acc0a107efb09b3baf0549846919ac3f853b574026e
-dist/2025-01-08/rust-std-beta-armv7r-none-eabihf.tar.gz=4263a0a290f88e9b5c09c6140aaa02fcc7bc455439070f6d4b4d9a38f8424c3f
-dist/2025-01-08/rust-std-beta-armv7r-none-eabihf.tar.xz=a3ff2f3691f7f62f9bb57259eb4e6c2976276fabc46e9ac6a7796ce2fd6ece5c
-dist/2025-01-08/rust-std-beta-i586-pc-windows-msvc.tar.gz=d073f07548e5a2d92e094c69b6a7b59cf91309ebb42e06393c410c95fa90b681
-dist/2025-01-08/rust-std-beta-i586-pc-windows-msvc.tar.xz=e8708e2a341358c14c3259a8c4c05db6eb7baf09050cdab383b44f0b70dea7b7
-dist/2025-01-08/rust-std-beta-i586-unknown-linux-gnu.tar.gz=9072d9bf10db42db4e150b73fddf1085495979a18f59cabd43d73c0f1336e112
-dist/2025-01-08/rust-std-beta-i586-unknown-linux-gnu.tar.xz=e43a369c7954f4645243990291c88dae3b6694e4d2efe7ed4f81b7b8b7c723c8
-dist/2025-01-08/rust-std-beta-i586-unknown-linux-musl.tar.gz=e7de687f826c37e20b64b5e091fc3ea514770d38c45bb39eb6ab5a9730be6d11
-dist/2025-01-08/rust-std-beta-i586-unknown-linux-musl.tar.xz=5ab4c606c30f534fa75351160af4c4dda660955658a0d6864d28d927b9ca07cd
-dist/2025-01-08/rust-std-beta-i686-linux-android.tar.gz=5936848fc7f45feeb797c6a78889762d0b36fe48dd82eb437049be6e8d17ee04
-dist/2025-01-08/rust-std-beta-i686-linux-android.tar.xz=d66a746f476ad27525c9f22136b664c0a98a811450caa083ff8c9def80dd886f
-dist/2025-01-08/rust-std-beta-i686-pc-windows-gnu.tar.gz=d6326c139001357e964fcad7e26b195fb707e8158791fdfbcd16910258438910
-dist/2025-01-08/rust-std-beta-i686-pc-windows-gnu.tar.xz=f455268ea0f33118607adb1a7ebe484a38904e1c698899f4857492633fad219f
-dist/2025-01-08/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=714846d27f13247f37edc266b66eb1792fa1c35d2dd13215800db55ed89cf8c3
-dist/2025-01-08/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=cede0b7977ee57ed24d792749dbfb42240f95a235d93b2e1a7ad4aa03d588da3
-dist/2025-01-08/rust-std-beta-i686-pc-windows-msvc.tar.gz=70fbea3fa87e1aa93668f2462ddf73b05c55883ae9d2bbdd0a3acc9ab51eb961
-dist/2025-01-08/rust-std-beta-i686-pc-windows-msvc.tar.xz=bc13da70c924372a2247d125bdfc850b9551e32ef990ca8dd0c24d282f9c7025
-dist/2025-01-08/rust-std-beta-i686-unknown-freebsd.tar.gz=c4583d916fdf07e7e274b59c32fe661b0c1780b925c4d84d01fccb1262cee70a
-dist/2025-01-08/rust-std-beta-i686-unknown-freebsd.tar.xz=77612c690f5ecbadb1f2d9128f79676bc3b199478cdb619321eb521e4f8777ca
-dist/2025-01-08/rust-std-beta-i686-unknown-linux-gnu.tar.gz=c487e6e164f31a9274a24a1668170db22e64def6412a38a38b6e0c4741523786
-dist/2025-01-08/rust-std-beta-i686-unknown-linux-gnu.tar.xz=cfd25efcec9004d223fb7257a34c0530ff755eb3337fe80468949df185e1adec
-dist/2025-01-08/rust-std-beta-i686-unknown-linux-musl.tar.gz=5e208e822d9d2db30bfa4ca363d29d923c5560ac7d220dfd32898524022aa2c7
-dist/2025-01-08/rust-std-beta-i686-unknown-linux-musl.tar.xz=742f8c4dde07be899de43502af87ea1457a4706078ea7f353914fd31d9b91537
-dist/2025-01-08/rust-std-beta-i686-unknown-uefi.tar.gz=3567303608260def6590e9f0c29ce776ce933f0a9cf4c568faa8713935ee9efc
-dist/2025-01-08/rust-std-beta-i686-unknown-uefi.tar.xz=dbea586494aeec9d2d29c80eb259cb6d66608c93b26f560f2276b490d6946a25
-dist/2025-01-08/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=ecbacd29dc59c59ac513958325ce3a2a2323156562dbf966f529f267fc52ce17
-dist/2025-01-08/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=69c2429bc0bdcb3e4ab9b05af37f65c60b936df6598d375843e63b8141371fe3
-dist/2025-01-08/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=f4f33e673f883a9ac3b0113281c890839498d70d72e5ba51094c851bd6f0d323
-dist/2025-01-08/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=c82917544801fe373b007aae871b4833db428a37d544e09644601d3fde682018
-dist/2025-01-08/rust-std-beta-loongarch64-unknown-none.tar.gz=d3fb635af8745de8a5019bb9bbc3b20b109ed85f7ced6e939836bc0a124a0fbd
-dist/2025-01-08/rust-std-beta-loongarch64-unknown-none.tar.xz=6e7e2d66e1c99507b1b515178d6a200532e1ae7600dc125d26b8ccf52d011399
-dist/2025-01-08/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=0fb8285f64d616d741a32ae07f69dfa96e0d231cb835a839dc42ea76fdf0ea83
-dist/2025-01-08/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=c1c92ca9c3153ea5f42aeec0c3ee7f1042e3e01d6a91784e6baaf201c9621608
-dist/2025-01-08/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=1749eb869811470620cf5e432b5f5dc128c6b8e9f3b9586fc20336c677b863da
-dist/2025-01-08/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=72c7a3c88afab27d0e4b09c313af336e6aff45046fae2becb17235affc1746f6
-dist/2025-01-08/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=36bd0cb97b921cdb915337ec1c7a23609c94c2485f932a1c27fd71804def533d
-dist/2025-01-08/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=45a6098b27a0de50e3c26d540ab4afeac30178bdd389c0a4d829b015cc5726ec
-dist/2025-01-08/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=00352c0a8fba406add478aa1bbf6b6ca99e7c5db302901616bd2cc740a9867b8
-dist/2025-01-08/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=69d7ca4226590875ae59a45b45e7726780dcf4091c9c44c3759931e2b05a42af
-dist/2025-01-08/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=6243b4efcf2435cf586248ebc9b99379e8b86ce5575d8845821a11c21f8946fd
-dist/2025-01-08/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=78898b9d99a25075a8c47e7b78e35b64b891179a8f54d41983370814f33b6eca
-dist/2025-01-08/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=ab293f2e7e3288a4c4842ee510307f18c9df6618702695add978bd1d56be21b1
-dist/2025-01-08/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=57b7c326e4167d01385f9f89d89e81b5b660a7e63e1c17b14b70e8c8e50774dd
-dist/2025-01-08/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=167fca173e6e2974a35be4c8fc5cc9043a3b34d74efba13a86df75d2600576d5
-dist/2025-01-08/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=4197393d32094f65fc781bf39ba95fb36988508f9ab6b41300ebe2ebad838640
-dist/2025-01-08/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=d3d0569bffb348bc580f3e382557939a4a87452a05dcfe1fbca8c8a9888c457d
-dist/2025-01-08/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=c0ad9def2f73a60b674b35b8f53483a0c017ad4e4db3b268b3c10bdbedc13625
-dist/2025-01-08/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=7f41fade9abdf4ee47e96ffcf345fc37231d60a645ce814b19738689018b77cd
-dist/2025-01-08/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=d6f21bf60530c691a6d40d0ba1ebe0ee041bf8a333f489671b1f1fea61950ffc
-dist/2025-01-08/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=0ddc2427ea4e448789b8053f111f7310f6da95d6cff8f644ce1f3ccffeb16f42
-dist/2025-01-08/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=77a2f8531ec6a87ef95ed5690c31d5e1e3cf65a633e0ff885cb0b2cc55a2fab4
-dist/2025-01-08/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=c72a5c97347dbf43c328170cd1ded9363f1f3659732d9497d73bc2a9e3b32de7
-dist/2025-01-08/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=584e99c8fdfd6e186509ad41f67d02ad92cd9d887c2b6159ad8a36334eba7aae
-dist/2025-01-08/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=536f1135a697180ed7674b8d9ac15232eac4d7735cbcc836cc099cd6136c39b2
-dist/2025-01-08/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=dad89574543674fd72dd2a6be4b2753b4e2211238d6208b201903c0645024fa5
-dist/2025-01-08/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=1fb747dc33e3016ec5f0d8161dadef20f0798f7a65967c316f0315826bf7e8d0
-dist/2025-01-08/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=05c57bfecf04cfb5279a3132138c9bf0c6773ea5fa01315bdcc83f0ad06165c5
-dist/2025-01-08/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=83e04e9c3ca61c2aa39a0c37b92d11a8571792244e6c5ebc795c1c3274a9a926
-dist/2025-01-08/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=4c1537651b695764db9ae3c536a605a7a9a1fdf51689350f7fff9638454844d3
-dist/2025-01-08/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=1c3164278134db89dc7cc5d2169402f28757e55c99438cb86a90cbf06f07ef7b
-dist/2025-01-08/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=ddb7ffbad2e308d80b901986f6e00f38ecc59359a9f7d28223c089b01ae86f91
-dist/2025-01-08/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=935d864e0e212ed9f70027fa7f6afe18757e561347c4d8b97221db2936a5afe7
-dist/2025-01-08/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=18cc0e5b000474a60938521e23c5ef057e184616ddb1e2b031db0f8b5d87931b
-dist/2025-01-08/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=e824c24bb3933941658a3a6c981e469c153aefc5bdb153216d90cbe8dc26adf8
-dist/2025-01-08/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=d40178695aff134127268c21a91ae8b4aaedf2d78122a00c844e0c4efe246815
-dist/2025-01-08/rust-std-beta-sparcv9-sun-solaris.tar.gz=c37a91e3c6685a11bc96acb1f7db48c30a45ed19c9a7f303ad4b60bb24228975
-dist/2025-01-08/rust-std-beta-sparcv9-sun-solaris.tar.xz=cf190f95859df6eb65ca3cc07aee95d4f3f8c0770c480ecd8373168cf0bce323
-dist/2025-01-08/rust-std-beta-thumbv6m-none-eabi.tar.gz=b598d8aba2ac570320ae7a1c8b9103f04cd0b81df37500ed838b88874eb7317c
-dist/2025-01-08/rust-std-beta-thumbv6m-none-eabi.tar.xz=ebd4c1ca68d4ca5944a3f0837a8a1018e18dcb31ef8436a4d02c347b251ff0be
-dist/2025-01-08/rust-std-beta-thumbv7em-none-eabi.tar.gz=3d0385fdb184a66a1af91e3db28ea0829b1a498f2431a896aeccf2c900cb9624
-dist/2025-01-08/rust-std-beta-thumbv7em-none-eabi.tar.xz=f778bfbb7033a53c61c3af187ee35e9e7713e9e98a6994f11ed9b589f3459391
-dist/2025-01-08/rust-std-beta-thumbv7em-none-eabihf.tar.gz=0a1669fc57856b2e475a9b8edd7575ad7ab07ad0b95a0ba9fb92e7fb26f81a0b
-dist/2025-01-08/rust-std-beta-thumbv7em-none-eabihf.tar.xz=bb6b245b183061f65e3a5d9e9c1bafc76c3f968ed7d0cbd0e33ff878f5e30804
-dist/2025-01-08/rust-std-beta-thumbv7m-none-eabi.tar.gz=3f459b3a6dbe99fa6bcce86e853096902f23e7e49a1b8c300ef4515796619b28
-dist/2025-01-08/rust-std-beta-thumbv7m-none-eabi.tar.xz=b9ce85bf7cfcb13526c2cbf56aba726919b818168c6f99fb855cf00ef8d0c76c
-dist/2025-01-08/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=366797feb0b31dccd500310903b494682b654800938a79c46e47313accaf622a
-dist/2025-01-08/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=33c50d91b1f23770031a3e1c9b3a78f901b30831bbed8c7f463c29ebb86d5a91
-dist/2025-01-08/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=43acc164b41da62e1aeb7f252f6d81f1f3b79281362348817134760185648071
-dist/2025-01-08/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=c93bc0681027e879719417049e61ddf7f4092d72d103d14994520bccaf6ede19
-dist/2025-01-08/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=0b36bef54f41302c871bfb92f45f248c34bd2450b159c68801eb13373d464e69
-dist/2025-01-08/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=7f9300e17e4786747ca434c1f1a0451aa7c7f933f7952b5010a0e4bf4d9e4198
-dist/2025-01-08/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=ca421607c9f67d0648dc7550781bf90983dca6f17e81153ebcc4ae2f69fe88a5
-dist/2025-01-08/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=0b20c32941914bacc1b0a16b334cd32feed1ff56e6a2551aa0ae6b22c41f4c46
-dist/2025-01-08/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=e792938012865b5c1fcec63bc25a9b72e28889515472cfd83d7d57fd8f84d7c5
-dist/2025-01-08/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=15338fd8f01e0fb422336ba055a4ccf4be3ff8ccdb123ace84e9dc9f1a64e3cc
-dist/2025-01-08/rust-std-beta-wasm32-unknown-emscripten.tar.gz=c57a71f14db1b122dec0ff70a04faf1b8a7a3af948e3ed81b15563b19c376334
-dist/2025-01-08/rust-std-beta-wasm32-unknown-emscripten.tar.xz=dbbd2251d206de84de81abd5b29e4ed1b08c00155141e08a7b6fa35559ac4e65
-dist/2025-01-08/rust-std-beta-wasm32-unknown-unknown.tar.gz=852381932ef65b7ce75f943164ac747bcce3b1d3f6e2c1cd434934c1030f789a
-dist/2025-01-08/rust-std-beta-wasm32-unknown-unknown.tar.xz=cbdf58a9afb016aee98416924578d0a8ece8a6d5a17734606928bedf37719129
-dist/2025-01-08/rust-std-beta-wasm32-wasip1.tar.gz=6dd459e217ea3b4f7f85811eca500c774a36dd849addd9874e4e54e972fc7c7c
-dist/2025-01-08/rust-std-beta-wasm32-wasip1.tar.xz=beca27838a50a2da0341d1bee58faaab18d67a41cd1724d39b30b4f8daf18359
-dist/2025-01-08/rust-std-beta-wasm32-wasip1-threads.tar.gz=8a264acc2656f35e61d4ebf8773dd3b29c0e7748ccaf326898089838128c609d
-dist/2025-01-08/rust-std-beta-wasm32-wasip1-threads.tar.xz=eac3340c629af165b67982326cbff6cd63a2721e41972b70826a9911af902e02
-dist/2025-01-08/rust-std-beta-wasm32-wasip2.tar.gz=ddef01fac3d8b1116b0f2b5f7b4a65a54070e06ccff8fc0429ed8e668d57d4fe
-dist/2025-01-08/rust-std-beta-wasm32-wasip2.tar.xz=6de7754db16d34a556264c6d37ed66480e832aacf2aefe34a7e82636ccd38653
-dist/2025-01-08/rust-std-beta-wasm32v1-none.tar.gz=8f8eef02573a4911630ceb59534bb91a084ecc9d8ba1ccfa6e59370f69af028f
-dist/2025-01-08/rust-std-beta-wasm32v1-none.tar.xz=86bb30d39659171af2120a86668f1803f3c1ca7b2a0f8662fc98a499734f9e17
-dist/2025-01-08/rust-std-beta-x86_64-apple-darwin.tar.gz=b4e018a5dec5b232867770a8d8ce43d670265a51b389c7a1f0f1652a9e2b685e
-dist/2025-01-08/rust-std-beta-x86_64-apple-darwin.tar.xz=b81c60d6b6c5f5fb1eba3037c545452bf7f070eae7b6c23ab3011f50de1f01ce
-dist/2025-01-08/rust-std-beta-x86_64-apple-ios.tar.gz=61a88f5fd29b413ae351db90a43773ad2cc846ef3a03b5747e98bcab7865b988
-dist/2025-01-08/rust-std-beta-x86_64-apple-ios.tar.xz=977ad619301f051e241f898c302bc230ed37dcd6041d925378cba6811a15f41a
-dist/2025-01-08/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=184c6fb1f051685f23a04ee2a57d15b8f1f3d5696b9cee0f8d48b230f108f408
-dist/2025-01-08/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=90715fa792f08da57964abae2b8366337c3372ecb92624783448ee6fc921792e
-dist/2025-01-08/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=13343f16a12d12bf5dea13e240a88e50855a3eaa16d87842e33356611ef6a0dc
-dist/2025-01-08/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=f273923ea18276e3440003bfe6f00479df907dffd18fb80b447c41baae396cb7
-dist/2025-01-08/rust-std-beta-x86_64-linux-android.tar.gz=3c86701e32a065bd9b0529360379b86180724497b5167f776253abba208db741
-dist/2025-01-08/rust-std-beta-x86_64-linux-android.tar.xz=daf93cde1b13402a2e7ef7faa2aa1644cacb2fafb211a28d4e1c7cb96e738372
-dist/2025-01-08/rust-std-beta-x86_64-pc-solaris.tar.gz=5cf8d53338a4c504dfb96dcbef5b2862921624c2c93edc7597478f97ef3f1a24
-dist/2025-01-08/rust-std-beta-x86_64-pc-solaris.tar.xz=a8a4105596906d4b1ac1588c1b301c1843c4ea695219fa6a979205a6b5fb336f
-dist/2025-01-08/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=f9c03150ce779c7a31ccf5fa4e12953af8d182bd7c0415300ea0ddee191a0e47
-dist/2025-01-08/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=fb81f14fc43c8c9e86da1f10dbff6474447029781b716c9ad67068f793f07ba5
-dist/2025-01-08/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=de329a0e32d0f66d50da01875c85ac807b826d2d2efbf971a7b46f89710dd2f7
-dist/2025-01-08/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=ea5ad2523161e086b0b898c8c989fc1b20a26b460f4403eeaa9fde881be58465
-dist/2025-01-08/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=b042f515a81b7151a0930e852fcb23632b74579ddd8be53dc37bf09fa94747f4
-dist/2025-01-08/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=6f850810bcb1ab381e0245ce7d7881d86852d041d679d622dab4f4317aca54db
-dist/2025-01-08/rust-std-beta-x86_64-unknown-freebsd.tar.gz=e415f16fbe3bfd0d9283ee41dc385f3a1a79f33730aba9d04da2acf7ea993617
-dist/2025-01-08/rust-std-beta-x86_64-unknown-freebsd.tar.xz=ce6967397e9dcf20c700957d5ef3a8fbe35795f0b7be1e8f2fc61ebebdd9771d
-dist/2025-01-08/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=6233e4e853dcbfe5dab0b1258fdadeec39f3d343fd99e597956677a949de1945
-dist/2025-01-08/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=228a0ccf377f633b450b6bdaec99f351cc9db41e61d3caeba85f675bc9e07954
-dist/2025-01-08/rust-std-beta-x86_64-unknown-illumos.tar.gz=d729b6e0f6d70104c730e7cb4d4472ce02452acceecabf98e411b2ad0d6cfdfc
-dist/2025-01-08/rust-std-beta-x86_64-unknown-illumos.tar.xz=51dad4bf611ab3bef919a9961f1a4d02f0203c63db501e32ff0810b2a1d81617
-dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=6c859df64c707c7783863a17e2980c2139a98293473363efa6873d6549b52e3f
-dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=f4cce8d15f242168ba0ec7942a1140b1dadcaeebc8c0e7e7bd35ef7f91e4b390
-dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=f7a559f89b5fa340c2974b8c85aad21e48995af01add8e459b82bae890f0b2e5
-dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=73007a7a396864a71003de912ceb847e8684c4c63d45f032da628267aa28cb7f
-dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=7746927bd5283c05717e006d252bba797b48bb9f50b3674587025125e1916ff7
-dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=4d2cc7aaa081dcc0b9fbf09601881023b6749d8b2986a01f82caae0218d2cdc9
-dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=6f2ecafe9003c8fba1f43e1acdd477cf0482e7f97c1687d6255c696bc45cf662
-dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=c82ece042d0980b1707d3871aa35b4b816179c3214e84ca7666e2189e4f062cc
-dist/2025-01-08/rust-std-beta-x86_64-unknown-netbsd.tar.gz=d41dcec02cd3dc2536786aa461256bf5ce1b65174ab6cc532564dbfb6dbb37bb
-dist/2025-01-08/rust-std-beta-x86_64-unknown-netbsd.tar.xz=cfc7dd1eaf1420db8b87d13bd9a857e258c2db4137ce1fab03583b82cff5e3b0
-dist/2025-01-08/rust-std-beta-x86_64-unknown-none.tar.gz=234209f51b8e8637cb2742cd482be0a333e4463869abbd5f00e548f03eb79483
-dist/2025-01-08/rust-std-beta-x86_64-unknown-none.tar.xz=36a5a189997d1c6eb05397007223611fc9777cee6fc495a885e46c2f52f62040
-dist/2025-01-08/rust-std-beta-x86_64-unknown-redox.tar.gz=a8df20db51fd121a970d6dcd24e583ac831c956f37b7e47b1533cba6f4b27dd4
-dist/2025-01-08/rust-std-beta-x86_64-unknown-redox.tar.xz=d1368bfa84bae9366cde19cb201fd13fe09d2c0b53f82cabefa85a78acf423e2
-dist/2025-01-08/rust-std-beta-x86_64-unknown-uefi.tar.gz=625834a177f20b99f706b9b25c60388db6cc42de7dd54a9ae10b16a86f4ab9bd
-dist/2025-01-08/rust-std-beta-x86_64-unknown-uefi.tar.xz=89a95f2c6a11a0788fcb4fb12c7b37dcae62ff682ae8e1d24910f64dcf801be6
-dist/2025-01-08/cargo-beta-aarch64-apple-darwin.tar.gz=be3bbcf4c95c1d30634cdd87efaf0ea57b8199649a9e502245ee3915f93f49c5
-dist/2025-01-08/cargo-beta-aarch64-apple-darwin.tar.xz=74eb6c112313e7bc0104e211397ef998c2713f3c350a0b8995355ea04f4c1df6
-dist/2025-01-08/cargo-beta-aarch64-pc-windows-msvc.tar.gz=089863e43456e8c2613cf63f82172c9b2b220d582d448a88a9301f12aa5471e2
-dist/2025-01-08/cargo-beta-aarch64-pc-windows-msvc.tar.xz=fe604aaf5d859192fa13c78643c072d49b31f1b16fdbb088e2917631aa683431
-dist/2025-01-08/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=f4c710be8d286696c57bce005e43458a5031fec2b706a8e825c498e7b1c9faa1
-dist/2025-01-08/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=18e510f07b0a6b94cc1ec14503c7a2c992ce17c9897c472d9330cf55514ca4c2
-dist/2025-01-08/cargo-beta-aarch64-unknown-linux-musl.tar.gz=b2a4e280c9150683d14ab98770a4bb6f27c74144abcb0d075e81e537cbd2e2d0
-dist/2025-01-08/cargo-beta-aarch64-unknown-linux-musl.tar.xz=096d0926b219a8dbb6952a66ff742936c7307baa236262b2d6ee5238c2b44153
-dist/2025-01-08/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=58eb3f62b876ee4be22ca51720204da9c3734a5a4a5365dedcede0a012a48891
-dist/2025-01-08/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=1ca32ac5479c6d27191c7726b0dad38af34e6423ba8e644461ca30c82382ce06
-dist/2025-01-08/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=45895027f54b7c4f1222196317ac1cc38a84ccf07696a72fb91b2d42218d4281
-dist/2025-01-08/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=f08639a9a86802637b08df47815e2b0e32ce826f76c7187a140f97abf1eaebf5
-dist/2025-01-08/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=63dfd33bb41426e81a8be487580656699502396350cd6c50a3bf32cacf2f5eb6
-dist/2025-01-08/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=1033972fe7345a4cb84d0ba8a479159bdda53d42f581a7087eb517144026e870
-dist/2025-01-08/cargo-beta-i686-pc-windows-gnu.tar.gz=2f00a1e75d995f89ad2b5fd509dcbce97aad2096638cea05d0e9662fe8f21997
-dist/2025-01-08/cargo-beta-i686-pc-windows-gnu.tar.xz=535e4ea02ffcb59ab5c492689aa25aaa7dd026a9db7e5a5e1a674464488e86fb
-dist/2025-01-08/cargo-beta-i686-pc-windows-msvc.tar.gz=e2c01590495c6c2384afb0287104bb9e9d8ba555c100c18c8bfd7f06bb4daf43
-dist/2025-01-08/cargo-beta-i686-pc-windows-msvc.tar.xz=6ace1bb6fb5cc03358433476d31f25076eb8d963d685df9c8dfc389a9caad479
-dist/2025-01-08/cargo-beta-i686-unknown-linux-gnu.tar.gz=a50b87367e59dcc3a1c22101d69cbf45a1485e42b2e12b6211d0f35059698d36
-dist/2025-01-08/cargo-beta-i686-unknown-linux-gnu.tar.xz=76d25cafff7f67abe142ba7183b9e1a1fcc18bbfe6969ea03783fd1cbdc7cd68
-dist/2025-01-08/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=3bd98bbaf3c1f718e4f40aea4dc0ad47e6c33b46b4b169841497b49a582b7caa
-dist/2025-01-08/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=62e384bb07173661c6c1e6ddad3d0fab31a25184966020f70b8492c916cf852b
-dist/2025-01-08/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=6bd1ed4631ae5020d4529fc404ef4cf6bf4a93616fd15e1cad9527277fbe200f
-dist/2025-01-08/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=e27425b6e8f6c5114aedce100068bda25be975d80761d6478c49588c45f3611a
-dist/2025-01-08/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=2b14ae8e9f383d2682292ce26bb5dbe9dab69b450564a5e3f7db3fb93864a21c
-dist/2025-01-08/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=dcb68fdece4a4a365a95c440de9bd360f8c1079f4f15eee3d61a53d83957c7e3
-dist/2025-01-08/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=9e9c94abd8fcdea831451105bc351bd9407f3ab4925226a171cb0d170a4a697b
-dist/2025-01-08/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=4cdd8795488a4c6ffcf9bc446576191dcc364e58dee785bf3ac2e756e3a9d5fa
-dist/2025-01-08/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=4eb0a9d2a1b85326c393250873a4550c8e6617e56df9a2d313aa220ffcb7a9ca
-dist/2025-01-08/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=2cf68732cc6926ae9727f627e64fab12c9fbe8803a640b25697ff6af23dbd8ab
-dist/2025-01-08/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=4f276075cf0ce993ac88728992369d996dcbe4e1f68e5e80e620c0a6b305a484
-dist/2025-01-08/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=5b52acb5500d93fdccc9bdc03e6e91313deff0a2801c2b8a587681239b2a6ecf
-dist/2025-01-08/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=8325fda118d5da0b376c0db751cf2ceeae2dd3021b930e3b55c14e02d0ac438b
-dist/2025-01-08/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=2a764695907dcef6b4259831636d0020e72dde5d213f532b3f04b0bae3615d4f
-dist/2025-01-08/cargo-beta-s390x-unknown-linux-gnu.tar.gz=12045986bfc2c346a914bd0b18d84d3e1c3103d6082b08659aa2508a483e0817
-dist/2025-01-08/cargo-beta-s390x-unknown-linux-gnu.tar.xz=ed09f5e3c37582c4ab42f0b4ef1353ff29182579818be28d8a184b33bec728f2
-dist/2025-01-08/cargo-beta-x86_64-apple-darwin.tar.gz=d026df870421796b76749529fd0a7965d83c2d915fa42599613c7521f92e391f
-dist/2025-01-08/cargo-beta-x86_64-apple-darwin.tar.xz=b2174c6efe4336f76d30f55cf83dd5604b2a4f706a76be1cc57780a45d5fe1dd
-dist/2025-01-08/cargo-beta-x86_64-pc-windows-gnu.tar.gz=7047bc8731c2eb00043f0237a12f5261942a1b6b99d574cbb6db32f2f1930180
-dist/2025-01-08/cargo-beta-x86_64-pc-windows-gnu.tar.xz=578f2d6d433dc249fe923edd0519f3db953c0a9beb8a2f2641e1bdb65863526b
-dist/2025-01-08/cargo-beta-x86_64-pc-windows-msvc.tar.gz=0b4dadaece478e1c0cadbb479bd2acffda3254f2ca3c2529e3b81a0357019239
-dist/2025-01-08/cargo-beta-x86_64-pc-windows-msvc.tar.xz=19dc7572f4ae2a9b46c9017f78c5ff7108e9e293f21a3a52eba03f29dd204f62
-dist/2025-01-08/cargo-beta-x86_64-unknown-freebsd.tar.gz=71672eeeedc18240a33ea8b0ee0ce2ca8fdb020d5701cf4b8d3cc464a0199cdd
-dist/2025-01-08/cargo-beta-x86_64-unknown-freebsd.tar.xz=e853f0e42602ff80f64fe245863ba0a4f50d8197ab4cde56c4bed53f4d7d9cbb
-dist/2025-01-08/cargo-beta-x86_64-unknown-illumos.tar.gz=42c1b82bfbccc05f381376b59c92d453810ea57d85e206b9ad958d0e9faa480d
-dist/2025-01-08/cargo-beta-x86_64-unknown-illumos.tar.xz=b83b7cfb56b087a0dc648eab5f695104a1f220896a2981d2b65f67aa1584838b
-dist/2025-01-08/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=0b87cfd9dd3349b23fdcedad9a0fca316ac59e720c4c8f7b67c44020dcaa9665
-dist/2025-01-08/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=19883a7bde6ed9a4587469f0c7bacb434b9734eb74c4b9c570fd3c217db6a52b
-dist/2025-01-08/cargo-beta-x86_64-unknown-linux-musl.tar.gz=11934bf3879a9c395676b9fb737fc9e6e0b54314e51008875a72a80d8e773a74
-dist/2025-01-08/cargo-beta-x86_64-unknown-linux-musl.tar.xz=2ccf643a305060f2fcd24b957a8f9db28dc6fbe44d1b947007a571cea976d973
-dist/2025-01-08/cargo-beta-x86_64-unknown-netbsd.tar.gz=f9982255fb124e74a79708e9e566fd3713b904919260ea498279cde580c9b899
-dist/2025-01-08/cargo-beta-x86_64-unknown-netbsd.tar.xz=18bd7da3c593a0bdcb14140ce19e5a43d42e041fb897fa4acf12f35e03b2d766
-dist/2025-01-08/clippy-beta-aarch64-apple-darwin.tar.gz=511e0a0b6bf59a8e9ff299a32e46586ced5f13a1ad43c9564921c27b905457c3
-dist/2025-01-08/clippy-beta-aarch64-apple-darwin.tar.xz=dd75a377e5a28aff5eca49c73b0b52a2141f347fbb3d2c164d87122663c60ed7
-dist/2025-01-08/clippy-beta-aarch64-pc-windows-msvc.tar.gz=3097ed66faa8489f2fac32453d2ebeb7bc39d5d58b2fa60d47e5f539a57d3658
-dist/2025-01-08/clippy-beta-aarch64-pc-windows-msvc.tar.xz=dd26d47db7f35a41eb16829b35079d2137eb41a254c810e8a9e6d393a899ed96
-dist/2025-01-08/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=a3bdd2413e3d040a1063113d6ba868ed4ffad157f97f180ce6410dc07d89fec4
-dist/2025-01-08/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=308402abb63ae6e364d4ef014aa9dcf338b86982a25fc0570c4ca0e348b50bbe
-dist/2025-01-08/clippy-beta-aarch64-unknown-linux-musl.tar.gz=07a3f0f0f6eca797d9feb6b3339a7c87ac4063bd4c898cb49d3a61c43b7b8ee6
-dist/2025-01-08/clippy-beta-aarch64-unknown-linux-musl.tar.xz=9b2fbae0ec014d61a3d20e532b526fb92bde03ab154b0ee02cb5aa4071c319cb
-dist/2025-01-08/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=9d6c781e2414d9ba43648fa958b2cee3937fa62d118ffbd7ae11fd71ca797011
-dist/2025-01-08/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=73d6d532acdcd6c64f48d12a24ee4abb6f46c6dbfc3d5c3d593887e98313c1a5
-dist/2025-01-08/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=0d698e42477ce7c068df67b389e8f63f82649e1e2b38324e3c3b8906ee9f056d
-dist/2025-01-08/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=9b94df3a1bcf891595a8263a61e3aa82a66013a5c59e8d8ac7742e033a1ac590
-dist/2025-01-08/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=c010c51bd0665e4fc8a3d0bc27af75d2bd112dc8cbb841252b3d44b3789665f8
-dist/2025-01-08/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=c7f9ecb195ded5ac7a03d353e51c264e5ccb4a3460733b06fdf967d8e3a5f085
-dist/2025-01-08/clippy-beta-i686-pc-windows-gnu.tar.gz=5f4ccf0aaeff0eb0970796ea23aae4590285b42b62b165fe3898649e203f57da
-dist/2025-01-08/clippy-beta-i686-pc-windows-gnu.tar.xz=4400d650806cbdb2a8e8e2d6ed0bd5f90fa46b8f2398f09fed98ef565135635f
-dist/2025-01-08/clippy-beta-i686-pc-windows-msvc.tar.gz=062eb313a72787fe53435c57b8a5b0c16ad2abd0644d8669038090d3572bc94d
-dist/2025-01-08/clippy-beta-i686-pc-windows-msvc.tar.xz=ae493ceb9e334b05345cd94a26b87f317909ee82c02f704c2c3b487f5b28e897
-dist/2025-01-08/clippy-beta-i686-unknown-linux-gnu.tar.gz=0d7ba60792aa6e5cd531362ab92977ae3368b2ca2284174019133c2ed9d495a7
-dist/2025-01-08/clippy-beta-i686-unknown-linux-gnu.tar.xz=ded4113933755736c3248f1b0e26cc42d436eb4c6cbb21745f87a2428eae6ae9
-dist/2025-01-08/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=a4525272c4d46ab120d61855d5e453b92b0fa83623c8c5cdf4384b746ba56925
-dist/2025-01-08/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=5acf5b947a7d7f546cc405975ce5eb1f7e1a86ffaa6ea7c18f5baccbe8e26a7c
-dist/2025-01-08/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=628a86af3590cf6ec46173bfd18790958618e1236d3bb54f6eb92be7f78cbdc5
-dist/2025-01-08/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=970c1e229fe35bbeb251e6e1291618d9da5334c1608685d8d602209bccafb4e8
-dist/2025-01-08/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=25ecca37c54464052f44b79ae061c992f9bb29a671881f5fdc7a8f4e1953e543
-dist/2025-01-08/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=e353972b9c73228c523077137a000d1c265dd24012fd1f3f44cb16ab172561c2
-dist/2025-01-08/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=b6d050a3cde8ff3c94dd072fce770ddf43486c8db37ca2ce2096f427f169cb81
-dist/2025-01-08/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=1728393681aa26afdd9b4c6147b1cd95a43e614cb379fd2f0e38fd68b26cd1fe
-dist/2025-01-08/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=4136945a33e3658464835c0c31a244b953b1bc2614dd38266f650ee8e330d5fc
-dist/2025-01-08/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=e121b45e188df1d540bd3d3d691b0b4043d5d067b52286e3e82c544d1f059a38
-dist/2025-01-08/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=6323723980ac6c17e951272bf5473b0f3735d05f00a469317d0371db9f1b562f
-dist/2025-01-08/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=9f7120352e4b0e147159df5e04c1d1939dfe0e1081a6a0d8915ab75709147079
-dist/2025-01-08/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=32f52736c78922bb47a624365f3bd7a06d28581ef4f1fffcb57575b6de739431
-dist/2025-01-08/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=50c2b4e8c57bd0f4aed56d88e1bfbab2fc8f6c6e6d2aa8cf83dbb36067f2ca69
-dist/2025-01-08/clippy-beta-s390x-unknown-linux-gnu.tar.gz=5c2082cb9fa73e0af8b3384a3caf76c7dccbe7a78f553a5527b3539bbee83c0b
-dist/2025-01-08/clippy-beta-s390x-unknown-linux-gnu.tar.xz=ca8c580219fe697b9dae674edb2a2c6ea6c737ebfc4d2580cb184745625874c0
-dist/2025-01-08/clippy-beta-x86_64-apple-darwin.tar.gz=83ac808792dadc4e5779c0b2185514de339cb61359b185d714713ab366909de4
-dist/2025-01-08/clippy-beta-x86_64-apple-darwin.tar.xz=c6a92d2b255736788cd53cb99b84e20ff135c4e5a7ed9cb2ccc9e5eb37523239
-dist/2025-01-08/clippy-beta-x86_64-pc-windows-gnu.tar.gz=6984f5b15e2f56e12924cb251d99f7b52307b1368c47ddc6ec4d17bbce8959e1
-dist/2025-01-08/clippy-beta-x86_64-pc-windows-gnu.tar.xz=fecd2eb58e8e1c9422e4433f120c3456f9cbd0f216863d9e3d37129bda966f79
-dist/2025-01-08/clippy-beta-x86_64-pc-windows-msvc.tar.gz=674115dee679648c45203b9014ce2aaf3812b3de079fc12aab4ba34aa4d8e8e1
-dist/2025-01-08/clippy-beta-x86_64-pc-windows-msvc.tar.xz=892ca2c9bb499ab0922919d89bba3c176e75570be2f4f2a1ac08608ba490d4cb
-dist/2025-01-08/clippy-beta-x86_64-unknown-freebsd.tar.gz=513b3402e525d1e28c648a640d4506f9456c5c2fb45e2b7bc7f2c325a2d2f920
-dist/2025-01-08/clippy-beta-x86_64-unknown-freebsd.tar.xz=5e5a6c353aa3c8cfaafa694e70b69ed54a8c8dea5ea46412fd191a28be3bd926
-dist/2025-01-08/clippy-beta-x86_64-unknown-illumos.tar.gz=f16841404d8bb2aa1bd530eb6c2850e665c9e90f82eb6968cfcd4063b5ff8d10
-dist/2025-01-08/clippy-beta-x86_64-unknown-illumos.tar.xz=3c23e2df43a58499b4cf3652b2b02b1f68141b417829eb06d44c977c745fc7ff
-dist/2025-01-08/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=43bda68cf861a73c8e9bb461e4c28d3c5315f04900db68168584db4f85e50492
-dist/2025-01-08/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=0d3bac2b017cb529d3fcf81042edae79362842f191a6759441afab41b19cd0eb
-dist/2025-01-08/clippy-beta-x86_64-unknown-linux-musl.tar.gz=af7613a78ea98f2f134a69a32bdc09a103f83d6b1ea2ea3c27ddb3eb74430695
-dist/2025-01-08/clippy-beta-x86_64-unknown-linux-musl.tar.xz=78baca17912ad3cf49214187471ddcca890e787dc9821daf37103ea9f8632c1a
-dist/2025-01-08/clippy-beta-x86_64-unknown-netbsd.tar.gz=f85ce010c7d235358e532b23e85ca8fd287376c311ca9427bd41ca0b3f04510b
-dist/2025-01-08/clippy-beta-x86_64-unknown-netbsd.tar.xz=aacc604a5b53267a8eb936a433eba97ad4a002558836c933548152fc6cf50b0f
-dist/2025-01-08/rustfmt-nightly-aarch64-apple-darwin.tar.gz=1ad6d3a92bfd2398af3f712b8238014b5517c80c54e2334e6bdf5bfec349bf0e
-dist/2025-01-08/rustfmt-nightly-aarch64-apple-darwin.tar.xz=fcee1911fad43cb5689786b9603ca43fe2e6fccc89aec1f63b8afba4df915a71
-dist/2025-01-08/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=3d219a1e888acdccaf75afc7c7820f45eb2161a0c78304f76a28af95c5a53dde
-dist/2025-01-08/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=0b4ea270256e8efb6df7d60473db256455fe7d5de835f164bdd0a92c3cea7369
-dist/2025-01-08/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=a7edc1692f4a5975fa5877e1af63c8e9c0a2d0946086413678973990fda8ee50
-dist/2025-01-08/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=bd4b98f560d00da97f2e7899ca32729581f9c5a386f398cf477c1ba6c922029e
-dist/2025-01-08/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=49387f42c45fcb21d55e056843ec3ea210c89b10722adfd2ad6ee5d4a929f7c8
-dist/2025-01-08/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=778b995192beced6c690d80103c719e4b30c16b5e3caa2e2586693baac7ead18
-dist/2025-01-08/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=906191d5b2ca8e7645d6ff8571419aa8b50ca62fe10a1934722f1a493230da83
-dist/2025-01-08/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=6944b61661c3b1f72ec86a80b222bdc0a20e88a4e2a2f342bbb7ae2f8a1e1a6b
-dist/2025-01-08/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=e7fd3ba048b6d20956f6a76b6e859204bb9847bbc1305482426bb40f5b28ad36
-dist/2025-01-08/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=312042e89eb0007fccdc5effa6098a762b94ff3a15840dee0fe681486b0ebda6
-dist/2025-01-08/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=584de19a62f85c418d01bc7943f0e3793f4c79776b8aeb5a7993cd1e7141bd7f
-dist/2025-01-08/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=43327de3051396e27793390468003d1f13da0f0ed1cb7d5224ededf2787fefe8
-dist/2025-01-08/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=bbb72a900c77cebec9cae4b2c6fd0e3bce3451bb2fb65fabfb9f042a55163f78
-dist/2025-01-08/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=fbf8acb567141328ca628bd3c81af9477eb177bb398be3feef55d57acde2af5b
-dist/2025-01-08/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=4a80751fdd514a71d20d440260a86510c83cadbeac3bf03014ef5377c6530e10
-dist/2025-01-08/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=fa3d56f5ec9f88448a2b6c36809b6c21bacb2cec7350571d386320aae2b410e5
-dist/2025-01-08/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=0f11501ddf7be92b987404df21fb4ed83ec8893d887943d86031709e7d671900
-dist/2025-01-08/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=264accec3e4ff18a3f21508bdc22988c86c0c899be83ed491f7f45f4d8d1f76e
-dist/2025-01-08/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=a32c70abfec103c12119a5adceb83eae81b7fc950733e6039e0b3d3a589d16c5
-dist/2025-01-08/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=b0ed3c98ee0cabe8e85d031539796f0ff3e6fb3ed90275242d6fe9f55900abed
-dist/2025-01-08/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=b4f8456e420eea3025f32303cda5de26c67d061e04fb2229a247411ac7dd8351
-dist/2025-01-08/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=e66969acdf2d98ffd854f19e7d9f8beee8ec8fe7ed4493bd308b2f9b44cd9c90
-dist/2025-01-08/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=f97621947a0a90815867d7a0a08722f87cab26584a4b61dca7d81e50336b16cd
-dist/2025-01-08/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=9af1743797ac19982892046c5d4d1865c0fa1e7cc0a38ef43f2364e215a2b5ad
-dist/2025-01-08/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=fdf25dcd2c911c4fc6fbb3a184d078e36cd908a6a7b135c2a48a6f6efabcfd78
-dist/2025-01-08/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=6df2621585eb4d0c5be9b3118034b70dc12e3ac999a47e843b9b2c8ca48629c8
-dist/2025-01-08/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=bd6c79723c219e2c2b56bea90e3c2808bdf2119d299fb84d11d021895292d464
-dist/2025-01-08/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=4e1f249176e480b12ea11bb49377cda875189f382086339ed3ce591e3c7576e1
-dist/2025-01-08/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=36877f682d6c43aaa755b5edb5599e9ee8f48969e93532f458f516ac052dd47b
-dist/2025-01-08/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=ef36ffefbe132c56c3a993ba4f8b9048f65ac87f3f22e9471064d3fa7c0e9bbd
-dist/2025-01-08/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=2d9a0f3c007b59fb107c859ee4eab0ceadfe4c220ba45bc8c8f4bf5cb2608ba7
-dist/2025-01-08/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=f09cde2c36a4b9791f1492b0319ef1444418b2162215d48d18a6eb7493dd275a
-dist/2025-01-08/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=585ef59a9fcb414ddec4fb69a6c33548a38b62c87be3c707443954c7be9eb764
-dist/2025-01-08/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=4da9c4095b0e30d61c9617a5cbfd69ebc77d54f248dfa3c2f9c096383184a762
-dist/2025-01-08/rustfmt-nightly-x86_64-apple-darwin.tar.gz=28ed0f8745b5b68527ca735a794b11a1411574cb0756b74b7e5ad1f0652f1670
-dist/2025-01-08/rustfmt-nightly-x86_64-apple-darwin.tar.xz=6b3c264c1e1002c381bc952ae5f24f56f7bd623067ef0f0179677798539d0aa9
-dist/2025-01-08/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=46b9ee6fe5c5bc6ec504b62fd9356cf467ea001cea073056fd8b53265b424940
-dist/2025-01-08/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=d888eaa7a4b42b4761cba736c75c29d047e31d6d3918c3d64e8347236918f035
-dist/2025-01-08/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=3b04474137945edf639d267a67712166c07df4c018276dfabbd7ad714c952750
-dist/2025-01-08/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=f5268dc4d20eb86ae882c5faffdc1b6dfee52ab4487569a02f92e2e001a936ba
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=6fe48737c200f3ab1ebea3b5089403ad76a8dad4754cbdfa274c89dbf9b0ea45
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=04f1a8d21dc54470df735f6b1f09e9d6e26c106d4ae4405962aaed11da80bea6
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=0dfa280e767a16665aad2bb6051b88a84850ccc408a24d99b89bf8d659149833
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=601215d564ed36cdd9be9abfc3ba42bbc15fc75d306e0921b36083a293067980
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=ce5f4421a454ac2e5f8e53d0ab6050be45f73a3931b9e60240b13f7bf06800ee
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=7cda6e670d0718d13b89225f58df1c6a2473e6d2626144354c854d671c778ba2
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=26e3275bab7d39c465bab76074dd54f534980c89f5460838da9745c171859604
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=b33178fff841b91968c2f6fc108389a1740d865214729406de40b49e6969d22f
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=cc8439ce6628f864503c7ca322ec0607000536c002895dc872ad1bca8e865119
-dist/2025-01-08/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=2d3c2f666bf57384e11f12dcb00346f73953ca8a2a60947ae5c0b14b856b9170
-dist/2025-01-08/rustc-nightly-aarch64-apple-darwin.tar.gz=febc42bc953bf6b23253670756fb294545a1db22b02fbe2273e1030a78f0dc8a
-dist/2025-01-08/rustc-nightly-aarch64-apple-darwin.tar.xz=f978d9d9e0bcc75efd4250406b796fb3f6cae31ec41ca2a40f88f7e70201171c
-dist/2025-01-08/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=6dfd42938c385aba18ba477e4430dd89e9b780d9217f410f68094d7bbbc722a3
-dist/2025-01-08/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=d79b6f6158a99ea82314a99a68c52c63deb16d777d74426780df06c5110576a5
-dist/2025-01-08/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=5dfaa19982b344ba8d3f59418a847a764eb8b6b4a9809b8a63aeafd4725cb406
-dist/2025-01-08/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=dbe770d4594c9f8cd27aec8d342fd5f6bb44570723228726cbf19424dc0d7708
-dist/2025-01-08/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=41357e54d974f3dfe0e71cac0eedc69625ddf7e2a1cf563c2e9689afa53cef11
-dist/2025-01-08/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=208ffbee7b68121ddc0cb92dc1ab73dc3b489869ab190abd99174026724a3493
-dist/2025-01-08/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=7970e126f177ea336cc243448d034c8ad1aa6489db36ea0bde54e2df472552df
-dist/2025-01-08/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=8333efc4f3bf9d6fb01a947a6f631f03fd506a494060e426ee7621831dfc3a95
-dist/2025-01-08/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=f8b9030db15e6004647772700a7b137fe9e7ff1c24fa0742c45a25d072e1f1e4
-dist/2025-01-08/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=f554b976502cdc78735def853947d9b48ab1ff1aca208cb348efdedae0df407d
-dist/2025-01-08/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=402109bd4811e723999c8747978452e2a96e2ddf1109393302f9c1be7e36348e
-dist/2025-01-08/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=b2dd7f94bbc34b91fd2dc2c1bab7179a51265bc51ac58b66c8aedbe849103749
-dist/2025-01-08/rustc-nightly-i686-pc-windows-gnu.tar.gz=9e3f1aa453de7bfd9a15f1925d96b46ce6375b49c6656db14bd2ed99f4138e1c
-dist/2025-01-08/rustc-nightly-i686-pc-windows-gnu.tar.xz=468a157752c69bb2096ffe91413086d04eef8c64b9cdc44b51d7e9a94d2f4b5e
-dist/2025-01-08/rustc-nightly-i686-pc-windows-msvc.tar.gz=1a9977db5843941c49c808830364e32c7e57190d3bf4dcf74e2a109473f808c0
-dist/2025-01-08/rustc-nightly-i686-pc-windows-msvc.tar.xz=7cc68c40929538b7711f5bccfa964841094eed9859f490846de0db0b2ba74343
-dist/2025-01-08/rustc-nightly-i686-unknown-linux-gnu.tar.gz=08c86c8984b966d3943de2252318aad2a27899fb58c5eb1079b8b8164b56d21f
-dist/2025-01-08/rustc-nightly-i686-unknown-linux-gnu.tar.xz=d3b53723f085887709951dae7b0389b8cd4159a22fc7189bf7d7bc15ecb4bc57
-dist/2025-01-08/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=515db325eb12b211d08367436fd07f5ceff4743930b9e685b0b13b94b99bfa34
-dist/2025-01-08/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=b4986e7aca0325059689f8d7ead67616b2965922e77da33d9d03a7235520b585
-dist/2025-01-08/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=541571e5deb51d360eeaf2c88a28cc25c98dead983a3b8f2a6e3f371df3ce0cb
-dist/2025-01-08/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=44fa8d77bf945b1a5ea9ed2a7e8228c8c0d5770098bbd8687173dff58b7005a1
-dist/2025-01-08/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=1ecae3935e253cc9b7aa44c8e7835fdf039d44ae19080e2316421b47453e3527
-dist/2025-01-08/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=b512b895e9b78069e57fce8c1982ea6fb8e463fbfe626474a6399008d5c149cf
-dist/2025-01-08/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=91c4ddebe0b50e8778297793d77a583b23b6c333d785564b97ea38a137c3b7df
-dist/2025-01-08/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=562f81acf112aefc6878132d7cf352da64b0eb1803d8c371e6713e270bea15bc
-dist/2025-01-08/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=147bcd50f63f068a5814200ffeb8adc775c65187fb9c178dae5468af3fc04611
-dist/2025-01-08/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=9b6e863729599a96547119c1c2a04f23167cb142447644b88ccaa86d073e1471
-dist/2025-01-08/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=85c085bf2771eb79dd3aca31ff9896de969de229c0549bd8c89a539393ef5cab
-dist/2025-01-08/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=107bba3499f4446aec6d79919453341a0d10fa5e6001da4cc9d3f1a618871989
-dist/2025-01-08/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=ca6663608404909610479a33562049d313882ab8252fd302657598b0251746ad
-dist/2025-01-08/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=f66d3d9a1d897346945b254aed29e29b82be1255908dd0accc7deebd698a0b78
-dist/2025-01-08/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=480fdbaad5a5e9d6412682c61de324ac37093f60377e5f772c59dab58e63e6a2
-dist/2025-01-08/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=c438d14d90ed5acfa2108788b7179aebd7fcbac10703b2c5207ed7eaf988ddeb
-dist/2025-01-08/rustc-nightly-x86_64-apple-darwin.tar.gz=b91f15c087c859b8ea6a5d556835c296ff480f6927efa9e535b9dcd726c8c4de
-dist/2025-01-08/rustc-nightly-x86_64-apple-darwin.tar.xz=64b1129ba56b964ad433a499b2b5dd590371a4a7fa0f859c551bced786d876f4
-dist/2025-01-08/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=c90d259076abbb62f26348a2bfaf5bc1dca1e6ba7d4c1dec8f02d9dfaa21cc53
-dist/2025-01-08/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=127c2335d668cb93169681ec3775e0c9a91e0c5e1dd6043bd9236e18b7dedbf1
-dist/2025-01-08/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=a0dd89c80a4c2c724a8910c33c6d5159beef9b462f912326c659defb87ebe41e
-dist/2025-01-08/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=b2c1972028521d6cd643a7a1f4db2eca1da5eb8ea03187bab5a7bef63377eec4
-dist/2025-01-08/rustc-nightly-x86_64-unknown-freebsd.tar.gz=3eb87ac0585b6a4a3cd0525e3f7fc04eafcb28b64ddb866beedbf24401810bf6
-dist/2025-01-08/rustc-nightly-x86_64-unknown-freebsd.tar.xz=fa93c78e53bc3e408c1b6d7917e643fb7f1f6203ec4a44036e8b73d37e650b82
-dist/2025-01-08/rustc-nightly-x86_64-unknown-illumos.tar.gz=3017ba6134aaf6cae0b7980ef211420ae1c09d230fc082e9f68a5a1a7335aad2
-dist/2025-01-08/rustc-nightly-x86_64-unknown-illumos.tar.xz=5a5881f7883eeb638c00ccc7a4cf453ddb987983228b066ec955b92d4e4855a7
-dist/2025-01-08/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=9c7796ef52678a29ea7e0406c1f2273ee11d907b379b3616237df9a05505140e
-dist/2025-01-08/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=0c978e79f9794221ebd7c0fc0d4313e323d1aef1a5358ffc9cb806fcd997e4ef
-dist/2025-01-08/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=21ff96c7b7c0a5a18051c12f01b67e90fef620c887f7d91e78944b5a1a0e8838
-dist/2025-01-08/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=2b7ffa8d546ed9b89472fd25ac56b4f6e968e99bfae9045a4019fab319716cf4
-dist/2025-01-08/rustc-nightly-x86_64-unknown-netbsd.tar.gz=ea30e5cef50b7b207844bc30ceaee4bcd30cde86f636080b243eb3e7e5367042
-dist/2025-01-08/rustc-nightly-x86_64-unknown-netbsd.tar.xz=c07dc61336037f475cb74945c0925fabd1fb33412eb4e6eba4004f207db67f3e
\ No newline at end of file
+dist/2025-02-08/rustc-beta-aarch64-apple-darwin.tar.gz=ca5440402ebfd3ba7ce3b30ecbcdc3e9341861996a5dd51601de3131d62d0bc2
+dist/2025-02-08/rustc-beta-aarch64-apple-darwin.tar.xz=bb7c79e5adb6998ac3a57ae7434a247029777bf3e1687c51ff3fdca938b72b3d
+dist/2025-02-08/rustc-beta-aarch64-pc-windows-msvc.tar.gz=596a586332d87beaf3d52fead6e6c286a1da6abc89b53da5f6874f5da134cded
+dist/2025-02-08/rustc-beta-aarch64-pc-windows-msvc.tar.xz=6828f88d3d576cdea838d975e0dc61ae2daf32746d7dbefce07f12684f5c0d97
+dist/2025-02-08/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=86943f595d3ad4b4ee5b7c9db63df9addf9c5e50e25267f64daa504dc4bb63b6
+dist/2025-02-08/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=13449944b13c4a8ef9aae649e1edf0bfbedc9816f7f32445ce9623098a21e51d
+dist/2025-02-08/rustc-beta-aarch64-unknown-linux-musl.tar.gz=ce7fc3bed538a938f11b1cc15da20dc7d68097cf7d68a37ecc969c225bf5dcaf
+dist/2025-02-08/rustc-beta-aarch64-unknown-linux-musl.tar.xz=a3b77720f7ff2a4707ecf44cab11ef088c3903ed6e123de14237b2149858f1a0
+dist/2025-02-08/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=a9f02a5eb65c85f98b73dfd88ef4eb48e6782455b3ccb77032b2df5bbfa39e84
+dist/2025-02-08/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=93c5ad3bcb8473a7ec0dcc81b788436c9881c9d9c276906dc09bada56b45180c
+dist/2025-02-08/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=90f46141b9590ad69f60ffabdceb262e0940081994bda97a74692b76fd5cf8c0
+dist/2025-02-08/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=364a0b19dd91fe47c7152bd5a495d5ebf10170e4e5896859b02aef81225fc72e
+dist/2025-02-08/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=977901c4eaf17b2acc8f7b7dd4e2efe5c45b45f5763f94b2ca36beadcc1544fc
+dist/2025-02-08/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=4f60ec3e8a48c97a98567338be479499dbfb48db328d3d208763a8e6ad36e80d
+dist/2025-02-08/rustc-beta-i686-pc-windows-gnu.tar.gz=ab1f6cf30ac8abf6dd130144355b79510633b24b06b416d82ba1fbccd318c2e5
+dist/2025-02-08/rustc-beta-i686-pc-windows-gnu.tar.xz=68327052940d99080217450553c42f3df81507385b5b90734c9b41a57e601ec6
+dist/2025-02-08/rustc-beta-i686-pc-windows-msvc.tar.gz=479053067ce64241d06a09d88b23cfb3da6dbcff46b5e8e33c2c1797ecdefb19
+dist/2025-02-08/rustc-beta-i686-pc-windows-msvc.tar.xz=12a4286b430fdd49e8806aa98a4395fc2ded6eae5ca254fb2cddc2c6db2cd893
+dist/2025-02-08/rustc-beta-i686-unknown-linux-gnu.tar.gz=865d88d2a9bb177851e901a56c5b3a295aa4ecdec8f73c72d4f9914b2e4aac60
+dist/2025-02-08/rustc-beta-i686-unknown-linux-gnu.tar.xz=3f17f91cd666e59efd5a47c2db28af8eee0d89d4ebbc6263f005e1d8d7d5b839
+dist/2025-02-08/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=a1c42bc975d9ccd10771aa83874d0ea382780a8a925016d966d50084fb45c267
+dist/2025-02-08/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=5452b62e9cccb5dac1cd36b01d31b11ac97c85bf4f82a559a15a08c278061d78
+dist/2025-02-08/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=eb9d9ac867835710ef4dd301aed0afbfeb4221c818ef4d7f70f4bb2b5bc02790
+dist/2025-02-08/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=0afbff667ada4671511c48d6c5558009f395f3c2f3ad3d10c716882f6c9860f6
+dist/2025-02-08/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=db77ef515643b4ced71ab9ffce80338fe99b03abd6b7672f627f38e33e6642d9
+dist/2025-02-08/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=cac3b683fb606be111d5788b1a4194ec0ea77e0226350454cb7d1904d6f2f78e
+dist/2025-02-08/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=a86bb2a0cd6f2c25f6f6c55b070a3f841c0a006588f759d0aa7c8d6b3401d904
+dist/2025-02-08/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=050e07098291a659baa3fb31e2a83c7e6e203614139dab3f3eb2c486c20b9f8b
+dist/2025-02-08/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=c20d1b649bb28b8abba4a5dd8e881a03061ebe091e5cdbc44310706fc76b55b0
+dist/2025-02-08/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=24c742968242e5bb3d81b865c0fdfdb021772a40fe4d25f3b83fdcf8ccb087bd
+dist/2025-02-08/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=2aa9e78148c44ae2c01f554449811993e592aa9c428de37fbdb42dead53eb60c
+dist/2025-02-08/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=2e6751dacf4ce4a60c61e1fa8afb746ac38285c62e567df78f2de27ce25e5770
+dist/2025-02-08/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=d0d365fdba806bda1263767d40365da7b5c2e5d01cfe6e9e4c5a2fd66ad4608a
+dist/2025-02-08/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=fef429294c81caa19fc0dac00eda00d55c087e94c7235e032b17c2b4f5556850
+dist/2025-02-08/rustc-beta-s390x-unknown-linux-gnu.tar.gz=75ea2ad9e2377d09c9517a932126f876eaf377ff0f38a382187bb4a8c31be34e
+dist/2025-02-08/rustc-beta-s390x-unknown-linux-gnu.tar.xz=908e6fff603ef6d0721efc24e8faf014f5cafa71fc0220da4dac5c870b974c04
+dist/2025-02-08/rustc-beta-x86_64-apple-darwin.tar.gz=ccea051b3787d3682258edcfa6a35f2d7a44ac5c3d8117fcd55cc0a97e7b9b92
+dist/2025-02-08/rustc-beta-x86_64-apple-darwin.tar.xz=3555ff1e179da6a249861086c8986039ab7dcdcf581beb1f27246f987da436f6
+dist/2025-02-08/rustc-beta-x86_64-pc-windows-gnu.tar.gz=227da932cd028d2c2415f4df4c14daf225e2a917a0879e1debcee2b8ebbfc790
+dist/2025-02-08/rustc-beta-x86_64-pc-windows-gnu.tar.xz=231c0fb2989746424f8ad394e9015ef13a6b991a50f62009e7bca3e010e9320e
+dist/2025-02-08/rustc-beta-x86_64-pc-windows-msvc.tar.gz=b75be89ce511758f7b9ab6b5701155349e5675e4b85975c33a91483d78666927
+dist/2025-02-08/rustc-beta-x86_64-pc-windows-msvc.tar.xz=bf529ca4409fefe3d38e2b0ee6b3102e9f8b7ace4352bea7e6d3148a84e98767
+dist/2025-02-08/rustc-beta-x86_64-unknown-freebsd.tar.gz=e2dcaf33887031f8d169ab734f3b3eb6858e5247097e46293c11ba1a2887a919
+dist/2025-02-08/rustc-beta-x86_64-unknown-freebsd.tar.xz=2cf5c49c04e57bcc34ada76ff22dd149c4d643b5af5766267663f2e0e4031d17
+dist/2025-02-08/rustc-beta-x86_64-unknown-illumos.tar.gz=c7572379985941a513b7b9e750043a74097655600cb34cb0460a34a5587b7e0d
+dist/2025-02-08/rustc-beta-x86_64-unknown-illumos.tar.xz=4e98bbcbae02618c3f95a21fdb22b4e067ce0bacd8370076a1bf8107964d2896
+dist/2025-02-08/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=bcc22d77b53b54bcb95a5b92b19af7cf5d3e4b4418c3c9ed1d5ab9db3cd6c3a0
+dist/2025-02-08/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=8f3eb1b74e06bbdbf1d09e5df205677db6f6ff78e94f80fc1fd1441deed86f80
+dist/2025-02-08/rustc-beta-x86_64-unknown-linux-musl.tar.gz=ccd5ba2c7c7d8c8eeaae2f7c7b462945d7c7ac552d6175dd33c0b77ee3d6730b
+dist/2025-02-08/rustc-beta-x86_64-unknown-linux-musl.tar.xz=ab198284a035b8b5ef584a925b5f7ef08228d1eeb43b17a33dab8c7ae93cbc96
+dist/2025-02-08/rustc-beta-x86_64-unknown-netbsd.tar.gz=5b52a1e3f591e6f65ac50d885cfa38e2bb655abc3db7f09ea860450b4b95d6e0
+dist/2025-02-08/rustc-beta-x86_64-unknown-netbsd.tar.xz=fad94b63a75e789df1e5d25e0bf44d1fc29146dea862006d5b1ffb5c20fdfc8d
+dist/2025-02-08/rust-std-beta-aarch64-apple-darwin.tar.gz=19c355276bb12522f3c8e94e843e6e54434c66c4e2e49bf68e084d43e1c83350
+dist/2025-02-08/rust-std-beta-aarch64-apple-darwin.tar.xz=c05a1e3e86e2846c4322df02f9b02a1bf16edbf39d3394da56e1a8b3b36d9a60
+dist/2025-02-08/rust-std-beta-aarch64-apple-ios.tar.gz=ade5b194bd6b7737f505d201f6560ec3aeb41345ea692b2d262317fe0a3bfc38
+dist/2025-02-08/rust-std-beta-aarch64-apple-ios.tar.xz=026a233fab1b27e70dd1455a9a9a0f097d0617b720f82549a413bc4b2d9a2755
+dist/2025-02-08/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=fe743c3895565a7e641b8727a0e96172e0a735bb77f9ced18e201f54d5bab19e
+dist/2025-02-08/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=66fd5b769ae7f0e4dd587fdf81ac31cb780cd20eadd082ef0252d7346354bfdb
+dist/2025-02-08/rust-std-beta-aarch64-apple-ios-sim.tar.gz=ccc55643bde9f89be185b560e44d379ef85a0cc7f087f2f2bf7738d523b7a32d
+dist/2025-02-08/rust-std-beta-aarch64-apple-ios-sim.tar.xz=b1d4c3de214fa207e987742ab73d316537ad9856eb3499d046f6aea4e9d3bc0c
+dist/2025-02-08/rust-std-beta-aarch64-linux-android.tar.gz=b17466c9da602c1c282826bdd878e6ba4592906f74b0e8bbe3df302c2358ede4
+dist/2025-02-08/rust-std-beta-aarch64-linux-android.tar.xz=4addf9a4ed3ae4c80b097027fef7237261d2e9ada641e549cc91595c83614d6e
+dist/2025-02-08/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=391f0b460feb164d29ed222b322380586743b19ab03c217690e8053e22903d3e
+dist/2025-02-08/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=d81567dc4e204f7080854d0a3a7e7e16424758ff122dfc14448fa9da630932aa
+dist/2025-02-08/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=91ff95f6a56ee5db99e72b293ea2048be0fd5ac3788bd32d9fc97337e7ee8b68
+dist/2025-02-08/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=d6eb64cdaa12fcc469687f99d03a30329847e89bf802361bb6acd61f65b0547e
+dist/2025-02-08/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=c9f43315d352ecddbc18a9034723c58d5d8ec77fffa9e0e82322743d162e3db7
+dist/2025-02-08/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=2356a2902f91323d1492ef12fa2f17d1e4934748cec03d6621d6ecfe272f1c3e
+dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=ccc8c1777dc8d2e04d4d0640ece7b7820a8fea60a0fe371efcaa055972dcd7b3
+dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=4208ef48af14c5feee97c16fe7e894777a479492760dc0eb838febf2eb92ece7
+dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=b67e319c5e447e9ebf4b9a7e51800e7d7aec3564f0829fa23df953d8ee714131
+dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=432ea33a49f0010125c960d7b93b585e7b4c91b34f9d07989cf1664bf7e71fe5
+dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=53bbbc52c4f99733c7b4a1038fa014867c0d6ca8f1d7eccba651fab4f794247e
+dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=6df101f4d5416cba695be66b975a4e4dcab2a3041d079f0a454f342a6d24d7db
+dist/2025-02-08/rust-std-beta-aarch64-unknown-none.tar.gz=f1ef3141ac9c634e7e6686cf3c13b83323eb168a249f596b1490f874372c1423
+dist/2025-02-08/rust-std-beta-aarch64-unknown-none.tar.xz=a709c52f479c73ed15709b3cb0b8e7641606cf86375a4c9a60b1c9d381c70183
+dist/2025-02-08/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=31b8fec1cd20dd1809bdf733209288d60de0f096fbd0cc2955982ce119703772
+dist/2025-02-08/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=afb3872ffa8ab3c79d08f713aeb76c658ea00a3b9d79d5516d89aa78ec1eab8e
+dist/2025-02-08/rust-std-beta-aarch64-unknown-uefi.tar.gz=d73b90fa9d3a330274b2004ec535d396f90a82ac5b10fb8688f82472bd2c5ac1
+dist/2025-02-08/rust-std-beta-aarch64-unknown-uefi.tar.xz=ae05fa6bf0638b0e26fcb8bcac5973835aa965a56507588fa3d43981f20eee89
+dist/2025-02-08/rust-std-beta-arm-linux-androideabi.tar.gz=c18354734b678f0665dd60bb8765df00bca5d3fb7bb6e6a4b83e3cde971c26cf
+dist/2025-02-08/rust-std-beta-arm-linux-androideabi.tar.xz=5f6bc44bbe3b24140fecad715cc5528249906bacf98fc3a0618a9c0cc92913e0
+dist/2025-02-08/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=d9a2ab83df4240431479fe27600ab1098333699e14103b8a627dc09a3dad6976
+dist/2025-02-08/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=4f95a441ff45c16fb8aa37432cffeef60f2e0711c9cb1015cf440f4da51d5425
+dist/2025-02-08/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=dacdeceea6625041f75c3f2fad4382d2c957b9511666987695fed8e3a2216c88
+dist/2025-02-08/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=e338c1d2cef57e4c4ef613e6b080371751b874f94a246ab32e872a008e9166ab
+dist/2025-02-08/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=8bd4174934e5d0e4dd8e757db494a238c95024be5336e6062923b479c0275b6a
+dist/2025-02-08/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=1637b8d23bc8052803d785f15031a75594860f2263808c9dee68dead29bcd37e
+dist/2025-02-08/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=db6eb6a2af3395e1eee0060d0c022c74c0741c765009f081c0646d696bd0b873
+dist/2025-02-08/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=ca21a4af4de66abf9d31ae6b3fbc33df152656feef7a269bf7d039d2766176ee
+dist/2025-02-08/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=118c52dfa7142c0ee281b126da5b043b2357b78e7e110000f490b20e6a1e7eed
+dist/2025-02-08/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=558fbb7453a2e633630ed33ad150dce87fa515b5b443ae66c5f85ee27e0e771f
+dist/2025-02-08/rust-std-beta-armebv7r-none-eabi.tar.gz=96ff6441b0577b25b83540dc803d692d3444bcd0b4f6128a7743970726facce9
+dist/2025-02-08/rust-std-beta-armebv7r-none-eabi.tar.xz=2621a9f82f73a3a2a2a0c6a7446549c5ad29a430a3e0b961909fe68da21b8491
+dist/2025-02-08/rust-std-beta-armebv7r-none-eabihf.tar.gz=0ef78d66dea96d1a6565fb3469bdcb3368f9e61a55a59a5d2508c54c091484e9
+dist/2025-02-08/rust-std-beta-armebv7r-none-eabihf.tar.xz=1c586301ae2a20ed1caaf0d62d985f9fd95bf2b937ebe7b6d738ca5812713722
+dist/2025-02-08/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=aaeb690b0a08e8f6546ac5608fade5852bb029db9189d6d036c69c4895c6ce32
+dist/2025-02-08/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=1d6ae672d5ebcd302a654c4347a386fabc3bf53aec9664cdf76b9c5a061d4eb1
+dist/2025-02-08/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=5557c7444e72eb29c904436f0221cb40c3156c5289c39b7e8c1a057dfd56c394
+dist/2025-02-08/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=ae9abe3580b1751854305200bd6a5dbf98aeef396e163534ac5521d04d7bfa7c
+dist/2025-02-08/rust-std-beta-armv7-linux-androideabi.tar.gz=c466403dfb8e15cd674859fad24e2e0dd1ba100946c662a9bf29f2440f02a938
+dist/2025-02-08/rust-std-beta-armv7-linux-androideabi.tar.xz=83ad7b8237ae7ab0ddd6f43b604b27677ec9e83453f3127c356936af12140ee2
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=12489ebd742dd611937c2942c6f897608d1c4acb0fcb103a2a18f70b9b2d0596
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=54231b6c641736b29317682be9d1de9463e23478a892c16e083bc1bf20c9c925
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=e41b6582cc6eb2340208a3473d54d441e13fab87bfee3091a513da4039c224c6
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=9ca2df0ba2afd630a94a3bac08f8c412fdb6f905333c8978ac9b6bb5be777774
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=dd9f6f6d930d18dc5e1764691acd2e33cdd032ef757d534ea70202fcdc18e461
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=9d0e4864ecb7e33b231dedd10b54ad7707d79c61ff455256fd693a46a4ecddb5
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=b508af76bcabed45442fc1587ea1c74bbbf85d75fbd2fb64d7078cd799485ae6
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=3f9916a37ac0b79586756f09986516ba08e1c24b4d4675bd17d66058e42494cd
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=a80bdd0178f0b9c98c2fe80e59a1b936115a509d9b1be0202bea09d275b4c5d0
+dist/2025-02-08/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=6cb0340d4633e52f7a6f3419a0f18a9d0b75f604fbfe99ce5886186f81204264
+dist/2025-02-08/rust-std-beta-armv7a-none-eabi.tar.gz=f9ac794582c73c7e0a36990daa6c2e2d637213dc16a0063aed330bf68cf04d4d
+dist/2025-02-08/rust-std-beta-armv7a-none-eabi.tar.xz=7463c6f6e9ba1bc056ab528e00017db0d6ac2b0e06812f0b1d7b569a8a7e51ab
+dist/2025-02-08/rust-std-beta-armv7r-none-eabi.tar.gz=c676cfbcaae8c7686a231693b923f98e23ed3dfa174ecf42aab57d94e2bddd85
+dist/2025-02-08/rust-std-beta-armv7r-none-eabi.tar.xz=93b2802c8f555fdf03cd309539eabfa2f8e434114f8f750b89ec3005249e9b91
+dist/2025-02-08/rust-std-beta-armv7r-none-eabihf.tar.gz=077cf1bbe4fdb0c011bd625a59ebc4b3d2876a50b544b76934523504c59042b9
+dist/2025-02-08/rust-std-beta-armv7r-none-eabihf.tar.xz=3be6d9e04ad155e78be5ecce391b57b285c7675cd9a4f86e2ddb388c934c21f8
+dist/2025-02-08/rust-std-beta-i586-pc-windows-msvc.tar.gz=2e705d5660544cec738cda300b059dcc1d730f7ff3cb029980a1ac9c1f9e6831
+dist/2025-02-08/rust-std-beta-i586-pc-windows-msvc.tar.xz=4cc0760e20f53648ae5b171c6948af3950cda4c468f2bb437016d92a2eeb2465
+dist/2025-02-08/rust-std-beta-i586-unknown-linux-gnu.tar.gz=3a516cf5c265899c9a548f6b9305b78069cc03864dcf1b3fa0e247adfa978cb8
+dist/2025-02-08/rust-std-beta-i586-unknown-linux-gnu.tar.xz=25144f4fb500ab9ba438042dd24796b25660fc3d16d3e04b64561bd35f84e46b
+dist/2025-02-08/rust-std-beta-i586-unknown-linux-musl.tar.gz=70bf9429de2e11fe9e14216d3c1cc61a3923e1a7c7bc17d5b0d63785716a9e26
+dist/2025-02-08/rust-std-beta-i586-unknown-linux-musl.tar.xz=35cfef70aa5c59ecbe0d563959c62ec0162a8943d32cdc45dd0207b6ad3d16eb
+dist/2025-02-08/rust-std-beta-i686-linux-android.tar.gz=a17f82a5f41e38c5c9ccaf1b2cf5182ed2e3c459e87c841497f0594cda7f71bf
+dist/2025-02-08/rust-std-beta-i686-linux-android.tar.xz=06565daae363ed88f579f261a89f75d126785c894e439976ae47870cedd56378
+dist/2025-02-08/rust-std-beta-i686-pc-windows-gnu.tar.gz=986595d50c1c5799f67bd04575b248c5cd81dc03f318bd137b46248f75b2727f
+dist/2025-02-08/rust-std-beta-i686-pc-windows-gnu.tar.xz=9daf96aa939ec6ed4ac8ff6119da06fca827a7f160e5c7db658653d5839846af
+dist/2025-02-08/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=f793d7a5ce20392287a7d178a2403d1d72dec2437401c447a7c5e3168c25bcf6
+dist/2025-02-08/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=039a361f65fd610b14142f0d654895f4ac271cfb03918f7fcd8b2e9c5ffc3c98
+dist/2025-02-08/rust-std-beta-i686-pc-windows-msvc.tar.gz=6cdd125eafa981da12bff2a7e519866cfe40b7d6d7b6debabbd2415759fd9dc8
+dist/2025-02-08/rust-std-beta-i686-pc-windows-msvc.tar.xz=7f1a722bc007efe77dbd099ff36f2c682ec4bcdb7e8b60d6ad868e9d08a9a367
+dist/2025-02-08/rust-std-beta-i686-unknown-freebsd.tar.gz=b7dc78d6d4e6ce343ce90a7153082575a991eebd8acbc3cdfbcb56d1cc281b83
+dist/2025-02-08/rust-std-beta-i686-unknown-freebsd.tar.xz=91d19c3086de738b3d11a2bd0f0ad31c9f6a9c39ef800fdb2040638fc91c69ac
+dist/2025-02-08/rust-std-beta-i686-unknown-linux-gnu.tar.gz=fdd0f12816d4bfc15c441cd26c7ef0f9ac05f19b03f471f162e8781f04bfc392
+dist/2025-02-08/rust-std-beta-i686-unknown-linux-gnu.tar.xz=a1ba9ce61110a1a64cba2bad7274865979d8d10cf30dba44137cd0acd4b49bf1
+dist/2025-02-08/rust-std-beta-i686-unknown-linux-musl.tar.gz=3774b47f5d6748c32d634f0414391121f2a68d7e3e15162cce62ca42bfce1db3
+dist/2025-02-08/rust-std-beta-i686-unknown-linux-musl.tar.xz=fb0203eb986554773288b732feb65a76aa7e4510b30acf60a9a879614332f0e1
+dist/2025-02-08/rust-std-beta-i686-unknown-uefi.tar.gz=a388f43900f4ac040e2263f06e89ef92c3d630f2631b37147eb1234e3ff5555b
+dist/2025-02-08/rust-std-beta-i686-unknown-uefi.tar.xz=5fcc43194705468d31fc07ea2cca780fef717adc2d46bd9508d006adcd237c23
+dist/2025-02-08/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=c1d25f88813fb558bf47478a7e2a43e735f2e7ceba87f3ab8e658200825ac6a5
+dist/2025-02-08/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=66ae16763fba1c9e54519a34b70811f4b54c2a3985bd0faab4ae1a454f837556
+dist/2025-02-08/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=0cf97c80c7dc0e760d9aa2f6a6d6b82ecceed06b0c0e7f56b2f3fee98f558d3e
+dist/2025-02-08/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=7b8284890d5c90e9a3d2cee73ee6b77ed0f023321a547a9add7d25e64886c9b9
+dist/2025-02-08/rust-std-beta-loongarch64-unknown-none.tar.gz=67f97000b8786928eb7ff7f060fdaa2fa9e3805c23e5f3fc24350c6ab0954c17
+dist/2025-02-08/rust-std-beta-loongarch64-unknown-none.tar.xz=5660100854fbe9fd87c0854b560a91dd5b653f07a0c374ba6349c44ff54b3b76
+dist/2025-02-08/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=a885c29e4eea19ada52cc22bfe395eb0f2e884932885c3978187a44405d5873a
+dist/2025-02-08/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=acbfef3c94943ebc1a44e662a5eeffea6c3c0f8b2518568b03d2e1c5baf323ea
+dist/2025-02-08/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=2bb3f9493afdd89c52bd62e2597c8687335e0d4fbe5a486782335a614881a516
+dist/2025-02-08/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=0702664eceb39c21390e3ee8dbfc0a7a181877449642b1b47dc74e1f463d8ebc
+dist/2025-02-08/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=788b46512726f8350f8266f4dc7e3bd4108ea96b2c257876d42d6c62cef71507
+dist/2025-02-08/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=a746eeeb6c41696c95144068e348237bc7a3b254b1c3db626797dd2947194999
+dist/2025-02-08/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=48f11a2d3aee9b3cb8d9e7f6480c8859427f446ebde617e2575a17dda6605fc7
+dist/2025-02-08/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=5a3933b2465cfe93daab1b5d339a0da17bc364d5621d85e192283250b337e38f
+dist/2025-02-08/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=50bddd9780ebcb5bc081b41c071c6059618881e1cc384f30787caa6fd2f28127
+dist/2025-02-08/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=4630d67082a6c2211a8c59a6da45d260616bd026d7cf7d2bbee5ae6d24b218c1
+dist/2025-02-08/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=4a0bcf103df6febd7b3e04bb24d54b30b6a2f4ffaf150f6774811c149f450588
+dist/2025-02-08/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=6a37963463641ddc14e03c0f9d8b037cd62afe3af89aeaa73f1f1d3aea1a6f93
+dist/2025-02-08/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=7e2c0f7ea78086cc2b8674aacf350b6de737ca68a51778a8a66c75932161a8a8
+dist/2025-02-08/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=a575b31731a910d2db684a931ced914b4286b942ce878fde94f08bafae92903c
+dist/2025-02-08/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=096407f438062be73bdd4f2efb6e06ddcb6c6c8e08b3c2db76388a4f4c4a731f
+dist/2025-02-08/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=38b771d01c0a56330d9547692c424e92b243d3f2448c13b29873cb2e4fe70b17
+dist/2025-02-08/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=218d5db0b8427fcc0a81612134d830e6807db8d66eaa4365c4b101f29ab75ae2
+dist/2025-02-08/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=1227b4dbfe7f3a0c7715904d3ed1e9f9846c49e522bb579d7dd76de370ab83a2
+dist/2025-02-08/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=8e5ad6f6116b0fef61650f2a3788cc9a9e6da1cd76dd0dc300d81060ef42ee6b
+dist/2025-02-08/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=777cc9ec22cb9b92ea3569d6835770f45ea7793397be670edeafa65660d411eb
+dist/2025-02-08/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=16d6414fcbfd0356206cccb10f0d5ec1391300c8bd92029d9457fc3030cf3cff
+dist/2025-02-08/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=bd4ffe303e7b6a9031eae2dca7b4af4c7095e06961a55a6eff01db57178c1635
+dist/2025-02-08/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=facbe91da7b765e03b058682a1353153b89632f5f60692b25077ba4152105faf
+dist/2025-02-08/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=e130dbd1aa2f19c308ca3e72e0456769ab0898a9bacdc667261396d786a22fca
+dist/2025-02-08/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=3849880a18e3176c4acb895dcee7f5befa64ad3413ac8476325d97a9a2bbc542
+dist/2025-02-08/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=8a14b3cb0c9e20ec84ab686e6eca5acd201e71364ab5007c96b884feb4b59340
+dist/2025-02-08/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=f5f58c50d793cb26103f812bb32b2d3623c57319a141e151201764f20032262b
+dist/2025-02-08/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=db7ea697f41b8dc2610c6d71ded8dc0b80ec848c002cb6af8faa3105023ec424
+dist/2025-02-08/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=b081a9b131703cbc11658eb84e54e495fca021bdc6487d902c7aeb8126629437
+dist/2025-02-08/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=2a3327ffdd3bfb9b4ce6d1aa13202958587d0819dc49ce08e635970d8e608b6c
+dist/2025-02-08/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=3b0abfeb0a6bda721e1faad0fe4ed2db072ae04beaef53d895f3902a26387522
+dist/2025-02-08/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=5d6314a99746c5fd7f1d0eb0ac426848b4baafb9e2f4e08b7ce361091909a485
+dist/2025-02-08/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=01f85bdc840f6d354fbc765b2574cbf039a97e7a8cd4345f31d4a93f41ea2936
+dist/2025-02-08/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=350aa8e77ce705d04d996ae3911121c14213fed5db6d179ae4efeb54e64d5554
+dist/2025-02-08/rust-std-beta-sparcv9-sun-solaris.tar.gz=4cdb48054bcd8c596657c466145e1ec9d9a513d6019694895b7b1218183d7ed1
+dist/2025-02-08/rust-std-beta-sparcv9-sun-solaris.tar.xz=abda0bf8356c63fcf50fafb196c86a6c2275f3155362fe6b9eb63c8a145e07dc
+dist/2025-02-08/rust-std-beta-thumbv6m-none-eabi.tar.gz=87ce4c701797be511509773e6121d69470d604f143c4e46e18866105193d503e
+dist/2025-02-08/rust-std-beta-thumbv6m-none-eabi.tar.xz=d0af4c523a37df6ef2519d2abd680e2abc21e8806904cbbfa2bad3ddebc55252
+dist/2025-02-08/rust-std-beta-thumbv7em-none-eabi.tar.gz=9c183442ae8a7bf18303331e23c2263d180157a4fa9d000735b57f54f894fbf3
+dist/2025-02-08/rust-std-beta-thumbv7em-none-eabi.tar.xz=c9278b82123969a4f9c8536f6d27ceb6b6cae182335cee4cfc1ba8f297d503c7
+dist/2025-02-08/rust-std-beta-thumbv7em-none-eabihf.tar.gz=cda7f615c006369dea46c6d00660d596459d2ca809b27802c15a9e71e741f806
+dist/2025-02-08/rust-std-beta-thumbv7em-none-eabihf.tar.xz=7b2bf45033d1849ced101c696641a3e0037dc65029bea06fcedf3b11af1b21b8
+dist/2025-02-08/rust-std-beta-thumbv7m-none-eabi.tar.gz=bbe3db6ddb17830708086940294a8931054c09d781968f69c810a5a17cb4299d
+dist/2025-02-08/rust-std-beta-thumbv7m-none-eabi.tar.xz=4cf28e2656f8927cbb75c007aded9d0fcac8d8d34841e9ac5486ba8ad3a75a58
+dist/2025-02-08/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=6021afefa8b06c99e09e63c07a8d4580ef7a6d9e004205d85f8fea47fb7c77d7
+dist/2025-02-08/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=7fb5c89a7605b0b377fd3e11d3ac5e33dc59667557b690b02df5c852109cefe8
+dist/2025-02-08/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=f1cbb573556272077f7a119e019ee4c1f8c533cfcbdb2b12c858c7d72c05212a
+dist/2025-02-08/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=2d7c0f7ece15f6ad5de053a4b0292113efd8b45457a7ea4ac4a84534985a6e7c
+dist/2025-02-08/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=fb5c1d99eeedb48edac78bce237351bb2a04b3ce1e028b47c488a28a0f5b258d
+dist/2025-02-08/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=301ced2f4ca8766183cfbd84b94ca09f21c9c2fee62b3e1afca440f5872ec6f0
+dist/2025-02-08/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=c720cd1896d201ecee177381386cf37ff58a0ad2e153efa8752dc11358489774
+dist/2025-02-08/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=f2e14c2a08777200dcec2c18677a1bd68c57a7caaed8751e17d4a82af0f61e9c
+dist/2025-02-08/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=146bfeecf574cab3bc15396c2523f27cc463ba9030d9a8c9a07118781a78227c
+dist/2025-02-08/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=093364007abdcb942a1d095bba6b3f6a63cb891e3897764923828db5aa44f970
+dist/2025-02-08/rust-std-beta-wasm32-unknown-emscripten.tar.gz=f2e4ef8637a02510dc3edf78f7117dc16671946e1eebf3ee8911160bde53f3a2
+dist/2025-02-08/rust-std-beta-wasm32-unknown-emscripten.tar.xz=d30b8b9a7607de4cee24b144452439726eb8b4a436f53c058c2b0c21b686a391
+dist/2025-02-08/rust-std-beta-wasm32-unknown-unknown.tar.gz=242403cc6e3df3d47c566c63fccfb40e6a95d2f2295630bb13f4875c9e28ae62
+dist/2025-02-08/rust-std-beta-wasm32-unknown-unknown.tar.xz=8ba08c010e49593d417feb05f3efe407200421bc26d40b51a8d92ae6cbc46200
+dist/2025-02-08/rust-std-beta-wasm32-wasip1.tar.gz=25cdad2de0d599c5e90373765acba871e2facc7656ea1362b3e0d1132fe8805b
+dist/2025-02-08/rust-std-beta-wasm32-wasip1.tar.xz=0eb3ae579124a47f7e8b63e6933e703d00c535f8369c614678e35c431a5480ff
+dist/2025-02-08/rust-std-beta-wasm32-wasip1-threads.tar.gz=08d400d8ad036c2b240f4044adc6cf484cf996b5f1cca5e9c0fe81814a71635e
+dist/2025-02-08/rust-std-beta-wasm32-wasip1-threads.tar.xz=46aeb5066e5fe4bc613a704c760292a85d2cd5ae10d135412adf5cb42de24015
+dist/2025-02-08/rust-std-beta-wasm32-wasip2.tar.gz=9df47e7c8280b8780ca41ed3dac9326375c76955560491ade1c2fdc8682b70d4
+dist/2025-02-08/rust-std-beta-wasm32-wasip2.tar.xz=275cc332f6d29c685ecfc308e143edccf58fce0359f632b038733a7759ae7389
+dist/2025-02-08/rust-std-beta-wasm32v1-none.tar.gz=96ee2faa07796474ea348b83b626cfa0bd07d108ffd05aed8051b63960315ee5
+dist/2025-02-08/rust-std-beta-wasm32v1-none.tar.xz=965650429f8129c65a6180025fdb69c0890f5c6f9c1fc16566c08b055e4ed93c
+dist/2025-02-08/rust-std-beta-x86_64-apple-darwin.tar.gz=92ebd93de4f4da8267e13824db8455dbcb7bb95ffda8ae480c648c2eb8f820da
+dist/2025-02-08/rust-std-beta-x86_64-apple-darwin.tar.xz=00e4b5a44f69a2c9235e522eee91e972624c75e3ce773928b09e9ee20d2d51ba
+dist/2025-02-08/rust-std-beta-x86_64-apple-ios.tar.gz=dfb3d88798ff9b490c1a517d57e459a77cf2bb2e8b427493a3a612405534ebb3
+dist/2025-02-08/rust-std-beta-x86_64-apple-ios.tar.xz=7091bae8ccf328336261c2b096d1565c0dc9dca02b03d4e228a7c3f4c412a6df
+dist/2025-02-08/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=79628c744d12c1bc5514801a530d903ec539efd16e82d0c871adfaa168b7f55b
+dist/2025-02-08/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=2b12ae64c94a4f11591de8484998391d2825bc68535257dd305d31a1c51a7210
+dist/2025-02-08/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=54f4caf75ac93676fd61fec65e2ea6b73774d5de7d7abe8d47d9c2d8030d8fe0
+dist/2025-02-08/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=abc1feb82d4449c0d098a1ee0861ad991e79911cf0d5cc9ed9b5ca1e134248e6
+dist/2025-02-08/rust-std-beta-x86_64-linux-android.tar.gz=fdc1afd6334f725cfd913faf0915da711cdbcc45c05ec2672fae34d97e73ca60
+dist/2025-02-08/rust-std-beta-x86_64-linux-android.tar.xz=9451c74b695dce762d56354fac148263b0a7de75209c127bc7126da54ede7114
+dist/2025-02-08/rust-std-beta-x86_64-pc-solaris.tar.gz=d32731be8a9d3c5e8279a1b4971d105fe457717acbdfcfd720bc0ae55a34df26
+dist/2025-02-08/rust-std-beta-x86_64-pc-solaris.tar.xz=a5a08cfaae7eb3d77c137bf0d436beb7a84a19e351f529fe459861a8841df44c
+dist/2025-02-08/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=7c41f46506f93132c5f90184d7ad1577edec98d47be17c6330f24cd172c673d5
+dist/2025-02-08/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=e439c8a7368e70685b239ab7b84bffcd8081ddc80c2d9f6d2b686485316aed68
+dist/2025-02-08/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=128c7e526e37551ba3b6a347cb870c4ceefb272d964512fa10635c8f1f6e239c
+dist/2025-02-08/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=660409184e81625419b91a4fb5d84572abb0505d9bc11bacbed50121f9230790
+dist/2025-02-08/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=10b37018a254f81e55f555628fcc535a54b0eae0097f02a148c443a3d7e762f9
+dist/2025-02-08/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=d61e44948d2ea70b44c8d3f958a3657dae9eb8a551aedb3ef90327da0124d9d5
+dist/2025-02-08/rust-std-beta-x86_64-unknown-freebsd.tar.gz=7ed5b948a50946b518040170be16cba1b5ec0c02f823436c973e5afbd335d26b
+dist/2025-02-08/rust-std-beta-x86_64-unknown-freebsd.tar.xz=0bdce5b2f88448dbbe101f4ef48231763739533b52c32ab6ef858b6b37d98a50
+dist/2025-02-08/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=49676d645ef9c49a421f3fa1d908830b61542541f1ea12c2d240ceaac3b977d4
+dist/2025-02-08/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=1c0854c619e2a0dd7e508513fb68c22352ddc170572bfe6535d2f759de069c53
+dist/2025-02-08/rust-std-beta-x86_64-unknown-illumos.tar.gz=8ded61102c481e7c000292a8c6d39d84c016f81b00618947ac7357a7c72fb142
+dist/2025-02-08/rust-std-beta-x86_64-unknown-illumos.tar.xz=b76ed9b0896cfe863fd2aff88fd6d075e6091a651cb0d5fa65307948316f7ebd
+dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=1cbcf5ae9dd2c61212b82bf27bf1b1b7d9504f077119c1fa04a978fa0ef3b2e6
+dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=86f236dc4222f5f93f160ca847f43f364e1659b6d4c9f68a31c202f5346f2221
+dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=2225ae88e8cf954b7eef8fc2e4f391c0194fd7be6433928dbc8aa6e2235ac479
+dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=6017a3197b7a103a4444b81f8fa4f790a2b11bf1c3db0af297e2ed0c97f78172
+dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=e7b3c4d8efb8f56fa76c3cfe51eb0683fc41308691ac194b9eb70e13b1b2e976
+dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=f0ad48db569e21b8fa1053de3320d766cbb10962ebbd69ed56f170bdaf76fe45
+dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=f1baa7f02c0969d74cd0ba420ae0a8d5e761cd5545c04fd2e432c889db8cb655
+dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=e572e1a7db7e0127bf7072e5361b91dac84c019afa6433538b40dc984957f1d7
+dist/2025-02-08/rust-std-beta-x86_64-unknown-netbsd.tar.gz=c714b5f4a61041b5c68abc532203c88d65a852a813b7af8e11ab3207804886fc
+dist/2025-02-08/rust-std-beta-x86_64-unknown-netbsd.tar.xz=61d6c87b146f114d14fe637257b9feccbb1d787958a7291f7800c7541bd8e21b
+dist/2025-02-08/rust-std-beta-x86_64-unknown-none.tar.gz=5ab7c9985beb3f07520cecbb60c2fcb8bf60b3079b253267fb55d2139619331a
+dist/2025-02-08/rust-std-beta-x86_64-unknown-none.tar.xz=992257d8f922654977d1c1fdad2b57654b4ea7fd2c27d6a4bcb8f85b9a75fc5a
+dist/2025-02-08/rust-std-beta-x86_64-unknown-redox.tar.gz=e5090b881329fd94e4250cef92464bf3fc42ae6566ab3bf461e1f3c843d3d1fe
+dist/2025-02-08/rust-std-beta-x86_64-unknown-redox.tar.xz=89cc1ad229a453c15d4a88137646d6824c572eed602c9c131982e3ddc62abd75
+dist/2025-02-08/rust-std-beta-x86_64-unknown-uefi.tar.gz=f42383deea91ab9dfdffede178b4411d751772a482811058dfc0bcc33da2fab6
+dist/2025-02-08/rust-std-beta-x86_64-unknown-uefi.tar.xz=3b4e67edf9785c0eff0fd83e357fbd4c0840620d1b7380ba5d270729f751e4b1
+dist/2025-02-08/cargo-beta-aarch64-apple-darwin.tar.gz=f197e428af3ea3d409a43b54372c9f0f7f8f70ef8d048e066b5c609364211e35
+dist/2025-02-08/cargo-beta-aarch64-apple-darwin.tar.xz=e84b8ec6f87512fbf31c823703b94ebee8531675430224331845158b8997121f
+dist/2025-02-08/cargo-beta-aarch64-pc-windows-msvc.tar.gz=16b73927483117d158a3f3aa36d9cd14d74dce707071345fab9e6c359b68665b
+dist/2025-02-08/cargo-beta-aarch64-pc-windows-msvc.tar.xz=3fb1381b750a1ccf386602394af21130e9cc6384b962bd008ffb2e11bcac4c1b
+dist/2025-02-08/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=2b0d90694987ee10a0f0e5b40c1f95c65c9bbeae6c921556b85067a1920f5988
+dist/2025-02-08/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=b47667e97225ce7542c6e9a137adbc7c002ee1e4b1e0c1255b5dcb87743d886f
+dist/2025-02-08/cargo-beta-aarch64-unknown-linux-musl.tar.gz=843bea38aaeaf6629060a046e6654fde6f4a73221a996e56ea9a1f35466cc6cb
+dist/2025-02-08/cargo-beta-aarch64-unknown-linux-musl.tar.xz=147827cb32d5ff3628f347800a9202eb0b3caaa142d363dffde94bc6bf821352
+dist/2025-02-08/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=0dd6585f3e93a60d4084a4f7f6c58748e82c03ea38fee164828d3911d024459b
+dist/2025-02-08/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=2e8240d79a86de26e7782265bd6551c6357a025b7084a3ba88161c84e2fee54b
+dist/2025-02-08/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=323095df9d5c9f47463c5b05729960ee0db5f910619050ed548adb2b8c59fc35
+dist/2025-02-08/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=8f5be63da1f8e9a7d90116c9793e03021855dde170a356002f306180d4ba7ff7
+dist/2025-02-08/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=63dfca05df7a8d14c27070ce882a96defa2e5c3134fe17e848273694b42b3c88
+dist/2025-02-08/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=3881f42ce8e69953804cb0c566fe08f44ab8763cefe8c0d6a4461645dd44f518
+dist/2025-02-08/cargo-beta-i686-pc-windows-gnu.tar.gz=70aabf19aa3db89599131fc09fc005a9c8c0974d3f04267df0e41007f5bc46d7
+dist/2025-02-08/cargo-beta-i686-pc-windows-gnu.tar.xz=c57bfddc9285dd7c1151c3bfbde4f92da394fe6c8d0239c1f9ee8eceeb15e29c
+dist/2025-02-08/cargo-beta-i686-pc-windows-msvc.tar.gz=056e750115574ab4e008d76d1bda67aa30f3818a9f46cc88d7ad13bb4238d772
+dist/2025-02-08/cargo-beta-i686-pc-windows-msvc.tar.xz=663a9ec0ba07807ce289bd61c66e196262e991046da44dd583fdc1414759f5e8
+dist/2025-02-08/cargo-beta-i686-unknown-linux-gnu.tar.gz=95dee9910674196f2bf655e91a8443be5b46e36747bf1e980e1585fa3789375b
+dist/2025-02-08/cargo-beta-i686-unknown-linux-gnu.tar.xz=09af49a00e181084e7f766c9008c2d3446ff1cb801780feb79d0b7cc31a038b6
+dist/2025-02-08/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=ab1ac3686ed7b3b50ace61efe20ea6848370de691cf0f287337113d7ca52c61b
+dist/2025-02-08/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=bee237e641da0d804f2002d33910bfb199127c5006af39dd06d877ca5fd1ff82
+dist/2025-02-08/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=9beb2a39f1ef7630f03ed1da5e1e68964a4b198fe7f18d0db9efb4f10d70b35f
+dist/2025-02-08/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=f1528e4aec2095d55b98e3421d2310f3aa3fcf7c2493f83e75d3cbc80e18f923
+dist/2025-02-08/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=2ee460d198339449e85ff8c7e522c47f33677e90f8b215c0a13514fe5f05cdb1
+dist/2025-02-08/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=4a9fc5e31abfe582b580e395ada8d59a1aecf65b07b09b8ce526a84fdf61830b
+dist/2025-02-08/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=9e471ec06debbe078b8c92773a1c4380969e92dbbd9f20884986b2cc7e942106
+dist/2025-02-08/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=1cc6e9e448f036af3bd6f8e597ee242edc65811835e20545e84ab917744b50ca
+dist/2025-02-08/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=08fb88ea0a4d904b28ef7a51275ccfd1f8480f1d33c7a5a83461d322143e81be
+dist/2025-02-08/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=0809a5f718157763bbf67e8c3a3b9b868a6694bd88b87277b542fc3207c1f1d7
+dist/2025-02-08/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=dcbf18b645016eee37a23dce4126d0ad61f8886e8997b480609e8f8fffe0191a
+dist/2025-02-08/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=f4f9350ec459016cc0fe54414d75fee119b0051e3ae1b839971ec5b569be97ce
+dist/2025-02-08/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=dbeee82ff5cec6c16ba873b40f986e85b55f831efbd4d09d0107b2e66037db87
+dist/2025-02-08/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=2974493a708fd5c793b9f1920a11b66aa5ad6aaffecb0b9c597416b7200e411a
+dist/2025-02-08/cargo-beta-s390x-unknown-linux-gnu.tar.gz=ca157ff6dac3d680f63c99fc2efbc30376eb6ae54682f40369c4d2aa8647b77c
+dist/2025-02-08/cargo-beta-s390x-unknown-linux-gnu.tar.xz=ea5ebe153fbe3d1fdf514ebc050f46776b075268aaf7e7e3ef308f13d0ad545f
+dist/2025-02-08/cargo-beta-x86_64-apple-darwin.tar.gz=dd19dc295a1c430a52c223478a01610b359e2e0b40abce7111c9a02a51d4d313
+dist/2025-02-08/cargo-beta-x86_64-apple-darwin.tar.xz=f729d46cb4ca8945657671d5d0c0a55792a2ac9f5ea21b3e2991843004fc23ae
+dist/2025-02-08/cargo-beta-x86_64-pc-windows-gnu.tar.gz=9a7dbfaaafd177a725aef60ec6c4fe3c5b732bcbd69a2e25a91ad7461a76ef4c
+dist/2025-02-08/cargo-beta-x86_64-pc-windows-gnu.tar.xz=ef585bc9e5f23368fbb960959f80fd34961909e62cd65bb847db06a7178b174a
+dist/2025-02-08/cargo-beta-x86_64-pc-windows-msvc.tar.gz=5e396a15cc63f084467d9afcb30cb374c070856b0aa3fcf209d88bcccfc6436b
+dist/2025-02-08/cargo-beta-x86_64-pc-windows-msvc.tar.xz=78cdbf2cf0d7fec4d24308853e96a39bf5c417905abfcad34de4d1b2d498a617
+dist/2025-02-08/cargo-beta-x86_64-unknown-freebsd.tar.gz=1e485ce036055c7b3e1949d9e34e7d3dca436438b3f09bd75d36e49217d53d44
+dist/2025-02-08/cargo-beta-x86_64-unknown-freebsd.tar.xz=80c5d0d5860eebbb807a2e5cf8ccba8ed4461f932825439ec8182f6f0c8939c4
+dist/2025-02-08/cargo-beta-x86_64-unknown-illumos.tar.gz=5681331e1d29b476c4f458fee453f73efc86856caf1d30c49df9dec3e147f4b1
+dist/2025-02-08/cargo-beta-x86_64-unknown-illumos.tar.xz=9f7d97045851bb1ab334761cddb38cd8bf3bb0b26f2fca4903c09301c70fbca4
+dist/2025-02-08/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=24bda5749883e133ac58ddcfdbd8dbeeb660c3b33d613852dd1d993cc13f6e8f
+dist/2025-02-08/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=2304e5cde3efdb5c6e7319d8239bca7d1c69306846cc3eba84d70d49b8c24e51
+dist/2025-02-08/cargo-beta-x86_64-unknown-linux-musl.tar.gz=825a42ae4bab8be081c7320f06fc7ce6d0c0c31f2224fb0c13af4d01e04c3626
+dist/2025-02-08/cargo-beta-x86_64-unknown-linux-musl.tar.xz=656d148e383896d06483297d785d62c8e235020081acb4110a8bf698a3d6d6e5
+dist/2025-02-08/cargo-beta-x86_64-unknown-netbsd.tar.gz=1e6a750acd6c1f44e37b3d1b1dceef7e8a0d2b0806e1577b667573a6340e7cf9
+dist/2025-02-08/cargo-beta-x86_64-unknown-netbsd.tar.xz=c45bd23fd1004cea41f133a40bd102e55e9f7ed29c9e8cec83dcacc4653da7c7
+dist/2025-02-08/clippy-beta-aarch64-apple-darwin.tar.gz=cd22d4191ca0fb9d8ec3d627805f297ca4528018e34c4f627e7e4fc05d6b0954
+dist/2025-02-08/clippy-beta-aarch64-apple-darwin.tar.xz=0c408799a742b00dce013553a597e62d8f84232ede6883632dade6b3d024904f
+dist/2025-02-08/clippy-beta-aarch64-pc-windows-msvc.tar.gz=b4d902d9a096cdc6eb655ae2a0960db6fe4b83ccb681cc5bb5124dcfc5e1fdc0
+dist/2025-02-08/clippy-beta-aarch64-pc-windows-msvc.tar.xz=9e2514d7f304e3253e7205cec8189b8f9b1d49da5b14b2c03e69b8bb0223a65c
+dist/2025-02-08/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=1496cc4bbd0edc18ce05bc2ca76d9ed78934f1d1c4749ff830dff7d1acc2535f
+dist/2025-02-08/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=4577dce94261cdf07064f43404ade755a8906ed0b1a39a148333d9309e011916
+dist/2025-02-08/clippy-beta-aarch64-unknown-linux-musl.tar.gz=d28217818fb6c1a13456684bfdbf9caa687dcc257fadffcde2d2fd94dfbb228a
+dist/2025-02-08/clippy-beta-aarch64-unknown-linux-musl.tar.xz=bae2f1841776e321f5f950678516bb31c05dea8f825fda23f3a3cd423dc00249
+dist/2025-02-08/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=e1698a07ab47d02954bdb67034de33a8414731e3d12a8937cdea97004d98e45f
+dist/2025-02-08/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=631499b2ee136c428f1c6045eb6aefee3e6c765dec1baeb0c3e4da056d540d71
+dist/2025-02-08/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=248a15737924d07afee2108e6545cb4bd5cce91878dedb5368c358c16a0b016d
+dist/2025-02-08/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=6581c968d48e37baf99addf17baf8b4fdda1417c201da311959c62a51783209a
+dist/2025-02-08/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=8ff9d93ea49d805ffd3534c6aa03692fa7dc8bf0460bba7c22259257dae863d1
+dist/2025-02-08/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=b267e928b9708cc168d84c005036d155547274e8fe03f23b14232609b780d219
+dist/2025-02-08/clippy-beta-i686-pc-windows-gnu.tar.gz=957e8d14451557ce11de7303be61a50c68af7b90293a46e48c9a1bb3db05d154
+dist/2025-02-08/clippy-beta-i686-pc-windows-gnu.tar.xz=576732c661cd0998f7b47e99fe84c3dbcb919e787e3222e1c27b5377361083aa
+dist/2025-02-08/clippy-beta-i686-pc-windows-msvc.tar.gz=5a4ea7d3fd79823b2342ec9069e865000dc5ab58be0fcf3655bcb161cb195858
+dist/2025-02-08/clippy-beta-i686-pc-windows-msvc.tar.xz=fbe4f93a9f1ab718a5dd3995ce67b7b0768f7f211f8fc3f1e6b181c4e4f1f467
+dist/2025-02-08/clippy-beta-i686-unknown-linux-gnu.tar.gz=0c013dba1ac3db5ec21e672f357c6a86c379c29f7cac0d43df4857e0332abe22
+dist/2025-02-08/clippy-beta-i686-unknown-linux-gnu.tar.xz=0e585010d88a8f04f9e031fcef623a12da7f82ed9f0d827157b10f6be80eb920
+dist/2025-02-08/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=2716e252361ac72dfebc8521b3f2c0edaa6e0a0bb0b9a3ea3b9b888a5d747104
+dist/2025-02-08/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=3d400fda76fbc8a830e12f5f71e40d4993019e9e53d58434ca23e3d8761d530f
+dist/2025-02-08/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=8d7cd64c2ec8ee5f25bbd6aa01ba22001a4ab2eae6ca481583f736a1da07dc31
+dist/2025-02-08/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=f60bca644d441e36e537e896d4b122ca0f8cde0fbd886f12c3a312efd5225997
+dist/2025-02-08/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=a3fc359554026ae39c7cc46c53c6928de0522387ad2327444745eefd0fdcc43b
+dist/2025-02-08/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=8344b79f4a2a61cf68e526c144bbe797f1c60dec047845fc731f4c47a58b7be6
+dist/2025-02-08/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=05c2cd6e95a7c8ef36703b9bc39cedb8e5eb5b3c93a66a16deef2e18e96be489
+dist/2025-02-08/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=2a0c36d392c3b69fc437c8ab8358f87c6c50380e8c5ced6690c9a7d0be9c95e8
+dist/2025-02-08/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=c9c6975ec5ef1e206a917d03841db90e1f4a3562b0afec32a4753134752454d3
+dist/2025-02-08/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=efe920b25316d84c08693f28d0593d227ca18456be2dd9b426c8cbf49d81a352
+dist/2025-02-08/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=b133cb9709d11da1710b3b833a3e15d3fc216cacfd37e6e1c7c8fe1dbc202067
+dist/2025-02-08/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=7db8db7300b87bc7841ef59111c8f83fc6e6ffedbb6dd8fbb79431edb821e017
+dist/2025-02-08/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=2fea1f879ca90478a2fb75566da4cbed2f2afec31af6d18160fe183772241658
+dist/2025-02-08/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=668ef736714909588cae0bc77c30c3063d2911b0e1c28fc77678081099d38a83
+dist/2025-02-08/clippy-beta-s390x-unknown-linux-gnu.tar.gz=a05eb2ea42fc2ed7df974610b076adae42ec456bb80eaf9191521dda5c0cf12b
+dist/2025-02-08/clippy-beta-s390x-unknown-linux-gnu.tar.xz=5874e0cfa3b7f7c3b8d9d0c84a519b98908b6228fcd9f29d971b9c36d639a998
+dist/2025-02-08/clippy-beta-x86_64-apple-darwin.tar.gz=e259a0e7776430f1697153505f937c92e942fb5c436c00dd9da3b160ef9a7856
+dist/2025-02-08/clippy-beta-x86_64-apple-darwin.tar.xz=a311ec69770a431837a26e63591dba11dedbad411b688ee69e457bb7a4596c50
+dist/2025-02-08/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2b8278419633f83ca22e2d1c54a170e04775d903076935ce13e91575d6122715
+dist/2025-02-08/clippy-beta-x86_64-pc-windows-gnu.tar.xz=13190a1e83debb9483abc7b0e4e3a4b8d53895542ffa56ebc012dbd72b8e7637
+dist/2025-02-08/clippy-beta-x86_64-pc-windows-msvc.tar.gz=9c8c8de0bd646bb0284e47b6adc1db6443d9da7c06ed6d237c421339a446fd83
+dist/2025-02-08/clippy-beta-x86_64-pc-windows-msvc.tar.xz=32dbce4ca3f3abf6da249e33297efea856b3b0ff39b3571531d71e1d0f90a46c
+dist/2025-02-08/clippy-beta-x86_64-unknown-freebsd.tar.gz=55b22726920214e2ca9c4e552b50401fb3eef872c63de554623aaeebf9e11e75
+dist/2025-02-08/clippy-beta-x86_64-unknown-freebsd.tar.xz=b67e699d65462020333c037f206287e609f35e448cffeed6ecaec6874ccb2233
+dist/2025-02-08/clippy-beta-x86_64-unknown-illumos.tar.gz=6bf570aa87c05050e5dffcc191db07b1b0abf18bce160637a1be39e5caa130e6
+dist/2025-02-08/clippy-beta-x86_64-unknown-illumos.tar.xz=52ae7e8906f27c020df67beae61c1c1faf6458a0ccb3e904b909841b2b504d89
+dist/2025-02-08/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=fadc4ff0f2acc6d44a5a29d01101152c8570dcca69ea4fd60e8ca6cc2cfac1e9
+dist/2025-02-08/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=fd8472509ffdb81ff5ce786784274f654eb213ce963caf6e5cb90baa9e641c3b
+dist/2025-02-08/clippy-beta-x86_64-unknown-linux-musl.tar.gz=c94e847aae4aa7a04981a4be424cdb2a1eae81a808858a5fc14a20134b7575e3
+dist/2025-02-08/clippy-beta-x86_64-unknown-linux-musl.tar.xz=b1f2a240069cda55c7c49afda6137822d7aee855557cf7269ac4f440d54a0ca9
+dist/2025-02-08/clippy-beta-x86_64-unknown-netbsd.tar.gz=86ada6c1406ff381a81624da25e65f415380da01252e6016bffe50ef7ca5b49d
+dist/2025-02-08/clippy-beta-x86_64-unknown-netbsd.tar.xz=2b24a66215cd93b84065cd35d00bb3e7c9482b118eaeaf089bb2a128450add88
+dist/2025-02-08/rustfmt-nightly-aarch64-apple-darwin.tar.gz=0e6740aa70ccffed1e2649619990b75586638b8eb34747aab58ba4cccfb09f29
+dist/2025-02-08/rustfmt-nightly-aarch64-apple-darwin.tar.xz=c5c166763202c35bb7844f0866f05cfb7e2666fe9416776a092372362e7bd8e3
+dist/2025-02-08/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=cf025264c087d9339787db6f8cd4c76aaa9c3118b7875de7413dc1894b660fcd
+dist/2025-02-08/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=f788a44b9542ddda3a88e3000c31644e1b9ee874ce523798b6638f7f181b8df0
+dist/2025-02-08/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=0a7d236cd45ef4f3f12e4516b202cf9b5190e70a19044c8b17c5eef16c45032e
+dist/2025-02-08/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=80cf271c8adc2192b212d1b40992d90aa21fcc695375774c17a4f70468c82c11
+dist/2025-02-08/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=58d0eef426f8f0c4bf191118161db008db378ee3e77d973d7e15e39e88c3f7ea
+dist/2025-02-08/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=7eedaef7100f7272f38fbc3cc14a1f4fee7deddd31a59f7db71c2a6f2f03f946
+dist/2025-02-08/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=df5190ea7d9bb84d5ffdda74cec7591388d3501c2a4084c667e0f29ca0a0ba9d
+dist/2025-02-08/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=96334a22d0534adc8521b6a000f422f1727f80235303137eac32f4e76e85194b
+dist/2025-02-08/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=2944da8dab479b4892f512711ed6bb3b242602ab11c81c6b22352a467c898165
+dist/2025-02-08/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=5aa59c9ded50503a2f05d5330ef41ae888254887559b31c4304422aa4ba9e73f
+dist/2025-02-08/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=bf17c1d62ae3f59b595c6536add64453d5584135e1d238bae55216c428416767
+dist/2025-02-08/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=c60925816b01596b846e56efa7cd0e186391e212da077b36d781b926799704ad
+dist/2025-02-08/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=5c73dce13f7e0ad408f39f49ae647b0fbda00416027ba43228a443f311b33fb1
+dist/2025-02-08/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=df005321b30d82854f97a3e68a702c64ded7f4cde18edc69c3b1d7c8927b53e0
+dist/2025-02-08/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=2483fe75cd360607f29fc5f7cfc6d55074047291544f398946b5c263eef6b164
+dist/2025-02-08/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=f2553f96bb513e999597c89d0655bf1b28a338d6510f9a146b3e47674c83c550
+dist/2025-02-08/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=9cbc32383a8b6025ab9b7d75bf95b831cba32826f2732597cc3749b1a44278d6
+dist/2025-02-08/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=07f16dcf8340feaa8ac400eb54833017d501f78f11f699c095febec148f35aef
+dist/2025-02-08/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=03f7b562d15fb47e8e3ad244b127ed170c6296fbf5bf822fddd51eb5ab2a4f1d
+dist/2025-02-08/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=834186eb75bff0e05f1a7d9ea63382c7b96a18519aa6815060554b06f3d7b90e
+dist/2025-02-08/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=45c7db895ae3751fe07dc7483d0c1ae6dae989ec0b3507eabdfaaf9b1f24af04
+dist/2025-02-08/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=8aef8265279fca165e1627639d64c1f980877744cbd8a927c6c6f3f1e9ef2fd8
+dist/2025-02-08/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=4f85245ee5c997a7d821ea3c397c5bc7315c8cb07605f2b5a4746f254ef567aa
+dist/2025-02-08/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=ec1326a520eb4bac792bce1e260b261e3cd638c123dc2da962bf2f25bf3a89a6
+dist/2025-02-08/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=dd473534cd897998f6dd361f18a61ea12ed38bbb323c3d602b3124e832ce37fb
+dist/2025-02-08/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=a3523178a5186ebd3847b1b0fbdf91f300b29f780fc7910fa867ccddaecbab73
+dist/2025-02-08/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=625777f6ccf6ede941a88252bea183f8f285f6d282f95a78153e5d45e63edaad
+dist/2025-02-08/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=7c57c7c0163c74beaa80378974cfbe222f70057e44a025e042989f3816cf02e0
+dist/2025-02-08/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=b431d8683230d783641bbacf7fee8102ecccf527485e8a753781b49906cdfb56
+dist/2025-02-08/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=637801af10b564fa8b2bc8b3075b3fc26efd69237702bdd95b60f6d55e7a92ea
+dist/2025-02-08/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=2532bededd1512c36f97ad91d065ccf681b4df47db86dc382635cbd55e6f1aaa
+dist/2025-02-08/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=16eb4fcdc66b86d45af649905b33eb1a9cb9a859eaf4becae10b443a747b790f
+dist/2025-02-08/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=2c29615e4de5f4f9aac64102afee2f7775e961037c2b044ff5ea4690564a0af5
+dist/2025-02-08/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=0f88b8da8d50b7bc1fef09a53c5cedb79d24b3a63b8ab8cc6960285acb7fde7a
+dist/2025-02-08/rustfmt-nightly-x86_64-apple-darwin.tar.gz=f46c2a065cf61ba644062b20efbbd6cfd0dcba5b15bc8f333c35e32dd4640e03
+dist/2025-02-08/rustfmt-nightly-x86_64-apple-darwin.tar.xz=9bd81b4ec3625d959f96d7b6b17d6c548673c10f7246b712f99fe40e8dcb4844
+dist/2025-02-08/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=2d37451b9314b525d41817c432e3bff5e90028cb020f0331f39490975376bf82
+dist/2025-02-08/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=e8ad4c33272708ba094a2a14e1a69d9071345351921b357ebd0df7d32ccfdcd3
+dist/2025-02-08/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=1d8e24202a8b2111b78531e5313446c6d2e3be083aef77cbd95c09b909b7c49b
+dist/2025-02-08/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=9217ed18bb34379079aa529e3ef2fcc899db75780db942b1b6a45cb8f9b317eb
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=f82fdf61057bae8a38daa767f72c74efefaa6043ef48229bed9d8a86787387be
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=60857a9f3518fa6e1a0b8f17a0391672af55bf37bf5fc965b18079060086f946
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=67384f76d40cb80dc79bf0221a4c021e33f11f283e793404421bd5391d75f0af
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=e1238f9c47666b623feca48243e88ad40ba70d3d762e5e0326dd29eef41f8c83
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=cdf48fd39c450219ecbc0801aab198c74e31e543b663030bcff9d6df8829f7b0
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=a5a461c01b8709335c7e2dfef9378ee49aee5f9491f4bf6173142ab87bee3d31
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=d9881dac0e6d10758cc5e28d3c63be557d596336685b5d095cb77f69853ad978
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=beec700c0c6829c8975abbd26f7330a3ddc21040a8f2d531f1991f99ac11363f
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=188004d4990d1ca6f8fa7b00dfab510b0cbe840fda4e7318942bc2664c03588a
+dist/2025-02-08/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=ff25e65591a638072362122059d71888ddef0b9b81f0b0d7b2fc285fe82192f9
+dist/2025-02-08/rustc-nightly-aarch64-apple-darwin.tar.gz=c97c0921c6749ab5eebb2fcc65cc7fc98af43d1504fa1cf4ef360e299c74fdde
+dist/2025-02-08/rustc-nightly-aarch64-apple-darwin.tar.xz=51e12e1a1bb60b65145a5742899f0ba3c60840c60962c424351dd337de7b2906
+dist/2025-02-08/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=469e68dc2e1546ca27117cb3d282a77bd783e84c351d911a2e45c91916fc5944
+dist/2025-02-08/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=ca16024d975f6c4835d53a47cc12e728380ed9e9126f4f523854b5c8af148499
+dist/2025-02-08/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=75e9f08ced58ed868a1c5e727b632c1ea9ed8f483cadc68d30d7394ab3f60215
+dist/2025-02-08/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=c5d3906481bed31bfa563f216e8c17e8be971cf64d0a5d66820025900aa82893
+dist/2025-02-08/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=a6dab5d9fd0ddb5fd83f5332e3608df71b62891c1bc02f73479cf0aa344c4d1a
+dist/2025-02-08/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=9b4412cb694f46774b5642b972b0c149b5ba8d4081069cf078ee83e7f7ab1c45
+dist/2025-02-08/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=cda11234e3e2370fb2a9ae7d4f50a7c44c646c5ea9dee4d4a576383785ae993d
+dist/2025-02-08/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=bd6cece56d6559ae261d5494af10d665bb7293f439287f1d190cd959c598ab15
+dist/2025-02-08/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=c29c0ace7fe5b160e9399813848e70865d4eb90536169d9c6089a90b74e4e0b7
+dist/2025-02-08/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=bea382931c0b9804ab6ea0f3666679493c1c4390a2f732ad367b6540d4279614
+dist/2025-02-08/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c83086892fb1ce1b4ca0c778e9efe57334bd18d74a961fccca78125d58f185b0
+dist/2025-02-08/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=30ac3e64449a919ccb70dd30350086bcd5e8f4d12e0da6851f685fb60cdb871b
+dist/2025-02-08/rustc-nightly-i686-pc-windows-gnu.tar.gz=f51df0f5c9a8a89fabfb347f1164000a99485bd85dd67ca7bc84e2a48f9c80e6
+dist/2025-02-08/rustc-nightly-i686-pc-windows-gnu.tar.xz=153a564d7930f3c217b25f8573f79b279af82b8ea5ad7ccf09f8c127d4cb6c33
+dist/2025-02-08/rustc-nightly-i686-pc-windows-msvc.tar.gz=2d9c05cb1d60804cfca6076f231ac03081d3b2072cdb87e5f1d9f036325a17a1
+dist/2025-02-08/rustc-nightly-i686-pc-windows-msvc.tar.xz=fbb95c6c97a5e4389b761a1ba712f111f808113ef30abbbf0e95bedc5344708a
+dist/2025-02-08/rustc-nightly-i686-unknown-linux-gnu.tar.gz=df09eea18c7be163abd768ede37cfdec306563d0b33219ae040d8f9eef263154
+dist/2025-02-08/rustc-nightly-i686-unknown-linux-gnu.tar.xz=3ba7cab1234713f4fffade6344b62fc6b89d264e3b8b993799e5e0051d869e08
+dist/2025-02-08/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=ae94de4d5bcd8c265fb0297078d446fd84bb5ca7f9e61f87e956330d2c439ccd
+dist/2025-02-08/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=be81df065f92bd25825af0935b3188418c97e377ed7ce05ae287f576ff2eec9c
+dist/2025-02-08/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=96ccf45347235ac893cb61aa0d61aedcc46ae7c93d26f3ad964a73ddd1c274f9
+dist/2025-02-08/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=1e19c00ef298e5cd1334aa60df8873c0925304bb2a996d0ca590d363443f2f20
+dist/2025-02-08/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=3e44c93e6be85dfcd8031fce279b1d1604859d149a979d91144272ed4da920fd
+dist/2025-02-08/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=c3651fdbfec98c155159d799a895917c0df3599dcda71a79bdcedee3c9cb616d
+dist/2025-02-08/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=4875368f83906c9f447657ed70b0d53ae75ff563e6bd9b75110defbaf44ba134
+dist/2025-02-08/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=069716dd18791fea69df0b97627bba5fc83ee466883080ef934f4cb6b6342ee7
+dist/2025-02-08/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=0aa826fe16a9245091b84972be39aae113f62c1a254b82ec91df81a2c2c2da82
+dist/2025-02-08/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=2324bf8323d784cd37ca9546295e252a0327e25386ba406409e5c4172412d356
+dist/2025-02-08/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=2b5debffe5fd870828cf54365b21b1cb989bc5223b76a911299208c5ec105c2c
+dist/2025-02-08/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=34342b7ac92698d15b53afa13897fa37401e33b591e2a9ebb00ea17bf2ad7741
+dist/2025-02-08/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=e189c8be0a75ebc0c65e1b467476c510415231c5bb67d742719b39c425ee98a6
+dist/2025-02-08/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=2407a0e42ff8280a16e944f430d2724bed6765295a64a53f463e341d35f9fb0b
+dist/2025-02-08/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=ffbaaee6cb11d1cbed985601a58fa5e9d796161b0435b9a8ef547148f042200a
+dist/2025-02-08/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=3c6dcdea50189f815b16033dfc8524687d7101eafb266be8f16681fcf348dbd5
+dist/2025-02-08/rustc-nightly-x86_64-apple-darwin.tar.gz=43b2f1b7d16b46419d8fcede2b5b354ab778a1f2c3f59e691b71db8cfa00d727
+dist/2025-02-08/rustc-nightly-x86_64-apple-darwin.tar.xz=6f18083854625d41b5ace4aa8b33f9c1aadfba764a6cb8ce1d5986f745ddfe3c
+dist/2025-02-08/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=eba376122f9f9439aa2f6f08a08d496e07fd3e5ac99c82a69eab279e44755b8f
+dist/2025-02-08/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=e5b67e358ae1068482f6e09cdacb6f212b6b6c5e87056909b54182d21c6ba5bb
+dist/2025-02-08/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=310f2fc7bf1d32926d78e264638d2795718a1406209238c8c18ba76680c58fca
+dist/2025-02-08/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=f8915c772b352fd7f25a7f1be36c94f7b383b813d9dae139831c9f7f2b960de8
+dist/2025-02-08/rustc-nightly-x86_64-unknown-freebsd.tar.gz=05bd6715082b006f6d43c369f37c262732e4bb1c44cabe50a201ceb8556ce651
+dist/2025-02-08/rustc-nightly-x86_64-unknown-freebsd.tar.xz=d03c251f78273d4a3de99e650634d30287c4868031ddd3cc929cef8d7cb5d215
+dist/2025-02-08/rustc-nightly-x86_64-unknown-illumos.tar.gz=16804058f8c88358ae2ab0a8302acb092c27a459ca7217d30fde504746be14f9
+dist/2025-02-08/rustc-nightly-x86_64-unknown-illumos.tar.xz=b76535703edb204daf577e42b0a1ae2a41bfa18e0e3205fb5773e7ec12ec9fc7
+dist/2025-02-08/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=5a63f9f4ee7c5a91252ae8b235780ed6349641c9b6593e9038021c3a3927374d
+dist/2025-02-08/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=0a53b3706ab2981fadb020362dd497917f8361cc778a11d9a7fa05a3b329eea2
+dist/2025-02-08/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=ab4e3c5a4eaabf0f227b160efcf2f8d0e9a572d079ece83c6313fca9865a5dc3
+dist/2025-02-08/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=dcd74640d883aa75df93b86b041f98ef99178d5f39e78de3ff6801077703da32
+dist/2025-02-08/rustc-nightly-x86_64-unknown-netbsd.tar.gz=cdb3d9ac0651e3d44dbb50b3e341e609e228cbc4c358b126547a2909b807901a
+dist/2025-02-08/rustc-nightly-x86_64-unknown-netbsd.tar.xz=f4227393819e678dd67c579fc00b52fc1a3974e270f10593d8b550f7362b5a63
\ No newline at end of file
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index feec2a7444f..27b8c038ad2 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -67,6 +67,7 @@ static TARGETS: &[&str] = &[
     "aarch64-unknown-none-softfloat",
     "aarch64-unknown-redox",
     "aarch64-unknown-uefi",
+    "amdgcn-amd-amdhsa",
     "arm64e-apple-darwin",
     "arm64e-apple-ios",
     "arm64e-apple-tvos",
@@ -603,11 +604,14 @@ impl Builder {
             })
             .collect();
 
-        dst.insert(pkg.manifest_component_name(), Package {
-            version: version_info.version.unwrap_or_default(),
-            git_commit_hash: version_info.git_commit,
-            target: targets,
-        });
+        dst.insert(
+            pkg.manifest_component_name(),
+            Package {
+                version: version_info.version.unwrap_or_default(),
+                git_commit_hash: version_info.git_commit,
+                target: targets,
+            },
+        );
     }
 
     fn url(&self, path: &Path) -> String {
diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs
index b2dc044ec66..f51072718a3 100644
--- a/src/tools/bump-stage0/src/main.rs
+++ b/src/tools/bump-stage0/src/main.rs
@@ -50,7 +50,7 @@ impl Tool {
 #
 # All changes below this comment will be overridden the next time the
 # tool is executed.
-            "#;
+"#;
 
         let mut file_content = String::new();
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 0e3d73849ab8cbbab3ec5c65cbd555586cb2133
+Subproject 2928e32734b04925ee51e1ae88bea9a83d2fd45
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 48e9f1d690e..ca973f4bb1a 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -4,13 +4,13 @@ use clippy_utils::expr_or_init;
 use clippy_utils::source::snippet;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
+use rustc_abi::IntegerType;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, FloatTy, Ty};
 use rustc_span::Span;
-use rustc_target::abi::IntegerType;
 
 use super::{CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION, utils};
 
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 9fbeab5bf2e..5c5978b5559 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -144,8 +144,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::doc::DOC_NESTED_REFDEFS_INFO,
     crate::doc::DOC_OVERINDENTED_LIST_ITEMS_INFO,
     crate::doc::EMPTY_DOCS_INFO,
-    crate::doc::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
-    crate::doc::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
     crate::doc::MISSING_ERRORS_DOC_INFO,
     crate::doc::MISSING_PANICS_DOC_INFO,
     crate::doc::MISSING_SAFETY_DOC_INFO,
@@ -162,6 +160,8 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO,
     crate::empty_drop::EMPTY_DROP_INFO,
     crate::empty_enum::EMPTY_ENUM_INFO,
+    crate::empty_line_after::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
+    crate::empty_line_after::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
     crate::empty_with_brackets::EMPTY_ENUM_VARIANTS_WITH_BRACKETS_INFO,
     crate::empty_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO,
     crate::endian_bytes::BIG_ENDIAN_BYTES_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs
deleted file mode 100644
index 6e85c6af642..00000000000
--- a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs
+++ /dev/null
@@ -1,345 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{SpanRangeExt, snippet_indent};
-use clippy_utils::tokenize_with_text;
-use itertools::Itertools;
-use rustc_ast::AttrStyle;
-use rustc_ast::token::CommentKind;
-use rustc_errors::{Applicability, Diag, SuggestionStyle};
-use rustc_hir::{AttrKind, Attribute, ItemKind, Node};
-use rustc_lexer::TokenKind;
-use rustc_lint::LateContext;
-use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData};
-
-use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR};
-
-#[derive(Debug, PartialEq, Clone, Copy)]
-enum StopKind {
-    Attr,
-    Doc(CommentKind),
-}
-
-impl StopKind {
-    fn is_doc(self) -> bool {
-        matches!(self, StopKind::Doc(_))
-    }
-}
-
-#[derive(Debug)]
-struct Stop {
-    span: Span,
-    kind: StopKind,
-    first: usize,
-    last: usize,
-}
-
-impl Stop {
-    fn convert_to_inner(&self) -> (Span, String) {
-        let inner = match self.kind {
-            // #|[...]
-            StopKind::Attr => InnerSpan::new(1, 1),
-            // /// or /**
-            //   ^      ^
-            StopKind::Doc(_) => InnerSpan::new(2, 3),
-        };
-        (self.span.from_inner(inner), "!".into())
-    }
-
-    fn comment_out(&self, cx: &LateContext<'_>, suggestions: &mut Vec<(Span, String)>) {
-        match self.kind {
-            StopKind::Attr => {
-                if cx.tcx.sess.source_map().is_multiline(self.span) {
-                    suggestions.extend([
-                        (self.span.shrink_to_lo(), "/* ".into()),
-                        (self.span.shrink_to_hi(), " */".into()),
-                    ]);
-                } else {
-                    suggestions.push((self.span.shrink_to_lo(), "// ".into()));
-                }
-            },
-            StopKind::Doc(CommentKind::Line) => suggestions.push((self.span.shrink_to_lo(), "// ".into())),
-            StopKind::Doc(CommentKind::Block) => {
-                // /** outer */  /*! inner */
-                //  ^             ^
-                let asterisk = self.span.from_inner(InnerSpan::new(1, 2));
-                suggestions.push((asterisk, String::new()));
-            },
-        }
-    }
-
-    fn from_attr(cx: &LateContext<'_>, attr: &Attribute) -> Option<Self> {
-        let SpanData { lo, hi, .. } = attr.span.data();
-        let file = cx.tcx.sess.source_map().lookup_source_file(lo);
-
-        Some(Self {
-            span: attr.span,
-            kind: match attr.kind {
-                AttrKind::Normal(_) => StopKind::Attr,
-                AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind),
-            },
-            first: file.lookup_line(file.relative_position(lo))?,
-            last: file.lookup_line(file.relative_position(hi))?,
-        })
-    }
-}
-
-/// Represents a set of attrs/doc comments separated by 1 or more empty lines
-///
-/// ```ignore
-/// /// chunk 1 docs
-/// // not an empty line so also part of chunk 1
-/// #[chunk_1_attrs] // <-- prev_stop
-///
-/// /* gap */
-///
-/// /// chunk 2 docs // <-- next_stop
-/// #[chunk_2_attrs]
-/// ```
-struct Gap<'a> {
-    /// The span of individual empty lines including the newline at the end of the line
-    empty_lines: Vec<Span>,
-    has_comment: bool,
-    next_stop: &'a Stop,
-    prev_stop: &'a Stop,
-    /// The chunk that includes [`prev_stop`](Self::prev_stop)
-    prev_chunk: &'a [Stop],
-}
-
-impl<'a> Gap<'a> {
-    fn new(cx: &LateContext<'_>, prev_chunk: &'a [Stop], next_chunk: &'a [Stop]) -> Option<Self> {
-        let prev_stop = prev_chunk.last()?;
-        let next_stop = next_chunk.first()?;
-        let gap_span = prev_stop.span.between(next_stop.span);
-        let gap_snippet = gap_span.get_source_text(cx)?;
-
-        let mut has_comment = false;
-        let mut empty_lines = Vec::new();
-
-        for (token, source, inner_span) in tokenize_with_text(&gap_snippet) {
-            match token {
-                TokenKind::BlockComment {
-                    doc_style: None,
-                    terminated: true,
-                }
-                | TokenKind::LineComment { doc_style: None } => has_comment = true,
-                TokenKind::Whitespace => {
-                    let newlines = source.bytes().positions(|b| b == b'\n');
-                    empty_lines.extend(
-                        newlines
-                            .tuple_windows()
-                            .map(|(a, b)| InnerSpan::new(inner_span.start + a + 1, inner_span.start + b))
-                            .map(|inner_span| gap_span.from_inner(inner_span)),
-                    );
-                },
-                // Ignore cfg_attr'd out attributes as they may contain empty lines, could also be from macro
-                // shenanigans
-                _ => return None,
-            }
-        }
-
-        (!empty_lines.is_empty()).then_some(Self {
-            empty_lines,
-            has_comment,
-            next_stop,
-            prev_stop,
-            prev_chunk,
-        })
-    }
-
-    fn contiguous_empty_lines(&self) -> impl Iterator<Item = Span> + '_ {
-        self.empty_lines
-            // The `+ BytePos(1)` means "next line", because each empty line span is "N:1-N:1".
-            .chunk_by(|a, b| a.hi() + BytePos(1) == b.lo())
-            .map(|chunk| {
-                let first = chunk.first().expect("at least one empty line");
-                let last = chunk.last().expect("at least one empty line");
-                // The BytePos subtraction here is safe, as before an empty line, there must be at least one
-                // attribute/comment. The span needs to start at the end of the previous line.
-                first.with_lo(first.lo() - BytePos(1)).with_hi(last.hi())
-            })
-    }
-}
-
-/// If the node the attributes/docs apply to is the first in the module/crate suggest converting
-/// them to inner attributes/docs
-fn suggest_inner(cx: &LateContext<'_>, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>]) {
-    let Some(owner) = cx.last_node_with_lint_attrs.as_owner() else {
-        return;
-    };
-    let parent_desc = match cx.tcx.parent_hir_node(owner.into()) {
-        Node::Item(item)
-            if let ItemKind::Mod(parent_mod) = item.kind
-                && let [first, ..] = parent_mod.item_ids
-                && first.owner_id == owner =>
-        {
-            "parent module"
-        },
-        Node::Crate(crate_mod)
-            if let Some(first) = crate_mod
-                .item_ids
-                .iter()
-                .map(|&id| cx.tcx.hir().item(id))
-                // skip prelude imports
-                .find(|item| !matches!(item.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
-                && first.owner_id == owner =>
-        {
-            "crate"
-        },
-        _ => return,
-    };
-
-    diag.multipart_suggestion_verbose(
-        match kind {
-            StopKind::Attr => format!("if the attribute should apply to the {parent_desc} use an inner attribute"),
-            StopKind::Doc(_) => format!("if the comment should document the {parent_desc} use an inner doc comment"),
-        },
-        gaps.iter()
-            .flat_map(|gap| gap.prev_chunk)
-            .map(Stop::convert_to_inner)
-            .collect(),
-        Applicability::MaybeIncorrect,
-    );
-}
-
-fn check_gaps(cx: &LateContext<'_>, gaps: &[Gap<'_>]) -> bool {
-    let Some(first_gap) = gaps.first() else {
-        return false;
-    };
-    let empty_lines = || gaps.iter().flat_map(|gap| gap.empty_lines.iter().copied());
-    let contiguous_empty_lines = || gaps.iter().flat_map(Gap::contiguous_empty_lines);
-    let mut has_comment = false;
-    let mut has_attr = false;
-    for gap in gaps {
-        has_comment |= gap.has_comment;
-        if !has_attr {
-            has_attr = gap.prev_chunk.iter().any(|stop| stop.kind == StopKind::Attr);
-        }
-    }
-    let kind = first_gap.prev_stop.kind;
-    let (lint, kind_desc) = match kind {
-        StopKind::Attr => (EMPTY_LINE_AFTER_OUTER_ATTR, "outer attribute"),
-        StopKind::Doc(_) => (EMPTY_LINE_AFTER_DOC_COMMENTS, "doc comment"),
-    };
-    let (lines, are, them) = if empty_lines().nth(1).is_some() {
-        ("lines", "are", "them")
-    } else {
-        ("line", "is", "it")
-    };
-    span_lint_and_then(
-        cx,
-        lint,
-        first_gap.prev_stop.span.to(empty_lines().last().unwrap()),
-        format!("empty {lines} after {kind_desc}"),
-        |diag| {
-            if let Some(owner) = cx.last_node_with_lint_attrs.as_owner() {
-                let def_id = owner.to_def_id();
-                let def_descr = cx.tcx.def_descr(def_id);
-                diag.span_label(
-                    cx.tcx.def_span(def_id),
-                    match kind {
-                        StopKind::Attr => format!("the attribute applies to this {def_descr}"),
-                        StopKind::Doc(_) => format!("the comment documents this {def_descr}"),
-                    },
-                );
-            }
-
-            diag.multipart_suggestion_with_style(
-                format!("if the empty {lines} {are} unintentional remove {them}"),
-                contiguous_empty_lines()
-                    .map(|empty_lines| (empty_lines, String::new()))
-                    .collect(),
-                Applicability::MaybeIncorrect,
-                SuggestionStyle::HideCodeAlways,
-            );
-
-            if has_comment && kind.is_doc() {
-                // Likely doc comments that applied to some now commented out code
-                //
-                // /// Old docs for Foo
-                // // struct Foo;
-
-                let mut suggestions = Vec::new();
-                for stop in gaps.iter().flat_map(|gap| gap.prev_chunk) {
-                    stop.comment_out(cx, &mut suggestions);
-                }
-                let name = match cx.tcx.hir().opt_name(cx.last_node_with_lint_attrs) {
-                    Some(name) => format!("`{name}`"),
-                    None => "this".into(),
-                };
-                diag.multipart_suggestion_verbose(
-                    format!("if the doc comment should not document {name} comment it out"),
-                    suggestions,
-                    Applicability::MaybeIncorrect,
-                );
-            } else {
-                suggest_inner(cx, diag, kind, gaps);
-            }
-
-            if kind == StopKind::Doc(CommentKind::Line)
-                && gaps
-                    .iter()
-                    .all(|gap| !gap.has_comment && gap.next_stop.kind == StopKind::Doc(CommentKind::Line))
-            {
-                // Commentless empty gaps between line doc comments, possibly intended to be part of the markdown
-
-                let indent = snippet_indent(cx, first_gap.prev_stop.span).unwrap_or_default();
-                diag.multipart_suggestion_verbose(
-                    format!("if the documentation should include the empty {lines} include {them} in the comment"),
-                    empty_lines()
-                        .map(|empty_line| (empty_line, format!("{indent}///")))
-                        .collect(),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-        },
-    );
-    kind.is_doc()
-}
-
-/// Returns `true` if [`EMPTY_LINE_AFTER_DOC_COMMENTS`] triggered, used to skip other doc comment
-/// lints where they would be confusing
-///
-/// [`EMPTY_LINE_AFTER_OUTER_ATTR`] is also here to share an implementation but does not return
-/// `true` if it triggers
-pub(super) fn check(cx: &LateContext<'_>, attrs: &[Attribute]) -> bool {
-    let mut outer = attrs
-        .iter()
-        .filter(|attr| attr.style == AttrStyle::Outer && !attr.span.from_expansion())
-        .map(|attr| Stop::from_attr(cx, attr))
-        .collect::<Option<Vec<_>>>()
-        .unwrap_or_default();
-
-    if outer.is_empty() {
-        return false;
-    }
-
-    // Push a fake attribute Stop for the item itself so we check for gaps between the last outer
-    // attr/doc comment and the item they apply to
-    let span = cx.tcx.hir().span(cx.last_node_with_lint_attrs);
-    if !span.from_expansion()
-        && let Ok(line) = cx.tcx.sess.source_map().lookup_line(span.lo())
-    {
-        outer.push(Stop {
-            span,
-            kind: StopKind::Attr,
-            first: line.line,
-            // last doesn't need to be accurate here, we don't compare it with anything
-            last: line.line,
-        });
-    }
-
-    let mut gaps = Vec::new();
-    let mut last = 0;
-    for pos in outer
-        .array_windows()
-        .positions(|[a, b]| b.first.saturating_sub(a.last) > 1)
-    {
-        // we want to be after the first stop in the window
-        let pos = pos + 1;
-        if let Some(gap) = Gap::new(cx, &outer[last..pos], &outer[pos..]) {
-            last = pos;
-            gaps.push(gap);
-        }
-    }
-
-    check_gaps(cx, &gaps)
-}
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 3d8ce7becdb..42e1f7fd950 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -33,7 +33,6 @@ use rustc_span::{Span, sym};
 use std::ops::Range;
 use url::Url;
 
-mod empty_line_after;
 mod include_in_doc_without_cfg;
 mod link_with_quotes;
 mod markdown;
@@ -493,82 +492,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for empty lines after outer attributes
-    ///
-    /// ### Why is this bad?
-    /// The attribute may have meant to be an inner attribute (`#![attr]`). If
-    /// it was meant to be an outer attribute (`#[attr]`) then the empty line
-    /// should be removed
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[allow(dead_code)]
-    ///
-    /// fn not_quite_good_code() {}
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// // Good (as inner attribute)
-    /// #![allow(dead_code)]
-    ///
-    /// fn this_is_fine() {}
-    ///
-    /// // or
-    ///
-    /// // Good (as outer attribute)
-    /// #[allow(dead_code)]
-    /// fn this_is_fine_too() {}
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub EMPTY_LINE_AFTER_OUTER_ATTR,
-    suspicious,
-    "empty line after outer attribute"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for empty lines after doc comments.
-    ///
-    /// ### Why is this bad?
-    /// The doc comment may have meant to be an inner doc comment, regular
-    /// comment or applied to some old code that is now commented out. If it was
-    /// intended to be a doc comment, then the empty line should be removed.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// /// Some doc comment with a blank line after it.
-    ///
-    /// fn f() {}
-    ///
-    /// /// Docs for `old_code`
-    /// // fn old_code() {}
-    ///
-    /// fn new_code() {}
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// //! Convert it to an inner doc comment
-    ///
-    /// // Or a regular comment
-    ///
-    /// /// Or remove the empty line
-    /// fn f() {}
-    ///
-    /// // /// Docs for `old_code`
-    /// // fn old_code() {}
-    ///
-    /// fn new_code() {}
-    /// ```
-    #[clippy::version = "1.70.0"]
-    pub EMPTY_LINE_AFTER_DOC_COMMENTS,
-    suspicious,
-    "empty line after doc comments"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Checks if included files in doc comments are included only for `cfg(doc)`.
     ///
     /// ### Why restrict this?
@@ -650,8 +573,6 @@ impl_lint_pass!(Documentation => [
     EMPTY_DOCS,
     DOC_LAZY_CONTINUATION,
     DOC_OVERINDENTED_LIST_ITEMS,
-    EMPTY_LINE_AFTER_OUTER_ATTR,
-    EMPTY_LINE_AFTER_DOC_COMMENTS,
     TOO_LONG_FIRST_DOC_PARAGRAPH,
     DOC_INCLUDE_WITHOUT_CFG,
 ]);
@@ -784,7 +705,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
     }
 
     include_in_doc_without_cfg::check(cx, attrs);
-    if suspicious_doc_comments::check(cx, attrs) || empty_line_after::check(cx, attrs) || is_doc_hidden(attrs) {
+    if suspicious_doc_comments::check(cx, attrs) || is_doc_hidden(attrs) {
         return None;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/empty_line_after.rs
new file mode 100644
index 00000000000..578ff6e38a6
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/empty_line_after.rs
@@ -0,0 +1,492 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::{SpanRangeExt, snippet_indent};
+use clippy_utils::tokenize_with_text;
+use itertools::Itertools;
+use rustc_ast::token::CommentKind;
+use rustc_ast::{AssocItemKind, AttrKind, AttrStyle, Attribute, Crate, Item, ItemKind, ModKind, NodeId};
+use rustc_errors::{Applicability, Diag, SuggestionStyle};
+use rustc_lexer::TokenKind;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
+use rustc_session::impl_lint_pass;
+use rustc_span::symbol::kw;
+use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for empty lines after outer attributes
+    ///
+    /// ### Why is this bad?
+    /// The attribute may have meant to be an inner attribute (`#![attr]`). If
+    /// it was meant to be an outer attribute (`#[attr]`) then the empty line
+    /// should be removed
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[allow(dead_code)]
+    ///
+    /// fn not_quite_good_code() {}
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// // Good (as inner attribute)
+    /// #![allow(dead_code)]
+    ///
+    /// fn this_is_fine() {}
+    ///
+    /// // or
+    ///
+    /// // Good (as outer attribute)
+    /// #[allow(dead_code)]
+    /// fn this_is_fine_too() {}
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub EMPTY_LINE_AFTER_OUTER_ATTR,
+    suspicious,
+    "empty line after outer attribute"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for empty lines after doc comments.
+    ///
+    /// ### Why is this bad?
+    /// The doc comment may have meant to be an inner doc comment, regular
+    /// comment or applied to some old code that is now commented out. If it was
+    /// intended to be a doc comment, then the empty line should be removed.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// /// Some doc comment with a blank line after it.
+    ///
+    /// fn f() {}
+    ///
+    /// /// Docs for `old_code`
+    /// // fn old_code() {}
+    ///
+    /// fn new_code() {}
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// //! Convert it to an inner doc comment
+    ///
+    /// // Or a regular comment
+    ///
+    /// /// Or remove the empty line
+    /// fn f() {}
+    ///
+    /// // /// Docs for `old_code`
+    /// // fn old_code() {}
+    ///
+    /// fn new_code() {}
+    /// ```
+    #[clippy::version = "1.70.0"]
+    pub EMPTY_LINE_AFTER_DOC_COMMENTS,
+    suspicious,
+    "empty line after doc comments"
+}
+
+#[derive(Debug)]
+struct ItemInfo {
+    kind: &'static str,
+    name: Symbol,
+    span: Span,
+    mod_items: Option<NodeId>,
+}
+
+pub struct EmptyLineAfter {
+    items: Vec<ItemInfo>,
+}
+
+impl_lint_pass!(EmptyLineAfter => [
+    EMPTY_LINE_AFTER_OUTER_ATTR,
+    EMPTY_LINE_AFTER_DOC_COMMENTS,
+]);
+
+impl EmptyLineAfter {
+    pub fn new() -> Self {
+        Self { items: Vec::new() }
+    }
+}
+
+#[derive(Debug, PartialEq, Clone, Copy)]
+enum StopKind {
+    Attr,
+    Doc(CommentKind),
+}
+
+impl StopKind {
+    fn is_doc(self) -> bool {
+        matches!(self, StopKind::Doc(_))
+    }
+}
+
+#[derive(Debug)]
+struct Stop {
+    span: Span,
+    kind: StopKind,
+    first: usize,
+    last: usize,
+}
+
+impl Stop {
+    fn convert_to_inner(&self) -> (Span, String) {
+        let inner = match self.kind {
+            // #![...]
+            StopKind::Attr => InnerSpan::new(1, 1),
+            // /// or /**
+            //   ^      ^
+            StopKind::Doc(_) => InnerSpan::new(2, 3),
+        };
+        (self.span.from_inner(inner), "!".into())
+    }
+
+    fn comment_out(&self, cx: &EarlyContext<'_>, suggestions: &mut Vec<(Span, String)>) {
+        match self.kind {
+            StopKind::Attr => {
+                if cx.sess().source_map().is_multiline(self.span) {
+                    suggestions.extend([
+                        (self.span.shrink_to_lo(), "/* ".into()),
+                        (self.span.shrink_to_hi(), " */".into()),
+                    ]);
+                } else {
+                    suggestions.push((self.span.shrink_to_lo(), "// ".into()));
+                }
+            },
+            StopKind::Doc(CommentKind::Line) => suggestions.push((self.span.shrink_to_lo(), "// ".into())),
+            StopKind::Doc(CommentKind::Block) => {
+                // /** outer */  /*! inner */
+                //  ^             ^
+                let asterisk = self.span.from_inner(InnerSpan::new(1, 2));
+                suggestions.push((asterisk, String::new()));
+            },
+        }
+    }
+
+    fn from_attr(cx: &EarlyContext<'_>, attr: &Attribute) -> Option<Self> {
+        let SpanData { lo, hi, .. } = attr.span.data();
+        let file = cx.sess().source_map().lookup_source_file(lo);
+
+        Some(Self {
+            span: attr.span,
+            kind: match attr.kind {
+                AttrKind::Normal(_) => StopKind::Attr,
+                AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind),
+            },
+            first: file.lookup_line(file.relative_position(lo))?,
+            last: file.lookup_line(file.relative_position(hi))?,
+        })
+    }
+}
+
+/// Represents a set of attrs/doc comments separated by 1 or more empty lines
+///
+/// ```ignore
+/// /// chunk 1 docs
+/// // not an empty line so also part of chunk 1
+/// #[chunk_1_attrs] // <-- prev_stop
+///
+/// /* gap */
+///
+/// /// chunk 2 docs // <-- next_stop
+/// #[chunk_2_attrs]
+/// ```
+struct Gap<'a> {
+    /// The span of individual empty lines including the newline at the end of the line
+    empty_lines: Vec<Span>,
+    has_comment: bool,
+    next_stop: &'a Stop,
+    prev_stop: &'a Stop,
+    /// The chunk that includes [`prev_stop`](Self::prev_stop)
+    prev_chunk: &'a [Stop],
+}
+
+impl<'a> Gap<'a> {
+    fn new(cx: &EarlyContext<'_>, prev_chunk: &'a [Stop], next_chunk: &'a [Stop]) -> Option<Self> {
+        let prev_stop = prev_chunk.last()?;
+        let next_stop = next_chunk.first()?;
+        let gap_span = prev_stop.span.between(next_stop.span);
+        let gap_snippet = gap_span.get_source_text(cx)?;
+
+        let mut has_comment = false;
+        let mut empty_lines = Vec::new();
+
+        for (token, source, inner_span) in tokenize_with_text(&gap_snippet) {
+            match token {
+                TokenKind::BlockComment {
+                    doc_style: None,
+                    terminated: true,
+                }
+                | TokenKind::LineComment { doc_style: None } => has_comment = true,
+                TokenKind::Whitespace => {
+                    let newlines = source.bytes().positions(|b| b == b'\n');
+                    empty_lines.extend(
+                        newlines
+                            .tuple_windows()
+                            .map(|(a, b)| InnerSpan::new(inner_span.start + a + 1, inner_span.start + b))
+                            .map(|inner_span| gap_span.from_inner(inner_span)),
+                    );
+                },
+                // Ignore cfg_attr'd out attributes as they may contain empty lines, could also be from macro
+                // shenanigans
+                _ => return None,
+            }
+        }
+
+        (!empty_lines.is_empty()).then_some(Self {
+            empty_lines,
+            has_comment,
+            next_stop,
+            prev_stop,
+            prev_chunk,
+        })
+    }
+
+    fn contiguous_empty_lines(&self) -> impl Iterator<Item = Span> + '_ {
+        self.empty_lines
+            // The `+ BytePos(1)` means "next line", because each empty line span is "N:1-N:1".
+            .chunk_by(|a, b| a.hi() + BytePos(1) == b.lo())
+            .map(|chunk| {
+                let first = chunk.first().expect("at least one empty line");
+                let last = chunk.last().expect("at least one empty line");
+                // The BytePos subtraction here is safe, as before an empty line, there must be at least one
+                // attribute/comment. The span needs to start at the end of the previous line.
+                first.with_lo(first.lo() - BytePos(1)).with_hi(last.hi())
+            })
+    }
+}
+
+impl EmptyLineAfter {
+    fn check_gaps(&self, cx: &EarlyContext<'_>, gaps: &[Gap<'_>], id: NodeId) {
+        let Some(first_gap) = gaps.first() else {
+            return;
+        };
+        let empty_lines = || gaps.iter().flat_map(|gap| gap.empty_lines.iter().copied());
+        let contiguous_empty_lines = || gaps.iter().flat_map(Gap::contiguous_empty_lines);
+        let mut has_comment = false;
+        let mut has_attr = false;
+        for gap in gaps {
+            has_comment |= gap.has_comment;
+            if !has_attr {
+                has_attr = gap.prev_chunk.iter().any(|stop| stop.kind == StopKind::Attr);
+            }
+        }
+        let kind = first_gap.prev_stop.kind;
+        let (lint, kind_desc) = match kind {
+            StopKind::Attr => (EMPTY_LINE_AFTER_OUTER_ATTR, "outer attribute"),
+            StopKind::Doc(_) => (EMPTY_LINE_AFTER_DOC_COMMENTS, "doc comment"),
+        };
+        let (lines, are, them) = if empty_lines().nth(1).is_some() {
+            ("lines", "are", "them")
+        } else {
+            ("line", "is", "it")
+        };
+        span_lint_and_then(
+            cx,
+            lint,
+            first_gap.prev_stop.span.to(empty_lines().last().unwrap()),
+            format!("empty {lines} after {kind_desc}"),
+            |diag| {
+                let info = self.items.last().unwrap();
+                diag.span_label(info.span, match kind {
+                    StopKind::Attr => format!("the attribute applies to this {}", info.kind),
+                    StopKind::Doc(_) => format!("the comment documents this {}", info.kind),
+                });
+
+                diag.multipart_suggestion_with_style(
+                    format!("if the empty {lines} {are} unintentional, remove {them}"),
+                    contiguous_empty_lines()
+                        .map(|empty_lines| (empty_lines, String::new()))
+                        .collect(),
+                    Applicability::MaybeIncorrect,
+                    SuggestionStyle::HideCodeAlways,
+                );
+
+                if has_comment && kind.is_doc() {
+                    // Likely doc comments that applied to some now commented out code
+                    //
+                    // /// Old docs for Foo
+                    // // struct Foo;
+
+                    let mut suggestions = Vec::new();
+                    for stop in gaps.iter().flat_map(|gap| gap.prev_chunk) {
+                        stop.comment_out(cx, &mut suggestions);
+                    }
+                    diag.multipart_suggestion_verbose(
+                        format!("if the doc comment should not document `{}` comment it out", info.name),
+                        suggestions,
+                        Applicability::MaybeIncorrect,
+                    );
+                } else {
+                    self.suggest_inner(diag, kind, gaps, id);
+                }
+
+                if kind == StopKind::Doc(CommentKind::Line)
+                    && gaps
+                        .iter()
+                        .all(|gap| !gap.has_comment && gap.next_stop.kind == StopKind::Doc(CommentKind::Line))
+                {
+                    // Commentless empty gaps between line doc comments, possibly intended to be part of the markdown
+
+                    let indent = snippet_indent(cx, first_gap.prev_stop.span).unwrap_or_default();
+                    diag.multipart_suggestion_verbose(
+                        format!("if the documentation should include the empty {lines} include {them} in the comment"),
+                        empty_lines()
+                            .map(|empty_line| (empty_line, format!("{indent}///")))
+                            .collect(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+            },
+        );
+    }
+
+    /// If the node the attributes/docs apply to is the first in the module/crate suggest converting
+    /// them to inner attributes/docs
+    fn suggest_inner(&self, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>], id: NodeId) {
+        if let Some(parent) = self.items.iter().rev().nth(1)
+            && (parent.kind == "module" || parent.kind == "crate")
+            && parent.mod_items == Some(id)
+        {
+            let desc = if parent.kind == "module" {
+                "parent module"
+            } else {
+                parent.kind
+            };
+            diag.multipart_suggestion_verbose(
+                match kind {
+                    StopKind::Attr => format!("if the attribute should apply to the {desc} use an inner attribute"),
+                    StopKind::Doc(_) => format!("if the comment should document the {desc} use an inner doc comment"),
+                },
+                gaps.iter()
+                    .flat_map(|gap| gap.prev_chunk)
+                    .map(Stop::convert_to_inner)
+                    .collect(),
+                Applicability::MaybeIncorrect,
+            );
+        }
+    }
+
+    fn check_item_kind(
+        &mut self,
+        cx: &EarlyContext<'_>,
+        kind: &ItemKind,
+        ident: &Ident,
+        span: Span,
+        attrs: &[Attribute],
+        id: NodeId,
+    ) {
+        self.items.push(ItemInfo {
+            kind: kind.descr(),
+            name: ident.name,
+            span: if span.contains(ident.span) {
+                span.with_hi(ident.span.hi())
+            } else {
+                span.with_hi(span.lo())
+            },
+            mod_items: match kind {
+                ItemKind::Mod(_, ModKind::Loaded(items, _, _, _)) => items
+                    .iter()
+                    .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
+                    .map(|i| i.id)
+                    .next(),
+                _ => None,
+            },
+        });
+
+        let mut outer = attrs
+            .iter()
+            .filter(|attr| attr.style == AttrStyle::Outer && !attr.span.from_expansion())
+            .map(|attr| Stop::from_attr(cx, attr))
+            .collect::<Option<Vec<_>>>()
+            .unwrap_or_default();
+
+        if outer.is_empty() {
+            return;
+        }
+
+        // Push a fake attribute Stop for the item itself so we check for gaps between the last outer
+        // attr/doc comment and the item they apply to
+        let span = self.items.last().unwrap().span;
+        if !span.from_expansion()
+            && let Ok(line) = cx.sess().source_map().lookup_line(span.lo())
+        {
+            outer.push(Stop {
+                span,
+                kind: StopKind::Attr,
+                first: line.line,
+                // last doesn't need to be accurate here, we don't compare it with anything
+                last: line.line,
+            });
+        }
+
+        let mut gaps = Vec::new();
+        let mut last = 0;
+        for pos in outer
+            .array_windows()
+            .positions(|[a, b]| b.first.saturating_sub(a.last) > 1)
+        {
+            // we want to be after the first stop in the window
+            let pos = pos + 1;
+            if let Some(gap) = Gap::new(cx, &outer[last..pos], &outer[pos..]) {
+                last = pos;
+                gaps.push(gap);
+            }
+        }
+
+        self.check_gaps(cx, &gaps, id);
+    }
+}
+
+impl EarlyLintPass for EmptyLineAfter {
+    fn check_crate(&mut self, _: &EarlyContext<'_>, krate: &Crate) {
+        self.items.push(ItemInfo {
+            kind: "crate",
+            name: kw::Crate,
+            span: krate.spans.inner_span.with_hi(krate.spans.inner_span.lo()),
+            mod_items: krate
+                .items
+                .iter()
+                .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
+                .map(|i| i.id)
+                .next(),
+        });
+    }
+
+    fn check_item_post(&mut self, _: &EarlyContext<'_>, _: &Item) {
+        self.items.pop();
+    }
+    fn check_impl_item_post(&mut self, _: &EarlyContext<'_>, _: &Item<AssocItemKind>) {
+        self.items.pop();
+    }
+    fn check_trait_item_post(&mut self, _: &EarlyContext<'_>, _: &Item<AssocItemKind>) {
+        self.items.pop();
+    }
+
+    fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &Item<AssocItemKind>) {
+        self.check_item_kind(
+            cx,
+            &item.kind.clone().into(),
+            &item.ident,
+            item.span,
+            &item.attrs,
+            item.id,
+        );
+    }
+
+    fn check_trait_item(&mut self, cx: &EarlyContext<'_>, item: &Item<AssocItemKind>) {
+        self.check_item_kind(
+            cx,
+            &item.kind.clone().into(),
+            &item.ident,
+            item.span,
+            &item.attrs,
+            item.id,
+        );
+    }
+
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        self.check_item_kind(cx, &item.kind, &item.ident, item.span, &item.attrs, item.id);
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index a89f0d9c432..c55d4387d69 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -10,7 +10,7 @@ use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 pub struct BoxedLocal {
     too_large_for_stack: u64,
@@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
         fn_def_id: LocalDefId,
     ) {
         if let Some(header) = fn_kind.header() {
-            if header.abi != Abi::Rust {
+            if header.abi != ExternAbi::Rust {
                 return;
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index f90bf9157aa..ae3acc1c4b1 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::{
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt as _;
 
 declare_clippy_lint! {
@@ -172,7 +172,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
                         && let output = typeck.expr_ty(body.value)
                         && let ty::Tuple(tys) = *subs.type_at(1).kind()
                     {
-                        cx.tcx.mk_fn_sig(tys, output, false, Safety::Safe, Abi::Rust)
+                        cx.tcx.mk_fn_sig(tys, output, false, Safety::Safe, ExternAbi::Rust)
                     } else {
                         return;
                     }
diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
index 0011da03dda..15afe3e8c14 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
@@ -7,7 +7,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'tcx>) {
         // functions with a body are already checked by `check_fn`
         if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind
-            && fn_sig.header.abi == Abi::Rust
+            && fn_sig.header.abi == ExternAbi::Rust
             && fn_sig.decl.inputs.len() as u64 > self.max_fn_params_bools
         {
             check_fn_decl(cx, fn_sig.decl, fn_sig.span, self.max_fn_params_bools);
@@ -162,7 +162,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
         def_id: LocalDefId,
     ) {
         if let Some(fn_header) = fn_kind.header()
-            && fn_header.abi == Abi::Rust
+            && fn_header.abi == ExternAbi::Rust
             && fn_decl.inputs.len() as u64 > self.max_fn_params_bools
             && get_parent_as_impl(cx.tcx, cx.tcx.local_def_id_to_hir_id(def_id))
                 .is_none_or(|impl_item| impl_item.of_trait.is_none())
diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
index e72a2ad49d8..f17f687719f 100644
--- a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
@@ -1,7 +1,7 @@
 use rustc_hir::{self as hir, intravisit};
 use rustc_lint::LateContext;
 use rustc_span::Span;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_trait_impl_item;
@@ -23,11 +23,11 @@ pub(super) fn check_fn(
             intravisit::FnKind::Method(
                 _,
                 &hir::FnSig {
-                    header: hir::FnHeader { abi: Abi::Rust, .. },
+                    header: hir::FnHeader { abi: ExternAbi::Rust, .. },
                     ..
                 },
             )
-            | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }) => check_arg_number(
+            | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: ExternAbi::Rust, .. }) => check_arg_number(
                 cx,
                 decl,
                 span.with_hi(decl.output.span().hi()),
@@ -41,7 +41,7 @@ pub(super) fn check_fn(
 pub(super) fn check_trait_item(cx: &LateContext<'_>, item: &hir::TraitItem<'_>, too_many_arguments_threshold: u64) {
     if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
         // don't lint extern functions decls, it's not their fault
-        if sig.header.abi == Abi::Rust {
+        if sig.header.abi == ExternAbi::Rust {
             check_arg_number(
                 cx,
                 sig.decl,
diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
index 415b47adac5..c58e8773e3a 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
@@ -5,7 +5,7 @@ use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
             // #11201
             && let header = signature.header
             && header.is_safe()
-            && header.abi == Abi::Rust
+            && header.abi == ExternAbi::Rust
             && impl_item.ident.name == sym::to_string
             && let decl = signature.decl
             && decl.implicit_self.has_implicit_self()
diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs
index 593704f206a..fd7965d564d 100644
--- a/src/tools/clippy/clippy_lints/src/large_futures.rs
+++ b/src/tools/clippy/clippy_lints/src/large_futures.rs
@@ -2,11 +2,11 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::implements_trait;
+use rustc_abi::Size;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, LangItem, MatchSource, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_target::abi::Size;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 8887ab7ec0d..13218331a67 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -126,6 +126,7 @@ mod duplicate_mod;
 mod else_if_without_else;
 mod empty_drop;
 mod empty_enum;
+mod empty_line_after;
 mod empty_with_brackets;
 mod endian_bytes;
 mod entry;
@@ -973,6 +974,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| Box::new(unused_trait_names::UnusedTraitNames::new(conf)));
     store.register_late_pass(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp));
     store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound));
+    store.register_early_pass(|| Box::new(empty_line_after::EmptyLineAfter::new()));
     store.register_late_pass(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf)));
     store.register_late_pass(|_| Box::new(unneeded_struct_pattern::UnneededStructPattern));
     store.register_late_pass(|_| Box::<unnecessary_semicolon::UnnecessarySemicolon>::default());
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index f501cf060c2..0a8eafad0e8 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -149,6 +149,7 @@ use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
 use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty};
 pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;
+use rustc_abi::ExternAbi;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
@@ -5447,7 +5448,7 @@ const FN_HEADER: hir::FnHeader = hir::FnHeader {
     safety: hir::HeaderSafety::Normal(hir::Safety::Safe),
     constness: hir::Constness::NotConst,
     asyncness: hir::IsAsync::NotAsync,
-    abi: rustc_target::spec::abi::Abi::Rust,
+    abi: ExternAbi::Rust,
 };
 
 struct ShouldImplTraitCase {
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 962d85c6a9d..ba4af134ccd 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -1,3 +1,4 @@
+
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::msrvs::{self, Msrv};
@@ -12,7 +13,7 @@ use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -183,11 +184,11 @@ fn already_const(header: hir::FnHeader) -> bool {
     header.constness == Constness::Const
 }
 
-fn could_be_const_with_abi(msrv: &Msrv, abi: Abi) -> bool {
+fn could_be_const_with_abi(msrv: &Msrv, abi: ExternAbi) -> bool {
     match abi {
-        Abi::Rust => true,
+        ExternAbi::Rust => true,
         // `const extern "C"` was stabilized after 1.62.0
-        Abi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_C_FN),
+        ExternAbi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_C_FN),
         // Rest ABIs are still unstable and need the `const_extern_fn` feature enabled.
         _ => msrv.meets(msrvs::CONST_EXTERN_FN),
     }
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 b7dc269061c..996251fdf16 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
@@ -20,7 +20,7 @@ use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -149,7 +149,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
                     return;
                 }
                 let attrs = cx.tcx.hir().attrs(hir_id);
-                if header.abi != Abi::Rust || requires_exact_signature(attrs) {
+                if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) {
                     return;
                 }
                 header.is_async()
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 2855703b9d5..40c65d1ef9e 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
@@ -19,7 +19,7 @@ use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
 use rustc_span::{Span, sym};
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy;
 
@@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
         match kind {
             FnKind::ItemFn(.., header) => {
                 let attrs = cx.tcx.hir().attrs(hir_id);
-                if header.abi != Abi::Rust || requires_exact_signature(attrs) {
+                if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) {
                     return;
                 }
             },
diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
index 2e2916c957d..b73b9083a99 100644
--- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
+++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
@@ -5,7 +5,7 @@ use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::{BytePos, Pos};
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
             for attr in attrs {
                 if let Some(ident) = attr.ident()
                     && ident.name == rustc_span::sym::no_mangle
-                    && fn_sig.header.abi == Abi::Rust
+                    && fn_sig.header.abi == ExternAbi::Rust
                     && let Some((fn_attrs, _)) = fn_snippet.rsplit_once("fn")
                     && !fn_attrs.contains("extern")
                 {
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 147654675ec..405bbfc9c6f 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -5,6 +5,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_in_const_context;
 use clippy_utils::macros::macro_backtrace;
 use clippy_utils::ty::{InteriorMut, implements_trait};
+use rustc_abi::VariantIdx;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
@@ -16,7 +17,6 @@ use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::impl_lint_pass;
 use rustc_span::{DUMMY_SP, Span, sym};
-use rustc_target::abi::VariantIdx;
 
 // FIXME: this is a correctness problem but there's no suitable
 // warn-by-default category.
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index b2089487a9f..a3e89671eec 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -19,7 +19,7 @@ use rustc_middle::ty::{self, RegionKind, TyCtxt};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{Span, sym};
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -277,7 +277,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
         let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
         match kind {
             FnKind::ItemFn(.., header) => {
-                if header.abi != Abi::Rust {
+                if header.abi != ExternAbi::Rust {
                     return;
                 }
                 let attrs = cx.tcx.hir().attrs(hir_id);
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 0b67594a9b1..7fba4b6a6c8 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -19,7 +19,7 @@ use rustc_middle::ty::{self, Binder, ClauseKind, ExistentialPredicate, List, Pre
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, sym};
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use std::{fmt, iter};
@@ -160,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
 
             check_mut_from_ref(cx, sig, None);
 
-            if !matches!(sig.header.abi, Abi::Rust) {
+            if !matches!(sig.header.abi, ExternAbi::Rust) {
                 // Ignore `extern` functions with non-Rust calling conventions
                 return;
             }
@@ -220,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
 
         check_mut_from_ref(cx, sig, Some(body));
 
-        if !matches!(sig.header.abi, Abi::Rust) {
+        if !matches!(sig.header.abi, ExternAbi::Rust) {
             // Ignore `extern` functions with non-Rust calling conventions
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
index 7f51660293b..0704653385f 100644
--- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
@@ -1,9 +1,9 @@
 use clippy_utils::diagnostics::span_lint;
+use rustc_abi::ExternAbi;
 use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
 use rustc_hir::{self as hir, AmbigArg, GenericParamKind, TyKind};
 use rustc_lint::LateContext;
 use rustc_span::Span;
-use rustc_target::spec::abi::Abi;
 
 use super::TYPE_COMPLEXITY;
 
@@ -50,7 +50,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
             TyKind::Path(..) | TyKind::Slice(..) | TyKind::Tup(..) | TyKind::Array(..) => (10 * self.nest, 1),
 
             // function types bring a lot of overhead
-            TyKind::BareFn(bare) if bare.abi == Abi::Rust => (50 * self.nest, 1),
+            TyKind::BareFn(bare) if bare.abi == ExternAbi::Rust => (50 * self.nest, 1),
 
             TyKind::TraitObject(param_bounds, _) => {
                 let has_lifetime_parameters = param_bounds.iter().any(|bound| {
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index 179d42a8b5d..59aaaa3d9fb 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -12,6 +12,7 @@
 //! code was written, and check if the span contains that text. Note this will only work correctly
 //! if the span is not from a `macro_rules` based macro.
 
+use rustc_abi::ExternAbi;
 use rustc_ast::AttrStyle;
 use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, TraitObjectSyntax, UintTy};
 use rustc_ast::token::CommentKind;
@@ -26,7 +27,6 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use rustc_span::symbol::{Ident, kw};
 use rustc_span::{Span, Symbol};
-use rustc_target::spec::abi::Abi;
 
 /// The search pattern to look for. Used by `span_matches_pat`
 #[derive(Clone)]
@@ -233,7 +233,7 @@ fn fn_header_search_pat(header: FnHeader) -> Pat {
         Pat::Str("const")
     } else if header.is_unsafe() {
         Pat::Str("unsafe")
-    } else if header.abi != Abi::Rust {
+    } else if header.abi != ExternAbi::Rust {
         Pat::Str("extern")
     } else {
         Pat::MultiStr(&["fn", "extern"])
@@ -375,7 +375,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {
         TyKind::BareFn(bare_fn) => (
             if bare_fn.safety.is_unsafe() {
                 Pat::Str("unsafe")
-            } else if bare_fn.abi != Abi::Rust {
+            } else if bare_fn.abi != ExternAbi::Rust {
                 Pat::Str("extern")
             } else {
                 Pat::MultiStr(&["fn", "extern"])
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index fab1db05d2e..db82c458f70 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -9,6 +9,7 @@ use std::sync::Arc;
 use crate::source::{SpanRangeExt, walk_span_to_context};
 use crate::{clip, is_direct_expn_of, sext, unsext};
 
+use rustc_abi::Size;
 use rustc_apfloat::Float;
 use rustc_apfloat::ieee::{Half, Quad};
 use rustc_ast::ast::{self, LitFloatType, LitKind};
@@ -25,7 +26,6 @@ use rustc_middle::{bug, mir, span_bug};
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::Ident;
 use rustc_span::{SyntaxContext, sym};
-use rustc_target::abi::Size;
 use std::cell::Cell;
 use std::cmp::Ordering;
 use std::hash::{Hash, Hasher};
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 337684b68f8..79cc5066580 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -29,6 +29,7 @@
 
 // FIXME: switch to something more ergonomic here, once available.
 // (Currently there is no way to opt into sysroot crates without `extern crate`.)
+extern crate rustc_abi;
 extern crate rustc_ast;
 extern crate rustc_ast_pretty;
 extern crate rustc_attr_parsing;
@@ -48,7 +49,6 @@ extern crate rustc_middle;
 extern crate rustc_mir_dataflow;
 extern crate rustc_session;
 extern crate rustc_span;
-extern crate rustc_target;
 extern crate rustc_trait_selection;
 extern crate smallvec;
 
@@ -123,7 +123,7 @@ use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{Ident, Symbol, kw};
 use rustc_span::{InnerSpan, Span, sym};
-use rustc_target::abi::Integer;
+use rustc_abi::Integer;
 use visitors::{Visitable, for_each_unconsumed_temporary};
 
 use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index e9a05c45747..a5374f6904e 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -4,6 +4,7 @@
 
 use core::ops::ControlFlow;
 use itertools::Itertools;
+use rustc_abi::VariantIdx;
 use rustc_ast::ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
@@ -23,7 +24,6 @@ use rustc_middle::ty::{
 };
 use rustc_span::symbol::Ident;
 use rustc_span::{DUMMY_SP, Span, Symbol, sym};
-use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
 use rustc_trait_selection::traits::{Obligation, ObligationCause};
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
index 04446787b6c..a065654e319 100644
--- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
@@ -66,3 +66,19 @@ fn escape_3() {}
 
 /// Backslashes ` \` within code blocks don't count.
 fn escape_4() {}
+
+trait Foo {
+    fn bar();
+}
+
+struct Bar;
+impl Foo for Bar {
+    // NOTE: false positive
+    /// Returns an `Option<Month>` from a i64, assuming a 1-index, January = 1.
+    ///
+    /// `Month::from_i64(n: i64)`: | `1`                  | `2`                   | ... | `12`
+    /// ---------------------------| -------------------- | --------------------- | ... | -----
+    /// ``:                        | Some(Month::January) | Some(Month::February) | ... |
+    /// Some(Month::December)
+    fn bar() {}
+}
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
index 50324010e97..c9fd25eb1a1 100644
--- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
@@ -94,5 +94,17 @@ LL | /// Escaped \` ` backticks don't count, but unescaped backticks do.
    |
    = help: a backtick may be missing a pair
 
-error: aborting due to 10 previous errors
+error: backticks are unbalanced
+  --> tests/ui/doc/unbalanced_ticks.rs:79:9
+   |
+LL |       /// `Month::from_i64(n: i64)`: | `1`                  | `2`                   | ... | `12`
+   |  _________^
+LL | |     /// ---------------------------| -------------------- | --------------------- | ... | -----
+LL | |     /// ``:                        | Some(Month::January) | Some(Month::February) | ... |
+LL | |     /// Some(Month::December)
+   | |_____________________________^
+   |
+   = help: a backtick may be missing a pair
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed
index fd6a94b6a80..3772b465fdb 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed
@@ -132,4 +132,13 @@ pub struct BlockComment;
 ))]
 fn empty_line_in_cfg_attr() {}
 
+trait Foo {
+    fn bar();
+}
+
+impl Foo for LineComment {
+    /// comment on assoc item
+    fn bar() {}
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed
index 7a57dcd9233..3028d03b669 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed
@@ -141,4 +141,13 @@ pub struct BlockComment;
 ))]
 fn empty_line_in_cfg_attr() {}
 
+trait Foo {
+    fn bar();
+}
+
+impl Foo for LineComment {
+    /// comment on assoc item
+    fn bar() {}
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs
index 1da761a5c3d..ae4ebc271fa 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs
@@ -144,4 +144,14 @@ pub struct BlockComment;
 ))]
 fn empty_line_in_cfg_attr() {}
 
+trait Foo {
+    fn bar();
+}
+
+impl Foo for LineComment {
+    /// comment on assoc item
+
+    fn bar() {}
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
index c5d5f3d3759..7b197ae67e0 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
@@ -5,11 +5,11 @@ LL | / /// for the crate
 LL | |
    | |_^
 LL |   fn first_in_crate() {}
-   |   ------------------- the comment documents this function
+   |   ----------------- the comment documents this function
    |
    = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]`
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the comment should document the crate use an inner doc comment
    |
 LL ~ //! Meant to be an
@@ -24,9 +24,9 @@ LL | /     /// for the module
 LL | |
    | |_^
 LL |       fn first_in_module() {}
-   |       -------------------- the comment documents this function
+   |       ------------------ the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the comment should document the parent module use an inner doc comment
    |
 LL ~     //! Meant to be an
@@ -42,9 +42,9 @@ LL | |
    | |_^
 LL |       /// Blank line
 LL |       fn indented() {}
-   |       ------------- the comment documents this function
+   |       ----------- the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the documentation should include the empty line include it in the comment
    |
 LL |     ///
@@ -57,9 +57,9 @@ LL | / /// This should produce a warning
 LL | |
    | |_^
 LL |   fn with_doc_and_newline() {}
-   |   ------------------------- the comment documents this function
+   |   ----------------------- the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 
 error: empty lines after doc comment
   --> tests/ui/empty_line_after/doc_comments.rs:44:1
@@ -72,9 +72,9 @@ LL | |
    | |_^
 ...
 LL |   fn three_attributes() {}
-   |   --------------------- the comment documents this function
+   |   ------------------- the comment documents this function
    |
-   = help: if the empty lines are unintentional remove them
+   = help: if the empty lines are unintentional, remove them
 
 error: empty line after doc comment
   --> tests/ui/empty_line_after/doc_comments.rs:56:5
@@ -84,9 +84,9 @@ LL | |     // fn old_code() {}
 LL | |
    | |_^
 LL |       fn new_code() {}
-   |       ------------- the comment documents this function
+   |       ----------- the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the doc comment should not document `new_code` comment it out
    |
 LL |     // /// docs for `old_code`
@@ -106,7 +106,7 @@ LL | |
 LL |       struct Multiple;
    |       --------------- the comment documents this struct
    |
-   = help: if the empty lines are unintentional remove them
+   = help: if the empty lines are unintentional, remove them
 help: if the doc comment should not document `Multiple` comment it out
    |
 LL ~     // /// Docs
@@ -126,9 +126,9 @@ LL | |      */
 LL | |
    | |_^
 LL |       fn first_in_module() {}
-   |       -------------------- the comment documents this function
+   |       ------------------ the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the comment should document the parent module use an inner doc comment
    |
 LL |     /*!
@@ -145,9 +145,9 @@ LL | |
    | |_^
 ...
 LL |       fn new_code() {}
-   |       ------------- the comment documents this function
+   |       ----------- the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the doc comment should not document `new_code` comment it out
    |
 LL -     /**
@@ -163,13 +163,24 @@ LL | |
    | |_^
 LL |       /// Docs for `new_code2`
 LL |       fn new_code2() {}
-   |       -------------- the comment documents this function
+   |       ------------ the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the doc comment should not document `new_code2` comment it out
    |
 LL |     // /// Docs for `old_code2`
    |     ++
 
-error: aborting due to 10 previous errors
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:152:5
+   |
+LL | /     /// comment on assoc item
+LL | |
+   | |_^
+LL |       fn bar() {}
+   |       ------ the comment documents this function
+   |
+   = help: if the empty line is unintentional, remove it
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
index a95306e2fa3..519ba6e6761 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
@@ -5,11 +5,11 @@ LL | / #[crate_type = "lib"]
 LL | |
    | |_^
 LL |   fn first_in_crate() {}
-   |   ------------------- the attribute applies to this function
+   |   ----------------- the attribute applies to this function
    |
    = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]`
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the attribute should apply to the crate use an inner attribute
    |
 LL | #![crate_type = "lib"]
@@ -23,9 +23,9 @@ LL | |
    | |_^
 LL |   /// some comment
 LL |   fn with_one_newline_and_comment() {}
-   |   --------------------------------- the attribute applies to this function
+   |   ------------------------------- the attribute applies to this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 
 error: empty line after outer attribute
   --> tests/ui/empty_line_after/outer_attribute.rs:23:1
@@ -34,9 +34,9 @@ LL | / #[inline]
 LL | |
    | |_^
 LL |   fn with_one_newline() {}
-   |   --------------------- the attribute applies to this function
+   |   ------------------- the attribute applies to this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 
 error: empty lines after outer attribute
   --> tests/ui/empty_line_after/outer_attribute.rs:30:5
@@ -46,9 +46,9 @@ LL | |
 LL | |
    | |_^
 LL |       fn with_two_newlines() {}
-   |       ---------------------- the attribute applies to this function
+   |       -------------------- the attribute applies to this function
    |
-   = help: if the empty lines are unintentional remove them
+   = help: if the empty lines are unintentional, remove them
 help: if the attribute should apply to the parent module use an inner attribute
    |
 LL |     #![crate_type = "lib"]
@@ -63,7 +63,7 @@ LL | |
 LL |   enum Baz {
    |   -------- the attribute applies to this enum
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 
 error: empty line after outer attribute
   --> tests/ui/empty_line_after/outer_attribute.rs:45:1
@@ -74,7 +74,7 @@ LL | |
 LL |   struct Foo {
    |   ---------- the attribute applies to this struct
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 
 error: empty line after outer attribute
   --> tests/ui/empty_line_after/outer_attribute.rs:53:1
@@ -85,7 +85,7 @@ LL | |
 LL |   mod foo {}
    |   ------- the attribute applies to this module
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 
 error: empty line after outer attribute
   --> tests/ui/empty_line_after/outer_attribute.rs:58:1
@@ -95,9 +95,9 @@ LL | | // Still lint cases where the empty line does not immediately follow the
 LL | |
    | |_^
 LL |   fn comment_before_empty_line() {}
-   |   ------------------------------ the attribute applies to this function
+   |   ---------------------------- the attribute applies to this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 
 error: empty lines after outer attribute
   --> tests/ui/empty_line_after/outer_attribute.rs:64:1
@@ -107,9 +107,9 @@ LL | / #[allow(unused)]
 LL | |
    | |_^
 LL |   pub fn isolated_comment() {}
-   |   ------------------------- the attribute applies to this function
+   |   ----------------------- the attribute applies to this function
    |
-   = help: if the empty lines are unintentional remove them
+   = help: if the empty lines are unintentional, remove them
 
 error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
index 614fc03571e..d3df6a41cb1 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
@@ -1,5 +1,6 @@
 #![allow(unused)]
 #![warn(clippy::suspicious_doc_comments)]
+#![allow(clippy::empty_line_after_doc_comments)]
 
 //! Real module documentation.
 //! Fake module documentation.
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
index 7dcba0fefc9..04db2b199c0 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
@@ -1,5 +1,6 @@
 #![allow(unused)]
 #![warn(clippy::suspicious_doc_comments)]
+#![allow(clippy::empty_line_after_doc_comments)]
 
 //! Real module documentation.
 ///! Fake module documentation.
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
index f12053b1595..c34e39cd0fc 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
@@ -1,5 +1,5 @@
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:5:1
+  --> tests/ui/suspicious_doc_comments.rs:6:1
    |
 LL | ///! Fake module documentation.
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -12,7 +12,7 @@ LL | //! Fake module documentation.
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:9:5
+  --> tests/ui/suspicious_doc_comments.rs:10:5
    |
 LL |     ///! This module contains useful functions.
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     //! This module contains useful functions.
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:21:5
+  --> tests/ui/suspicious_doc_comments.rs:22:5
    |
 LL | /     /**! This module contains useful functions.
 LL | |      */
@@ -36,7 +36,7 @@ LL +      */
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:35:5
+  --> tests/ui/suspicious_doc_comments.rs:36:5
    |
 LL | /     ///! This module
 LL | |     ///! contains
@@ -51,7 +51,7 @@ LL ~     //! useful functions.
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:43:5
+  --> tests/ui/suspicious_doc_comments.rs:44:5
    |
 LL | /     ///! a
 LL | |     ///! b
@@ -64,7 +64,7 @@ LL ~     //! b
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:51:5
+  --> tests/ui/suspicious_doc_comments.rs:52:5
    |
 LL |     ///! a
    |     ^^^^^^
@@ -75,7 +75,7 @@ LL |     //! a
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:57:5
+  --> tests/ui/suspicious_doc_comments.rs:58:5
    |
 LL | /     ///! a
 LL | |
@@ -90,7 +90,7 @@ LL ~     //! b
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:69:5
+  --> tests/ui/suspicious_doc_comments.rs:70:5
    |
 LL |     ///! Very cool macro
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -101,7 +101,7 @@ LL |     //! Very cool macro
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:76:5
+  --> tests/ui/suspicious_doc_comments.rs:77:5
    |
 LL |     ///! Huh.
    |     ^^^^^^^^^
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 00821fc9f9d..cde4f7a665c 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -224,7 +224,9 @@ pub struct Config {
     /// The directory containing the compiler sysroot
     pub sysroot_base: PathBuf,
 
-    /// The name of the stage being built (stage1, etc)
+    /// The number of the stage under test.
+    pub stage: u32,
+    /// The id of the stage under test (stage1-xxx, etc).
     pub stage_id: String,
 
     /// The test mode, e.g. ui or debuginfo.
diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs
index 6e5ced17c20..cfe51b5655f 100644
--- a/src/tools/compiletest/src/header/cfg.rs
+++ b/src/tools/compiletest/src/header/cfg.rs
@@ -192,7 +192,7 @@ fn parse_cfg_name_directive<'a>(
         message: "on big-endian targets",
     }
     condition! {
-        name: config.stage_id.split('-').next().unwrap(),
+        name: format!("stage{}", config.stage).as_str(),
         allowed_names: &["stage0", "stage1", "stage2"],
         message: "when the bootstrapping stage is {name}",
     }
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index ebba16d41f9..522d340b678 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -72,6 +72,7 @@ struct ConfigBuilder {
     channel: Option<String>,
     host: Option<String>,
     target: Option<String>,
+    stage: Option<u32>,
     stage_id: Option<String>,
     llvm_version: Option<String>,
     git_hash: bool,
@@ -102,6 +103,11 @@ impl ConfigBuilder {
         self
     }
 
+    fn stage(&mut self, n: u32) -> &mut Self {
+        self.stage = Some(n);
+        self
+    }
+
     fn stage_id(&mut self, s: &str) -> &mut Self {
         self.stage_id = Some(s.to_owned());
         self
@@ -156,6 +162,8 @@ impl ConfigBuilder {
             "--cxxflags=",
             "--llvm-components=",
             "--android-cross-path=",
+            "--stage",
+            &self.stage.unwrap_or(2).to_string(),
             "--stage-id",
             self.stage_id.as_deref().unwrap_or("stage2-x86_64-unknown-linux-gnu"),
             "--channel",
@@ -251,9 +259,10 @@ fn revisions() {
     let config: Config = cfg().build();
 
     assert_eq!(parse_rs(&config, "//@ revisions: a b c").revisions, vec!["a", "b", "c"],);
-    assert_eq!(parse_makefile(&config, "# revisions: hello there").revisions, vec![
-        "hello", "there"
-    ],);
+    assert_eq!(
+        parse_makefile(&config, "# revisions: hello there").revisions,
+        vec!["hello", "there"],
+    );
 }
 
 #[test]
@@ -387,7 +396,7 @@ fn std_debug_assertions() {
 
 #[test]
 fn stage() {
-    let config: Config = cfg().stage_id("stage1-x86_64-unknown-linux-gnu").build();
+    let config: Config = cfg().stage(1).stage_id("stage1-x86_64-unknown-linux-gnu").build();
 
     assert!(check_ignore(&config, "//@ ignore-stage1"));
     assert!(!check_ignore(&config, "//@ ignore-stage2"));
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 27a046ba5bc..d0a83cab9cd 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -64,6 +64,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         .reqopt("", "src-base", "directory to scan for test files", "PATH")
         .reqopt("", "build-base", "directory to deposit test outputs", "PATH")
         .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH")
+        .reqopt("", "stage", "stage number under test", "N")
         .reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET")
         .reqopt(
             "",
@@ -294,6 +295,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
         panic!("`--nocapture` is deprecated; please use `--no-capture`");
     }
 
+    let stage = match matches.opt_str("stage") {
+        Some(stage) => stage.parse::<u32>().expect("expected `--stage` to be an unsigned integer"),
+        None => panic!("`--stage` is required"),
+    };
+
     Config {
         bless: matches.opt_present("bless"),
         compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
@@ -311,7 +317,10 @@ pub fn parse_config(args: Vec<String>) -> Config {
         src_base,
         build_base: opt_path(matches, "build-base"),
         sysroot_base: opt_path(matches, "sysroot-base"),
+
+        stage,
         stage_id: matches.opt_str("stage-id").unwrap(),
+
         mode,
         suite: matches.opt_str("suite").unwrap(),
         debugger: matches.opt_str("debugger").map(|debugger| {
@@ -415,6 +424,7 @@ pub fn log_config(config: &Config) {
     logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path));
     logv(c, format!("src_base: {:?}", config.src_base.display()));
     logv(c, format!("build_base: {:?}", config.build_base.display()));
+    logv(c, format!("stage: {}", config.stage));
     logv(c, format!("stage_id: {}", config.stage_id));
     logv(c, format!("mode: {}", config.mode));
     logv(c, format!("run_ignored: {}", config.run_ignored));
diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
index 7ef16e4a966..16c46fc1339 100644
--- a/src/tools/compiletest/src/runtest/run_make.rs
+++ b/src/tools/compiletest/src/runtest/run_make.rs
@@ -239,30 +239,6 @@ impl TestCx<'_> {
             }
         }
 
-        // `self.config.stage_id` looks like `stage1-<target_triple>`, but we only want
-        // the `stage1` part as that is what the output directories of bootstrap are prefixed with.
-        // Note that this *assumes* build layout from bootstrap is produced as:
-        //
-        // ```
-        // build/<target_triple>/          // <- this is `build_root`
-        // ├── stage0
-        // ├── stage0-bootstrap-tools
-        // ├── stage0-codegen
-        // ├── stage0-rustc
-        // ├── stage0-std
-        // ├── stage0-sysroot
-        // ├── stage0-tools
-        // ├── stage0-tools-bin
-        // ├── stage1
-        // ├── stage1-std
-        // ├── stage1-tools
-        // ├── stage1-tools-bin
-        // └── test
-        // ```
-        // FIXME(jieyouxu): improve the communication between bootstrap and compiletest here so
-        // we don't have to hack out a `stageN`.
-        let stage = self.config.stage_id.split('-').next().unwrap();
-
         // In order to link in the support library as a rlib when compiling recipes, we need three
         // paths:
         // 1. Path of the built support library rlib itself.
@@ -284,10 +260,12 @@ impl TestCx<'_> {
         // support lib and its deps are organized, can't we copy them to the tools-bin dir as
         // well?), but this seems to work for now.
 
-        let stage_tools_bin = build_root.join(format!("{stage}-tools-bin"));
+        let stage_number = self.config.stage;
+
+        let stage_tools_bin = build_root.join(format!("stage{stage_number}-tools-bin"));
         let support_lib_path = stage_tools_bin.join("librun_make_support.rlib");
 
-        let stage_tools = build_root.join(format!("{stage}-tools"));
+        let stage_tools = build_root.join(format!("stage{stage_number}-tools"));
         let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps");
         let support_lib_deps_deps = stage_tools.join("release").join("deps");
 
@@ -368,7 +346,7 @@ impl TestCx<'_> {
         // provided through env vars.
 
         // Compute stage-specific standard library paths.
-        let stage_std_path = build_root.join(&stage).join("lib");
+        let stage_std_path = build_root.join(format!("stage{stage_number}")).join("lib");
 
         // Compute dynamic library search paths for recipes.
         let recipe_dylib_search_paths = {
diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs
index 33fac3edccd..82ebd33d0d1 100644
--- a/src/tools/coverage-dump/src/covfun.rs
+++ b/src/tools/coverage-dump/src/covfun.rs
@@ -95,10 +95,13 @@ pub(crate) fn dump_covfun_mappings(
         // has increased or decreased the number of physical counters needed.
         // (It's possible for the generated code to have more counters that
         // aren't used by any mappings, but that should hopefully be rare.)
-        println!("Highest counter ID seen: {}", match max_counter {
-            Some(id) => format!("c{id}"),
-            None => "(none)".to_owned(),
-        });
+        println!(
+            "Highest counter ID seen: {}",
+            match max_counter {
+                Some(id) => format!("c{id}"),
+                None => "(none)".to_owned(),
+            }
+        );
         println!();
     }
     Ok(())
diff --git a/src/tools/enzyme b/src/tools/enzyme
-Subproject 0e5fa4a3d475f4dece489c9e06b11164f83789f
+Subproject 7f3b207c4413c9d715fd54b36b8a8fd3179e0b6
diff --git a/src/tools/generate-copyright/src/cargo_metadata.rs b/src/tools/generate-copyright/src/cargo_metadata.rs
index 420579372ac..51e353e9b22 100644
--- a/src/tools/generate-copyright/src/cargo_metadata.rs
+++ b/src/tools/generate-copyright/src/cargo_metadata.rs
@@ -98,12 +98,15 @@ pub fn get_metadata(
             }
             // otherwise it's an out-of-tree dependency
             let package_id = Package { name: package.name, version: package.version.to_string() };
-            output.insert(package_id, PackageMetadata {
-                license: package.license.unwrap_or_else(|| String::from("Unspecified")),
-                authors: package.authors,
-                notices: BTreeMap::new(),
-                is_in_libstd: None,
-            });
+            output.insert(
+                package_id,
+                PackageMetadata {
+                    license: package.license.unwrap_or_else(|| String::from("Unspecified")),
+                    authors: package.authors,
+                    notices: BTreeMap::new(),
+                    is_in_libstd: None,
+                },
+            );
         }
     }
 
diff --git a/src/tools/generate-copyright/src/main.rs b/src/tools/generate-copyright/src/main.rs
index 0a446ecff5b..7a014989e68 100644
--- a/src/tools/generate-copyright/src/main.rs
+++ b/src/tools/generate-copyright/src/main.rs
@@ -24,12 +24,16 @@ fn main() -> Result<(), Error> {
     let root_path = std::path::absolute(".")?;
 
     // Scan Cargo dependencies
-    let mut collected_cargo_metadata =
-        cargo_metadata::get_metadata_and_notices(&cargo, &out_dir.join("vendor"), &root_path, &[
+    let mut collected_cargo_metadata = cargo_metadata::get_metadata_and_notices(
+        &cargo,
+        &out_dir.join("vendor"),
+        &root_path,
+        &[
             Path::new("./Cargo.toml"),
             Path::new("./src/tools/cargo/Cargo.toml"),
             Path::new("./library/Cargo.toml"),
-        ])?;
+        ],
+    )?;
 
     let library_collected_cargo_metadata = cargo_metadata::get_metadata_and_notices(
         &cargo,
diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs
index a37e6c2eb5c..28deb7e7cee 100644
--- a/src/tools/jsondoclint/src/validator/tests.rs
+++ b/src/tools/jsondoclint/src/validator/tests.rs
@@ -21,32 +21,42 @@ fn errors_on_missing_links() {
         root: Id(0),
         crate_version: None,
         includes_private: false,
-        index: FxHashMap::from_iter([(Id(0), Item {
-            name: Some("root".to_owned()),
-            id: Id(0),
-            crate_id: 0,
-            span: None,
-            visibility: Visibility::Public,
-            docs: None,
-            links: FxHashMap::from_iter([("Not Found".to_owned(), Id(1))]),
-            attrs: vec![],
-            deprecation: None,
-            inner: ItemEnum::Module(Module { is_crate: true, items: vec![], is_stripped: false }),
-        })]),
+        index: FxHashMap::from_iter([(
+            Id(0),
+            Item {
+                name: Some("root".to_owned()),
+                id: Id(0),
+                crate_id: 0,
+                span: None,
+                visibility: Visibility::Public,
+                docs: None,
+                links: FxHashMap::from_iter([("Not Found".to_owned(), Id(1))]),
+                attrs: vec![],
+                deprecation: None,
+                inner: ItemEnum::Module(Module {
+                    is_crate: true,
+                    items: vec![],
+                    is_stripped: false,
+                }),
+            },
+        )]),
         paths: FxHashMap::default(),
         external_crates: FxHashMap::default(),
         format_version: rustdoc_json_types::FORMAT_VERSION,
     };
 
-    check(&k, &[Error {
-        kind: ErrorKind::NotFound(vec![vec![
-            SelectorPart::Field("index".to_owned()),
-            SelectorPart::Field("0".to_owned()),
-            SelectorPart::Field("links".to_owned()),
-            SelectorPart::Field("Not Found".to_owned()),
-        ]]),
-        id: Id(1),
-    }]);
+    check(
+        &k,
+        &[Error {
+            kind: ErrorKind::NotFound(vec![vec![
+                SelectorPart::Field("index".to_owned()),
+                SelectorPart::Field("0".to_owned()),
+                SelectorPart::Field("links".to_owned()),
+                SelectorPart::Field("Not Found".to_owned()),
+            ]]),
+            id: Id(1),
+        }],
+    );
 }
 
 // Test we would catch
@@ -58,48 +68,60 @@ fn errors_on_local_in_paths_and_not_index() {
         crate_version: None,
         includes_private: false,
         index: FxHashMap::from_iter([
-            (Id(0), Item {
-                id: Id(0),
-                crate_id: 0,
-                name: Some("microcore".to_owned()),
-                span: None,
-                visibility: Visibility::Public,
-                docs: None,
-                links: FxHashMap::from_iter([(("prim@i32".to_owned(), Id(2)))]),
-                attrs: Vec::new(),
-                deprecation: None,
-                inner: ItemEnum::Module(Module {
-                    is_crate: true,
-                    items: vec![Id(1)],
-                    is_stripped: false,
-                }),
-            }),
-            (Id(1), Item {
-                id: Id(1),
-                crate_id: 0,
-                name: Some("i32".to_owned()),
-                span: None,
-                visibility: Visibility::Public,
-                docs: None,
-                links: FxHashMap::default(),
-                attrs: Vec::new(),
-                deprecation: None,
-                inner: ItemEnum::Primitive(Primitive { name: "i32".to_owned(), impls: vec![] }),
-            }),
+            (
+                Id(0),
+                Item {
+                    id: Id(0),
+                    crate_id: 0,
+                    name: Some("microcore".to_owned()),
+                    span: None,
+                    visibility: Visibility::Public,
+                    docs: None,
+                    links: FxHashMap::from_iter([(("prim@i32".to_owned(), Id(2)))]),
+                    attrs: Vec::new(),
+                    deprecation: None,
+                    inner: ItemEnum::Module(Module {
+                        is_crate: true,
+                        items: vec![Id(1)],
+                        is_stripped: false,
+                    }),
+                },
+            ),
+            (
+                Id(1),
+                Item {
+                    id: Id(1),
+                    crate_id: 0,
+                    name: Some("i32".to_owned()),
+                    span: None,
+                    visibility: Visibility::Public,
+                    docs: None,
+                    links: FxHashMap::default(),
+                    attrs: Vec::new(),
+                    deprecation: None,
+                    inner: ItemEnum::Primitive(Primitive { name: "i32".to_owned(), impls: vec![] }),
+                },
+            ),
         ]),
-        paths: FxHashMap::from_iter([(Id(2), ItemSummary {
-            crate_id: 0,
-            path: vec!["microcore".to_owned(), "i32".to_owned()],
-            kind: ItemKind::Primitive,
-        })]),
+        paths: FxHashMap::from_iter([(
+            Id(2),
+            ItemSummary {
+                crate_id: 0,
+                path: vec!["microcore".to_owned(), "i32".to_owned()],
+                kind: ItemKind::Primitive,
+            },
+        )]),
         external_crates: FxHashMap::default(),
         format_version: rustdoc_json_types::FORMAT_VERSION,
     };
 
-    check(&krate, &[Error {
-        id: Id(2),
-        kind: ErrorKind::Custom("Id for local item in `paths` but not in `index`".to_owned()),
-    }]);
+    check(
+        &krate,
+        &[Error {
+            id: Id(2),
+            kind: ErrorKind::Custom("Id for local item in `paths` but not in `index`".to_owned()),
+        }],
+    );
 }
 
 #[test]
@@ -117,84 +139,96 @@ fn errors_on_missing_path() {
         crate_version: None,
         includes_private: false,
         index: FxHashMap::from_iter([
-            (Id(0), Item {
-                id: Id(0),
-                crate_id: 0,
-                name: Some("foo".to_owned()),
-                span: None,
-                visibility: Visibility::Public,
-                docs: None,
-                links: FxHashMap::default(),
-                attrs: Vec::new(),
-                deprecation: None,
-                inner: ItemEnum::Module(Module {
-                    is_crate: true,
-                    items: vec![Id(1), Id(2)],
-                    is_stripped: false,
-                }),
-            }),
-            (Id(1), Item {
-                id: Id(0),
-                crate_id: 0,
-                name: Some("Bar".to_owned()),
-                span: None,
-                visibility: Visibility::Public,
-                docs: None,
-                links: FxHashMap::default(),
-                attrs: Vec::new(),
-                deprecation: None,
-                inner: ItemEnum::Struct(Struct {
-                    kind: StructKind::Unit,
-                    generics: generics.clone(),
-                    impls: vec![],
-                }),
-            }),
-            (Id(2), Item {
-                id: Id(0),
-                crate_id: 0,
-                name: Some("mk_bar".to_owned()),
-                span: None,
-                visibility: Visibility::Public,
-                docs: None,
-                links: FxHashMap::default(),
-                attrs: Vec::new(),
-                deprecation: None,
-                inner: ItemEnum::Function(Function {
-                    sig: FunctionSignature {
-                        inputs: vec![],
-                        output: Some(Type::ResolvedPath(Path {
-                            path: "Bar".to_owned(),
-                            id: Id(1),
-                            args: None,
-                        })),
-                        is_c_variadic: false,
-                    },
-                    generics,
-                    header: FunctionHeader {
-                        is_const: false,
-                        is_unsafe: false,
-                        is_async: false,
-                        abi: Abi::Rust,
-                    },
-                    has_body: true,
-                }),
-            }),
+            (
+                Id(0),
+                Item {
+                    id: Id(0),
+                    crate_id: 0,
+                    name: Some("foo".to_owned()),
+                    span: None,
+                    visibility: Visibility::Public,
+                    docs: None,
+                    links: FxHashMap::default(),
+                    attrs: Vec::new(),
+                    deprecation: None,
+                    inner: ItemEnum::Module(Module {
+                        is_crate: true,
+                        items: vec![Id(1), Id(2)],
+                        is_stripped: false,
+                    }),
+                },
+            ),
+            (
+                Id(1),
+                Item {
+                    id: Id(0),
+                    crate_id: 0,
+                    name: Some("Bar".to_owned()),
+                    span: None,
+                    visibility: Visibility::Public,
+                    docs: None,
+                    links: FxHashMap::default(),
+                    attrs: Vec::new(),
+                    deprecation: None,
+                    inner: ItemEnum::Struct(Struct {
+                        kind: StructKind::Unit,
+                        generics: generics.clone(),
+                        impls: vec![],
+                    }),
+                },
+            ),
+            (
+                Id(2),
+                Item {
+                    id: Id(0),
+                    crate_id: 0,
+                    name: Some("mk_bar".to_owned()),
+                    span: None,
+                    visibility: Visibility::Public,
+                    docs: None,
+                    links: FxHashMap::default(),
+                    attrs: Vec::new(),
+                    deprecation: None,
+                    inner: ItemEnum::Function(Function {
+                        sig: FunctionSignature {
+                            inputs: vec![],
+                            output: Some(Type::ResolvedPath(Path {
+                                path: "Bar".to_owned(),
+                                id: Id(1),
+                                args: None,
+                            })),
+                            is_c_variadic: false,
+                        },
+                        generics,
+                        header: FunctionHeader {
+                            is_const: false,
+                            is_unsafe: false,
+                            is_async: false,
+                            abi: Abi::Rust,
+                        },
+                        has_body: true,
+                    }),
+                },
+            ),
         ]),
-        paths: FxHashMap::from_iter([(Id(0), ItemSummary {
-            crate_id: 0,
-            path: vec!["foo".to_owned()],
-            kind: ItemKind::Module,
-        })]),
+        paths: FxHashMap::from_iter([(
+            Id(0),
+            ItemSummary { crate_id: 0, path: vec!["foo".to_owned()], kind: ItemKind::Module },
+        )]),
         external_crates: FxHashMap::default(),
         format_version: rustdoc_json_types::FORMAT_VERSION,
     };
 
-    check(&krate, &[Error {
-        kind: ErrorKind::Custom(
-            r#"No entry in '$.paths' for Path { path: "Bar", id: Id(1), args: None }"#.to_owned(),
-        ),
-        id: Id(1),
-    }]);
+    check(
+        &krate,
+        &[Error {
+            kind: ErrorKind::Custom(
+                r#"No entry in '$.paths' for Path { path: "Bar", id: Id(1), args: None }"#
+                    .to_owned(),
+            ),
+            id: Id(1),
+        }],
+    );
 }
 
 #[test]
@@ -204,18 +238,25 @@ fn checks_local_crate_id_is_correct() {
         root: Id(0),
         crate_version: None,
         includes_private: false,
-        index: FxHashMap::from_iter([(Id(0), Item {
-            id: Id(0),
-            crate_id: LOCAL_CRATE_ID.wrapping_add(1),
-            name: Some("irrelavent".to_owned()),
-            span: None,
-            visibility: Visibility::Public,
-            docs: None,
-            links: FxHashMap::default(),
-            attrs: Vec::new(),
-            deprecation: None,
-            inner: ItemEnum::Module(Module { is_crate: true, items: vec![], is_stripped: false }),
-        })]),
+        index: FxHashMap::from_iter([(
+            Id(0),
+            Item {
+                id: Id(0),
+                crate_id: LOCAL_CRATE_ID.wrapping_add(1),
+                name: Some("irrelavent".to_owned()),
+                span: None,
+                visibility: Visibility::Public,
+                docs: None,
+                links: FxHashMap::default(),
+                attrs: Vec::new(),
+                deprecation: None,
+                inner: ItemEnum::Module(Module {
+                    is_crate: true,
+                    items: vec![],
+                    is_stripped: false,
+                }),
+            },
+        )]),
         paths: FxHashMap::default(),
         external_crates: FxHashMap::default(),
         format_version: FORMAT_VERSION,
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index f6e84465780..9fd33e23204 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -19,24 +19,30 @@ mod groups;
 /// level of the lint, which will be more difficult to support, since rustc
 /// currently does not track that historical information.
 static RENAMES: &[(Level, &[(&str, &str)])] = &[
-    (Level::Allow, &[
-        ("single-use-lifetime", "single-use-lifetimes"),
-        ("elided-lifetime-in-path", "elided-lifetimes-in-paths"),
-        ("async-idents", "keyword-idents"),
-        ("disjoint-capture-migration", "rust-2021-incompatible-closure-captures"),
-        ("keyword-idents", "keyword-idents-2018"),
-        ("or-patterns-back-compat", "rust-2021-incompatible-or-patterns"),
-    ]),
-    (Level::Warn, &[
-        ("bare-trait-object", "bare-trait-objects"),
-        ("unstable-name-collision", "unstable-name-collisions"),
-        ("unused-doc-comment", "unused-doc-comments"),
-        ("redundant-semicolon", "redundant-semicolons"),
-        ("overlapping-patterns", "overlapping-range-endpoints"),
-        ("non-fmt-panic", "non-fmt-panics"),
-        ("unused-tuple-struct-fields", "dead-code"),
-        ("static-mut-ref", "static-mut-refs"),
-    ]),
+    (
+        Level::Allow,
+        &[
+            ("single-use-lifetime", "single-use-lifetimes"),
+            ("elided-lifetime-in-path", "elided-lifetimes-in-paths"),
+            ("async-idents", "keyword-idents"),
+            ("disjoint-capture-migration", "rust-2021-incompatible-closure-captures"),
+            ("keyword-idents", "keyword-idents-2018"),
+            ("or-patterns-back-compat", "rust-2021-incompatible-or-patterns"),
+        ],
+    ),
+    (
+        Level::Warn,
+        &[
+            ("bare-trait-object", "bare-trait-objects"),
+            ("unstable-name-collision", "unstable-name-collisions"),
+            ("unused-doc-comment", "unused-doc-comments"),
+            ("redundant-semicolon", "redundant-semicolons"),
+            ("overlapping-patterns", "overlapping-range-endpoints"),
+            ("non-fmt-panic", "non-fmt-panics"),
+            ("unused-tuple-struct-fields", "dead-code"),
+            ("static-mut-ref", "static-mut-refs"),
+        ],
+    ),
     (Level::Deny, &[("exceeding-bitshifts", "arithmetic-overflow")]),
 ];
 
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index dd48038e07a..48458cdcbc3 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-e0607238c95df66e3d25a6c17aebe18c6726fc74
+6171d944aea415a3023d4262e0895aa3b18c771f
diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
index 0d0d79098d5..b6c5522b3d2 100644
--- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
+++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
@@ -299,27 +299,6 @@ fn simd_mask() {
         }
     }
 
-    // This used to cause an ICE. It exercises simd_select_bitmask with an array as input.
-    let bitmask = u8x4::from_array([0b00001101, 0, 0, 0]);
-    assert_eq!(
-        mask32x4::from_bitmask_vector(bitmask),
-        mask32x4::from_array([true, false, true, true]),
-    );
-    let bitmask = u8x8::from_array([0b01000101, 0, 0, 0, 0, 0, 0, 0]);
-    assert_eq!(
-        mask32x8::from_bitmask_vector(bitmask),
-        mask32x8::from_array([true, false, true, false, false, false, true, false]),
-    );
-    let bitmask =
-        u8x16::from_array([0b01000101, 0b11110000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
-    assert_eq!(
-        mask32x16::from_bitmask_vector(bitmask),
-        mask32x16::from_array([
-            true, false, true, false, false, false, true, false, false, false, false, false, true,
-            true, true, true,
-        ]),
-    );
-
     // Also directly call simd_select_bitmask, to test both kinds of argument types.
     unsafe {
         // These masks are exactly the results we got out above in the `simd_bitmask` tests.
diff --git a/src/tools/rust-analyzer/.git-blame-ignore-revs b/src/tools/rust-analyzer/.git-blame-ignore-revs
index 2ccdc8c0425..651502965ef 100644
--- a/src/tools/rust-analyzer/.git-blame-ignore-revs
+++ b/src/tools/rust-analyzer/.git-blame-ignore-revs
@@ -14,3 +14,4 @@ f247090558c9ba3c551566eae5882b7ca865225f
 b2f6fd4f961fc7e4fbfdb80cae2e6065f8436f15
 c48062fe2ab9a2d913d1985a6b0aec4bf936bfc1
 f532576ac53ddcc666bc8d59e0b6437065e2f599
+4704881b641884de50645637108b6b6f5b68aaf9
diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
index 5258d9ddd3a..e4fa94643ba 100644
--- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
@@ -11,6 +11,7 @@ on:
 
 jobs:
   publish:
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
     name: publish
     runs-on: ubuntu-latest
     steps:
diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
index f1533bf26e5..5023a634fde 100644
--- a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
@@ -9,6 +9,7 @@ on:
 
 jobs:
   publish-libs:
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
     name: publish
     runs-on: ubuntu-latest
     steps:
diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml
index 39ac652de0f..3f1c8b2a9c1 100644
--- a/src/tools/rust-analyzer/.github/workflows/release.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/release.yaml
@@ -22,6 +22,7 @@ env:
 
 jobs:
   dist:
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
     strategy:
       matrix:
         include:
@@ -138,6 +139,7 @@ jobs:
           path: ./dist
 
   dist-x86_64-unknown-linux-musl:
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
     name: dist (x86_64-unknown-linux-musl)
     runs-on: ubuntu-latest
     env:
@@ -183,6 +185,7 @@ jobs:
           path: ./dist
 
   publish:
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
     name: publish
     runs-on: ubuntu-latest
     needs: ["dist", "dist-x86_64-unknown-linux-musl"]
@@ -257,24 +260,24 @@ jobs:
         working-directory: ./editors/code
 
       - name: Publish Extension (Code Marketplace, release)
-        if: github.ref == 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
+        if: github.ref == 'refs/heads/release' && github.repository == 'rust-lang/rust-analyzer'
         working-directory: ./editors/code
         # token from https://dev.azure.com/rust-analyzer/
         run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
 
       - name: Publish Extension (OpenVSX, release)
-        if: github.ref == 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
+        if: github.ref == 'refs/heads/release' && github.repository == 'rust-lang/rust-analyzer'
         working-directory: ./editors/code
         run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
         timeout-minutes: 2
 
       - name: Publish Extension (Code Marketplace, nightly)
-        if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
+        if: github.ref != 'refs/heads/release' && github.repository == 'rust-lang/rust-analyzer'
         working-directory: ./editors/code
         run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix --pre-release
 
       - name: Publish Extension (OpenVSX, nightly)
-        if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
+        if: github.ref != 'refs/heads/release' && github.repository == 'rust-lang/rust-analyzer'
         working-directory: ./editors/code
         run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
         timeout-minutes: 2
diff --git a/src/tools/rust-analyzer/.gitignore b/src/tools/rust-analyzer/.gitignore
index c4470a45078..7192e685e29 100644
--- a/src/tools/rust-analyzer/.gitignore
+++ b/src/tools/rust-analyzer/.gitignore
@@ -6,10 +6,11 @@ target/
 *.log
 *.iml
 .vscode/settings.json
-generated_assists.adoc
-generated_features.adoc
-generated_diagnostic.adoc
 .DS_Store
 /out/
 /dump.lsif
 .envrc
+docs/book/book
+docs/book/src/assists_generated.md
+docs/book/src/diagnostics_generated.md
+docs/book/src/features_generated.md
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 2dfca7c4803..98268d8f844 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -1408,9 +1408,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
 dependencies = [
  "unicode-ident",
 ]
@@ -1514,9 +1514,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_abi"
-version = "0.91.0"
+version = "0.94.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5246e9e1f450333a990877eabbc36fe0567e7cedd56d5365db319e14079cf2a"
+checksum = "2fa4333df7b71217edb44a36702cafd2bcfc9850677bdf78b32c9f2c98e5df40"
 dependencies = [
  "bitflags 2.7.0",
  "ra-ap-rustc_index",
@@ -1525,9 +1525,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_index"
-version = "0.91.0"
+version = "0.94.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59fd8e4f5b34c434ec111efb0e0614954db048b9307d3b2e4cc3c915da9d2160"
+checksum = "d200275ff3d952cc11108f4dc6a692473659758623d63f2bdcea6104a7f1cec8"
 dependencies = [
  "ra-ap-rustc_index_macros",
  "smallvec",
@@ -1535,9 +1535,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_index_macros"
-version = "0.91.0"
+version = "0.94.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d34973fe081392bd1edb022e865e9952fcaa093f9cdae183edce64472e5e889"
+checksum = "06eb63df8c1ce2dcb07647305bed811c9c5ebd157def01a81c1b9479b8592b3b"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1546,19 +1546,20 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_lexer"
-version = "0.91.0"
+version = "0.94.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52fa42c582e21b35e8f61a5afe3c63a9c722d995826762eb19b18beeccf5157f"
+checksum = "b7a4d402b2f85650e8c1f78e2e2defc241b03948d6e30d9f5254c9b82755cc4d"
 dependencies = [
+ "memchr",
  "unicode-properties",
  "unicode-xid",
 ]
 
 [[package]]
 name = "ra-ap-rustc_parse_format"
-version = "0.91.0"
+version = "0.94.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "740383328d7033393e5385f4a6073b880d5811b0fc0fd2559e481f905940f2f8"
+checksum = "a23a382dbe392beb26360c1a8ce9193155ef74eeac59bcda0fa0a233e047323a"
 dependencies = [
  "ra-ap-rustc_index",
  "ra-ap-rustc_lexer",
@@ -1566,9 +1567,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_pattern_analysis"
-version = "0.91.0"
+version = "0.94.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c39f544728f32cebffb1a8b92ba3c1f3dcb4144081438d192137ed197d479a9d"
+checksum = "d746955d67f315ab79767f1d0bbc17fee4f0970d4a00b9ad76bf09cc7d3cd17e"
 dependencies = [
  "ra-ap-rustc_index",
  "rustc-hash 2.0.0",
@@ -2001,9 +2002,9 @@ dependencies = [
 
 [[package]]
 name = "tenthash"
-version = "0.4.0"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d67f9f3cf70e0852941d7bc3cb884b49b24b8ee956baf91ad0abae31f5ef11fb"
+checksum = "2d092d622df8bb64e5de8dc86a3667702d5f1e0fe2f0604c6035540703c8cd1e"
 
 [[package]]
 name = "test-fixture"
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index c42ae171d86..44c628e8294 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -87,11 +87,11 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
 vfs = { path = "./crates/vfs", version = "0.0.0" }
 edition = { path = "./crates/edition", version = "0.0.0" }
 
-ra-ap-rustc_lexer = { version = "0.91", default-features = false }
-ra-ap-rustc_parse_format = { version = "0.91", default-features = false }
-ra-ap-rustc_index = { version = "0.91", default-features = false }
-ra-ap-rustc_abi = { version = "0.91", default-features = false }
-ra-ap-rustc_pattern_analysis = { version = "0.91", default-features = false }
+ra-ap-rustc_lexer = { version = "0.94", default-features = false }
+ra-ap-rustc_parse_format = { version = "0.94", default-features = false }
+ra-ap-rustc_index = { version = "0.94", default-features = false }
+ra-ap-rustc_abi = { version = "0.94", default-features = false }
+ra-ap-rustc_pattern_analysis = { version = "0.94", default-features = false }
 
 # local crates that aren't published to crates.io. These should not have versions.
 
diff --git a/src/tools/rust-analyzer/PRIVACY.md b/src/tools/rust-analyzer/PRIVACY.md
index 89e252be731..ef9c2437ab7 100644
--- a/src/tools/rust-analyzer/PRIVACY.md
+++ b/src/tools/rust-analyzer/PRIVACY.md
@@ -1 +1 @@
-See the [Privacy](https://rust-analyzer.github.io/manual.html#privacy) section of the user manual.
+See the [Privacy](https://rust-analyzer.github.io/book/privacy.html) section of the user manual.
diff --git a/src/tools/rust-analyzer/README.md b/src/tools/rust-analyzer/README.md
index 552f71f1518..56883723c93 100644
--- a/src/tools/rust-analyzer/README.md
+++ b/src/tools/rust-analyzer/README.md
@@ -1,6 +1,6 @@
 <p align="center">
   <img
-    src="https://raw.githubusercontent.com/rust-analyzer/rust-analyzer/master/assets/logo-wide.svg"
+    src="https://raw.githubusercontent.com/rust-lang/rust-analyzer/master/assets/logo-wide.svg"
     alt="rust-analyzer logo">
 </p>
 
@@ -9,7 +9,7 @@ It is a part of a larger rls-2.0 effort to create excellent IDE support for Rust
 
 ## Quick Start
 
-https://rust-analyzer.github.io/manual.html#installation
+https://rust-analyzer.github.io/book/installation.html
 
 ## Documentation
 
@@ -18,12 +18,13 @@ if you are just curious about how things work under the hood, check the [./docs/
 folder.
 
 If you want to **use** rust-analyzer's language server with your editor of
-choice, check [the manual](https://rust-analyzer.github.io/manual.html) folder.
+choice, check [the manual](https://rust-analyzer.github.io/book/).
 It also contains some tips & tricks to help you be more productive when using rust-analyzer.
 
 ## Security and Privacy
 
-See the corresponding sections of [the manual](https://rust-analyzer.github.io/manual.html#security).
+See the [security](https://rust-analyzer.github.io/book/security.html) and
+[privacy](https://rust-analyzer.github.io/book/privacy.html) sections of the manual.
 
 ## Communication
 
diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs
index a0fc8c31eaf..c2cea071905 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/input.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs
@@ -129,9 +129,9 @@ impl fmt::Display for CrateName {
 }
 
 impl ops::Deref for CrateName {
-    type Target = str;
-    fn deref(&self) -> &str {
-        self.0.as_str()
+    type Target = Symbol;
+    fn deref(&self) -> &Symbol {
+        &self.0
     }
 }
 
@@ -230,8 +230,8 @@ impl fmt::Display for CrateDisplayName {
 }
 
 impl ops::Deref for CrateDisplayName {
-    type Target = str;
-    fn deref(&self) -> &str {
+    type Target = Symbol;
+    fn deref(&self) -> &Symbol {
         &self.crate_name
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index 12f5f6ad79a..c5bbd4edba9 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -95,10 +95,14 @@ impl FunctionData {
             .map(Box::new);
         let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
         if flags.contains(FnFlags::HAS_UNSAFE_KW)
-            && !crate_graph[krate].edition.at_least_2024()
             && attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
         {
             flags.remove(FnFlags::HAS_UNSAFE_KW);
+            flags.insert(FnFlags::DEPRECATED_SAFE_2024);
+        }
+
+        if attrs.by_key(&sym::target_feature).exists() {
+            flags.insert(FnFlags::HAS_TARGET_FEATURE);
         }
 
         Arc::new(FunctionData {
@@ -148,6 +152,10 @@ impl FunctionData {
         self.flags.contains(FnFlags::HAS_UNSAFE_KW)
     }
 
+    pub fn is_deprecated_safe_2024(&self) -> bool {
+        self.flags.contains(FnFlags::DEPRECATED_SAFE_2024)
+    }
+
     pub fn is_safe(&self) -> bool {
         self.flags.contains(FnFlags::HAS_SAFE_KW)
     }
@@ -155,6 +163,10 @@ impl FunctionData {
     pub fn is_varargs(&self) -> bool {
         self.flags.contains(FnFlags::IS_VARARGS)
     }
+
+    pub fn has_target_feature(&self) -> bool {
+        self.flags.contains(FnFlags::HAS_TARGET_FEATURE)
+    }
 }
 
 fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
index bf6cc1dcade..598a850898b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -10,12 +10,12 @@ use triomphe::Arc;
 
 use crate::{
     attr::{Attrs, AttrsWithOwner},
-    body::{scope::ExprScopes, Body, BodySourceMap},
     data::{
         adt::{EnumData, EnumVariantData, StructData, VariantData},
         ConstData, ExternCrateDeclData, FunctionData, ImplData, Macro2Data, MacroRulesData,
         ProcMacroData, StaticData, TraitAliasData, TraitData, TypeAliasData,
     },
+    expr_store::{scope::ExprScopes, Body, BodySourceMap},
     generics::GenericParams,
     import_map::ImportMap,
     item_tree::{AttrOwner, ItemTree, ItemTreeSourceMaps},
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs
index de439249306..9df6eaade75 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs
@@ -1,18 +1,19 @@
-//! Defines `Body`: a lowered representation of bodies of functions, statics and
+//! Defines `ExpressionStore`: a lowered representation of functions, statics and
 //! consts.
+mod body;
 mod lower;
 mod pretty;
 pub mod scope;
+
 #[cfg(test)]
 mod tests;
 
 use std::ops::{Deref, Index};
 
-use base_db::CrateId;
 use cfg::{CfgExpr, CfgOptions};
 use either::Either;
 use hir_expand::{name::Name, ExpandError, InFile};
-use la_arena::{Arena, ArenaMap, Idx, RawIdx};
+use la_arena::{Arena, ArenaMap};
 use rustc_hash::FxHashMap;
 use smallvec::SmallVec;
 use span::{Edition, MacroFileId, SyntaxContextData};
@@ -22,19 +23,18 @@ use tt::TextRange;
 
 use crate::{
     db::DefDatabase,
-    expander::Expander,
     hir::{
-        dummy_expr_id, Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label,
-        LabelId, Pat, PatId, RecordFieldPat, Statement,
+        Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat,
+        PatId, RecordFieldPat, Statement,
     },
-    item_tree::AttrOwner,
     nameres::DefMap,
     path::{ModPath, Path},
-    src::HasSource,
     type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap},
-    BlockId, DefWithBodyId, HasModule, Lookup, SyntheticSyntax,
+    BlockId, DefWithBodyId, Lookup, SyntheticSyntax,
 };
 
+pub use self::body::{Body, BodySourceMap};
+
 /// A wrapper around [`span::SyntaxContextId`] that is intended only for comparisons.
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct HygieneId(span::SyntaxContextId);
@@ -58,9 +58,29 @@ impl HygieneId {
     }
 }
 
-/// The body of an item (function, const etc.).
+pub type ExprPtr = AstPtr<ast::Expr>;
+pub type ExprSource = InFile<ExprPtr>;
+
+pub type PatPtr = AstPtr<ast::Pat>;
+pub type PatSource = InFile<PatPtr>;
+
+pub type LabelPtr = AstPtr<ast::Label>;
+pub type LabelSource = InFile<LabelPtr>;
+
+pub type FieldPtr = AstPtr<ast::RecordExprField>;
+pub type FieldSource = InFile<FieldPtr>;
+
+pub type PatFieldPtr = AstPtr<Either<ast::RecordExprField, ast::RecordPatField>>;
+pub type PatFieldSource = InFile<PatFieldPtr>;
+
+pub type ExprOrPatPtr = AstPtr<Either<ast::Expr, ast::Pat>>;
+pub type ExprOrPatSource = InFile<ExprOrPatPtr>;
+
+pub type SelfParamPtr = AstPtr<ast::SelfParam>;
+pub type MacroCallPtr = AstPtr<ast::MacroCall>;
+
 #[derive(Debug, Eq, PartialEq)]
-pub struct Body {
+pub struct ExpressionStore {
     pub exprs: Arena<Expr>,
     pub pats: Arena<Pat>,
     pub bindings: Arena<Binding>,
@@ -68,19 +88,9 @@ pub struct Body {
     /// Id of the closure/coroutine that owns the corresponding binding. If a binding is owned by the
     /// top level expression, it will not be listed in here.
     pub binding_owners: FxHashMap<BindingId, ExprId>,
-    /// The patterns for the function's parameters. While the parameter types are
-    /// part of the function signature, the patterns are not (they don't change
-    /// the external type of the function).
-    ///
-    /// If this `Body` is for the body of a constant, this will just be
-    /// empty.
-    pub params: Box<[PatId]>,
-    pub self_param: Option<BindingId>,
-    /// The `ExprId` of the actual body expression.
-    pub body_expr: ExprId,
     pub types: TypesMap,
-    /// Block expressions in this body that may contain inner items.
-    block_scopes: Vec<BlockId>,
+    /// Block expressions in this store that may contain inner items.
+    block_scopes: Box<[BlockId]>,
 
     /// A map from binding to its hygiene ID.
     ///
@@ -92,44 +102,13 @@ pub struct Body {
     binding_hygiene: FxHashMap<BindingId, HygieneId>,
     /// A map from an variable usages to their hygiene ID.
     ///
-    /// Expressions that can be recorded here are single segment path, although not all single segments path refer
+    /// Expressions (and destructuing patterns) that can be recorded here are single segment path, although not all single segments path refer
     /// to variables and have hygiene (some refer to items, we don't know at this stage).
-    expr_hygiene: FxHashMap<ExprId, HygieneId>,
-    /// A map from a destructuring assignment possible variable usages to their hygiene ID.
-    pat_hygiene: FxHashMap<PatId, HygieneId>,
+    ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
 }
 
-pub type ExprPtr = AstPtr<ast::Expr>;
-pub type ExprSource = InFile<ExprPtr>;
-
-pub type PatPtr = AstPtr<ast::Pat>;
-pub type PatSource = InFile<PatPtr>;
-
-pub type LabelPtr = AstPtr<ast::Label>;
-pub type LabelSource = InFile<LabelPtr>;
-
-pub type FieldPtr = AstPtr<ast::RecordExprField>;
-pub type FieldSource = InFile<FieldPtr>;
-
-pub type PatFieldPtr = AstPtr<Either<ast::RecordExprField, ast::RecordPatField>>;
-pub type PatFieldSource = InFile<PatFieldPtr>;
-
-pub type ExprOrPatPtr = AstPtr<Either<ast::Expr, ast::Pat>>;
-pub type ExprOrPatSource = InFile<ExprOrPatPtr>;
-
-/// An item body together with the mapping from syntax nodes to HIR expression
-/// IDs. This is needed to go from e.g. a position in a file to the HIR
-/// expression containing it; but for type inference etc., we want to operate on
-/// a structure that is agnostic to the actual positions of expressions in the
-/// file, so that we don't recompute types whenever some whitespace is typed.
-///
-/// One complication here is that, due to macro expansion, a single `Body` might
-/// be spread across several files. So, for each ExprId and PatId, we record
-/// both the HirFileId and the position inside the file. However, we only store
-/// AST -> ExprId mapping for non-macro files, as it is not clear how to handle
-/// this properly for macros.
-#[derive(Default, Debug, Eq, PartialEq)]
-pub struct BodySourceMap {
+#[derive(Debug, Eq, PartialEq, Default)]
+pub struct ExpressionStoreSourceMap {
     // AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map
     // to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected).
     expr_map: FxHashMap<ExprSource, ExprOrPatId>,
@@ -141,7 +120,6 @@ pub struct BodySourceMap {
     label_map: FxHashMap<LabelSource, LabelId>,
     label_map_back: ArenaMap<LabelId, LabelSource>,
 
-    self_param: Option<InFile<AstPtr<ast::SelfParam>>>,
     binding_definitions: FxHashMap<BindingId, SmallVec<[PatId; 4]>>,
 
     /// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
@@ -153,11 +131,25 @@ pub struct BodySourceMap {
 
     template_map: Option<Box<FormatTemplate>>,
 
-    expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, MacroFileId>,
+    expansions: FxHashMap<InFile<MacroCallPtr>, MacroFileId>,
 
-    /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in
+    /// Diagnostics accumulated during lowering. These contain `AstPtr`s and so are stored in
     /// the source map (since they're just as volatile).
-    diagnostics: Vec<BodyDiagnostic>,
+    diagnostics: Vec<ExpressionStoreDiagnostics>,
+}
+
+/// The body of an item (function, const etc.).
+#[derive(Debug, Eq, PartialEq, Default)]
+pub struct ExpressionStoreBuilder {
+    pub exprs: Arena<Expr>,
+    pub pats: Arena<Pat>,
+    pub bindings: Arena<Binding>,
+    pub labels: Arena<Label>,
+    pub binding_owners: FxHashMap<BindingId, ExprId>,
+    pub types: TypesMap,
+    block_scopes: Vec<BlockId>,
+    binding_hygiene: FxHashMap<BindingId, HygieneId>,
+    ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
 }
 
 #[derive(Default, Debug, Eq, PartialEq)]
@@ -171,166 +163,62 @@ struct FormatTemplate {
     /// The value stored for each capture is its template literal and offset inside it. The template literal
     /// is from the `format_args[_nl]!()` macro and so needs to be mapped up once to go to the user-written
     /// template.
-    implicit_capture_to_source: FxHashMap<ExprId, InFile<(AstPtr<ast::Expr>, TextRange)>>,
+    implicit_capture_to_source: FxHashMap<ExprId, InFile<(ExprPtr, TextRange)>>,
 }
 
 #[derive(Debug, Eq, PartialEq)]
-pub enum BodyDiagnostic {
+pub enum ExpressionStoreDiagnostics {
     InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
-    MacroError { node: InFile<AstPtr<ast::MacroCall>>, err: ExpandError },
-    UnresolvedMacroCall { node: InFile<AstPtr<ast::MacroCall>>, path: ModPath },
+    MacroError { node: InFile<MacroCallPtr>, err: ExpandError },
+    UnresolvedMacroCall { node: InFile<MacroCallPtr>, path: ModPath },
     UnreachableLabel { node: InFile<AstPtr<ast::Lifetime>>, name: Name },
     AwaitOutsideOfAsync { node: InFile<AstPtr<ast::AwaitExpr>>, location: String },
     UndeclaredLabel { node: InFile<AstPtr<ast::Lifetime>>, name: Name },
 }
 
-impl Body {
-    pub(crate) fn body_with_source_map_query(
-        db: &dyn DefDatabase,
-        def: DefWithBodyId,
-    ) -> (Arc<Body>, Arc<BodySourceMap>) {
-        let _p = tracing::info_span!("body_with_source_map_query").entered();
-        let mut params = None;
-
-        let mut is_async_fn = false;
-        let InFile { file_id, value: body } = {
-            match def {
-                DefWithBodyId::FunctionId(f) => {
-                    let data = db.function_data(f);
-                    let f = f.lookup(db);
-                    let src = f.source(db);
-                    params = src.value.param_list().map(move |param_list| {
-                        let item_tree = f.id.item_tree(db);
-                        let func = &item_tree[f.id.value];
-                        let krate = f.container.module(db).krate;
-                        let crate_graph = db.crate_graph();
-                        (
-                            param_list,
-                            (0..func.params.len()).map(move |idx| {
-                                item_tree
-                                    .attrs(
-                                        db,
-                                        krate,
-                                        AttrOwner::Param(
-                                            f.id.value,
-                                            Idx::from_raw(RawIdx::from(idx as u32)),
-                                        ),
-                                    )
-                                    .is_cfg_enabled(&crate_graph[krate].cfg_options)
-                            }),
-                        )
-                    });
-                    is_async_fn = data.is_async();
-                    src.map(|it| it.body().map(ast::Expr::from))
-                }
-                DefWithBodyId::ConstId(c) => {
-                    let c = c.lookup(db);
-                    let src = c.source(db);
-                    src.map(|it| it.body())
-                }
-                DefWithBodyId::StaticId(s) => {
-                    let s = s.lookup(db);
-                    let src = s.source(db);
-                    src.map(|it| it.body())
-                }
-                DefWithBodyId::VariantId(v) => {
-                    let s = v.lookup(db);
-                    let src = s.source(db);
-                    src.map(|it| it.expr())
-                }
-                DefWithBodyId::InTypeConstId(c) => c.lookup(db).id.map(|_| c.source(db).expr()),
-            }
-        };
-        let module = def.module(db);
-        let expander = Expander::new(db, file_id, module);
-        let (mut body, mut source_map) =
-            Body::new(db, def, expander, params, body, module.krate, is_async_fn);
-        body.shrink_to_fit();
-        source_map.shrink_to_fit();
-
-        (Arc::new(body), Arc::new(source_map))
-    }
-
-    pub(crate) fn body_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> {
-        db.body_with_source_map(def).0
-    }
-
-    /// Returns an iterator over all block expressions in this body that define inner items.
-    pub fn blocks<'a>(
-        &'a self,
-        db: &'a dyn DefDatabase,
-    ) -> impl Iterator<Item = (BlockId, Arc<DefMap>)> + 'a {
-        self.block_scopes.iter().map(move |&block| (block, db.block_def_map(block)))
-    }
-
-    pub fn pretty_print(
-        &self,
-        db: &dyn DefDatabase,
-        owner: DefWithBodyId,
-        edition: Edition,
-    ) -> String {
-        pretty::print_body_hir(db, self, owner, edition)
-    }
-
-    pub fn pretty_print_expr(
-        &self,
-        db: &dyn DefDatabase,
-        owner: DefWithBodyId,
-        expr: ExprId,
-        edition: Edition,
-    ) -> String {
-        pretty::print_expr_hir(db, self, owner, expr, edition)
-    }
-
-    pub fn pretty_print_pat(
-        &self,
-        db: &dyn DefDatabase,
-        owner: DefWithBodyId,
-        pat: PatId,
-        oneline: bool,
-        edition: Edition,
-    ) -> String {
-        pretty::print_pat_hir(db, self, owner, pat, oneline, edition)
-    }
-
-    fn new(
-        db: &dyn DefDatabase,
-        owner: DefWithBodyId,
-        expander: Expander,
-        params: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
-        body: Option<ast::Expr>,
-        krate: CrateId,
-        is_async_fn: bool,
-    ) -> (Body, BodySourceMap) {
-        lower::lower(db, owner, expander, params, body, krate, is_async_fn)
-    }
-
-    fn shrink_to_fit(&mut self) {
+impl ExpressionStoreBuilder {
+    fn finish(self) -> ExpressionStore {
         let Self {
-            body_expr: _,
-            params: _,
-            self_param: _,
             block_scopes,
-            exprs,
-            labels,
-            pats,
-            bindings,
-            binding_owners,
-            binding_hygiene,
-            expr_hygiene,
-            pat_hygiene,
-            types,
+            mut exprs,
+            mut labels,
+            mut pats,
+            mut bindings,
+            mut binding_owners,
+            mut binding_hygiene,
+            mut ident_hygiene,
+            mut types,
         } = self;
-        block_scopes.shrink_to_fit();
         exprs.shrink_to_fit();
         labels.shrink_to_fit();
         pats.shrink_to_fit();
         bindings.shrink_to_fit();
         binding_owners.shrink_to_fit();
         binding_hygiene.shrink_to_fit();
-        expr_hygiene.shrink_to_fit();
-        pat_hygiene.shrink_to_fit();
+        ident_hygiene.shrink_to_fit();
         types.shrink_to_fit();
+
+        ExpressionStore {
+            exprs,
+            pats,
+            bindings,
+            labels,
+            binding_owners,
+            types,
+            block_scopes: block_scopes.into_boxed_slice(),
+            binding_hygiene,
+            ident_hygiene,
+        }
+    }
+}
+
+impl ExpressionStore {
+    /// Returns an iterator over all block expressions in this store that define inner items.
+    pub fn blocks<'a>(
+        &'a self,
+        db: &'a dyn DefDatabase,
+    ) -> impl Iterator<Item = (BlockId, Arc<DefMap>)> + 'a {
+        self.block_scopes.iter().map(move |&block| (block, db.block_def_map(block)))
     }
 
     pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
@@ -658,11 +546,11 @@ impl Body {
     }
 
     pub fn expr_path_hygiene(&self, expr: ExprId) -> HygieneId {
-        self.expr_hygiene.get(&expr).copied().unwrap_or(HygieneId::ROOT)
+        self.ident_hygiene.get(&expr.into()).copied().unwrap_or(HygieneId::ROOT)
     }
 
     pub fn pat_path_hygiene(&self, pat: PatId) -> HygieneId {
-        self.pat_hygiene.get(&pat).copied().unwrap_or(HygieneId::ROOT)
+        self.ident_hygiene.get(&pat.into()).copied().unwrap_or(HygieneId::ROOT)
     }
 
     pub fn expr_or_pat_path_hygiene(&self, id: ExprOrPatId) -> HygieneId {
@@ -673,27 +561,7 @@ impl Body {
     }
 }
 
-impl Default for Body {
-    fn default() -> Self {
-        Self {
-            body_expr: dummy_expr_id(),
-            exprs: Default::default(),
-            pats: Default::default(),
-            bindings: Default::default(),
-            labels: Default::default(),
-            params: Default::default(),
-            block_scopes: Default::default(),
-            binding_owners: Default::default(),
-            self_param: Default::default(),
-            binding_hygiene: Default::default(),
-            expr_hygiene: Default::default(),
-            pat_hygiene: Default::default(),
-            types: Default::default(),
-        }
-    }
-}
-
-impl Index<ExprId> for Body {
+impl Index<ExprId> for ExpressionStore {
     type Output = Expr;
 
     fn index(&self, expr: ExprId) -> &Expr {
@@ -701,7 +569,7 @@ impl Index<ExprId> for Body {
     }
 }
 
-impl Index<PatId> for Body {
+impl Index<PatId> for ExpressionStore {
     type Output = Pat;
 
     fn index(&self, pat: PatId) -> &Pat {
@@ -709,7 +577,7 @@ impl Index<PatId> for Body {
     }
 }
 
-impl Index<LabelId> for Body {
+impl Index<LabelId> for ExpressionStore {
     type Output = Label;
 
     fn index(&self, label: LabelId) -> &Label {
@@ -717,7 +585,7 @@ impl Index<LabelId> for Body {
     }
 }
 
-impl Index<BindingId> for Body {
+impl Index<BindingId> for ExpressionStore {
     type Output = Binding;
 
     fn index(&self, b: BindingId) -> &Binding {
@@ -725,7 +593,7 @@ impl Index<BindingId> for Body {
     }
 }
 
-impl Index<TypeRefId> for Body {
+impl Index<TypeRefId> for ExpressionStore {
     type Output = TypeRef;
 
     fn index(&self, b: TypeRefId) -> &TypeRef {
@@ -735,7 +603,7 @@ impl Index<TypeRefId> for Body {
 
 // FIXME: Change `node_` prefix to something more reasonable.
 // Perhaps `expr_syntax` and `expr_id`?
-impl BodySourceMap {
+impl ExpressionStoreSourceMap {
     pub fn expr_or_pat_syntax(&self, id: ExprOrPatId) -> Result<ExprOrPatSource, SyntheticSyntax> {
         match id {
             ExprOrPatId::ExprId(id) => self.expr_syntax(id).map(|it| it.map(AstPtr::wrap_left)),
@@ -757,9 +625,7 @@ impl BodySourceMap {
         self.expansions.get(&src).cloned()
     }
 
-    pub fn macro_calls(
-        &self,
-    ) -> impl Iterator<Item = (InFile<AstPtr<ast::MacroCall>>, MacroFileId)> + '_ {
+    pub fn macro_calls(&self) -> impl Iterator<Item = (InFile<MacroCallPtr>, MacroFileId)> + '_ {
         self.expansions.iter().map(|(&a, &b)| (a, b))
     }
 
@@ -767,10 +633,6 @@ impl BodySourceMap {
         self.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax)
     }
 
-    pub fn self_param_syntax(&self) -> Option<InFile<AstPtr<ast::SelfParam>>> {
-        self.self_param
-    }
-
     pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
         self.pat_map.get(&node.map(AstPtr::new)).cloned()
     }
@@ -801,9 +663,7 @@ impl BodySourceMap {
         self.expr_map.get(&src).copied()
     }
 
-    pub fn expansions(
-        &self,
-    ) -> impl Iterator<Item = (&InFile<AstPtr<ast::MacroCall>>, &MacroFileId)> {
+    pub fn expansions(&self) -> impl Iterator<Item = (&InFile<MacroCallPtr>, &MacroFileId)> {
         self.expansions.iter()
     }
 
@@ -823,7 +683,7 @@ impl BodySourceMap {
     pub fn format_args_implicit_capture(
         &self,
         capture_expr: ExprId,
-    ) -> Option<InFile<(AstPtr<ast::Expr>, TextRange)>> {
+    ) -> Option<InFile<(ExprPtr, TextRange)>> {
         self.template_map.as_ref()?.implicit_capture_to_source.get(&capture_expr).copied()
     }
 
@@ -837,14 +697,13 @@ impl BodySourceMap {
             .zip(self.template_map.as_ref()?.asm_to_captures.get(&expr).map(std::ops::Deref::deref))
     }
 
-    /// Get a reference to the body source map's diagnostics.
-    pub fn diagnostics(&self) -> &[BodyDiagnostic] {
+    /// Get a reference to the source map's diagnostics.
+    pub fn diagnostics(&self) -> &[ExpressionStoreDiagnostics] {
         &self.diagnostics
     }
 
     fn shrink_to_fit(&mut self) {
         let Self {
-            self_param: _,
             expr_map,
             expr_map_back,
             pat_map,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs
new file mode 100644
index 00000000000..a55fec4f8b1
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs
@@ -0,0 +1,175 @@
+//! Defines `Body`: a lowered representation of functions, statics and
+//! consts.
+use std::ops;
+
+use hir_expand::{InFile, Lookup};
+use la_arena::{Idx, RawIdx};
+use span::Edition;
+use syntax::ast;
+use triomphe::Arc;
+
+use crate::{
+    db::DefDatabase,
+    expander::Expander,
+    expr_store::{lower, pretty, ExpressionStore, ExpressionStoreSourceMap, SelfParamPtr},
+    hir::{BindingId, ExprId, PatId},
+    item_tree::AttrOwner,
+    src::HasSource,
+    DefWithBodyId, HasModule,
+};
+
+/// The body of an item (function, const etc.).
+#[derive(Debug, Eq, PartialEq)]
+pub struct Body {
+    pub store: ExpressionStore,
+    /// The patterns for the function's parameters. While the parameter types are
+    /// part of the function signature, the patterns are not (they don't change
+    /// the external type of the function).
+    ///
+    /// If this `Body` is for the body of a constant, this will just be
+    /// empty.
+    pub params: Box<[PatId]>,
+    pub self_param: Option<BindingId>,
+    /// The `ExprId` of the actual body expression.
+    pub body_expr: ExprId,
+}
+
+impl ops::Deref for Body {
+    type Target = ExpressionStore;
+
+    fn deref(&self) -> &Self::Target {
+        &self.store
+    }
+}
+
+/// An item body together with the mapping from syntax nodes to HIR expression
+/// IDs. This is needed to go from e.g. a position in a file to the HIR
+/// expression containing it; but for type inference etc., we want to operate on
+/// a structure that is agnostic to the actual positions of expressions in the
+/// file, so that we don't recompute types whenever some whitespace is typed.
+///
+/// One complication here is that, due to macro expansion, a single `Body` might
+/// be spread across several files. So, for each ExprId and PatId, we record
+/// both the HirFileId and the position inside the file. However, we only store
+/// AST -> ExprId mapping for non-macro files, as it is not clear how to handle
+/// this properly for macros.
+#[derive(Default, Debug, Eq, PartialEq)]
+pub struct BodySourceMap {
+    pub self_param: Option<InFile<SelfParamPtr>>,
+    pub store: ExpressionStoreSourceMap,
+}
+
+impl ops::Deref for BodySourceMap {
+    type Target = ExpressionStoreSourceMap;
+
+    fn deref(&self) -> &Self::Target {
+        &self.store
+    }
+}
+
+impl Body {
+    pub(crate) fn body_with_source_map_query(
+        db: &dyn DefDatabase,
+        def: DefWithBodyId,
+    ) -> (Arc<Body>, Arc<BodySourceMap>) {
+        let _p = tracing::info_span!("body_with_source_map_query").entered();
+        let mut params = None;
+
+        let mut is_async_fn = false;
+        let InFile { file_id, value: body } = {
+            match def {
+                DefWithBodyId::FunctionId(f) => {
+                    let data = db.function_data(f);
+                    let f = f.lookup(db);
+                    let src = f.source(db);
+                    params = src.value.param_list().map(move |param_list| {
+                        let item_tree = f.id.item_tree(db);
+                        let func = &item_tree[f.id.value];
+                        let krate = f.container.module(db).krate;
+                        let crate_graph = db.crate_graph();
+                        (
+                            param_list,
+                            (0..func.params.len()).map(move |idx| {
+                                item_tree
+                                    .attrs(
+                                        db,
+                                        krate,
+                                        AttrOwner::Param(
+                                            f.id.value,
+                                            Idx::from_raw(RawIdx::from(idx as u32)),
+                                        ),
+                                    )
+                                    .is_cfg_enabled(&crate_graph[krate].cfg_options)
+                            }),
+                        )
+                    });
+                    is_async_fn = data.is_async();
+                    src.map(|it| it.body().map(ast::Expr::from))
+                }
+                DefWithBodyId::ConstId(c) => {
+                    let c = c.lookup(db);
+                    let src = c.source(db);
+                    src.map(|it| it.body())
+                }
+                DefWithBodyId::StaticId(s) => {
+                    let s = s.lookup(db);
+                    let src = s.source(db);
+                    src.map(|it| it.body())
+                }
+                DefWithBodyId::VariantId(v) => {
+                    let s = v.lookup(db);
+                    let src = s.source(db);
+                    src.map(|it| it.expr())
+                }
+                DefWithBodyId::InTypeConstId(c) => c.lookup(db).id.map(|_| c.source(db).expr()),
+            }
+        };
+        let module = def.module(db);
+        let expander = Expander::new(db, file_id, module);
+        let (body, mut source_map) =
+            lower::lower_body(db, def, expander, params, body, module.krate, is_async_fn);
+        source_map.store.shrink_to_fit();
+
+        (Arc::new(body), Arc::new(source_map))
+    }
+
+    pub(crate) fn body_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> {
+        db.body_with_source_map(def).0
+    }
+
+    pub fn pretty_print(
+        &self,
+        db: &dyn DefDatabase,
+        owner: DefWithBodyId,
+        edition: Edition,
+    ) -> String {
+        pretty::print_body_hir(db, self, owner, edition)
+    }
+
+    pub fn pretty_print_expr(
+        &self,
+        db: &dyn DefDatabase,
+        owner: DefWithBodyId,
+        expr: ExprId,
+        edition: Edition,
+    ) -> String {
+        pretty::print_expr_hir(db, self, owner, expr, edition)
+    }
+
+    pub fn pretty_print_pat(
+        &self,
+        db: &dyn DefDatabase,
+        owner: DefWithBodyId,
+        pat: PatId,
+        oneline: bool,
+        edition: Edition,
+    ) -> String {
+        pretty::print_pat_hir(db, self, owner, pat, oneline, edition)
+    }
+}
+
+impl BodySourceMap {
+    pub fn self_param_syntax(&self) -> Option<InFile<SelfParamPtr>> {
+        self.self_param
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
index 16c7b5ca00a..88f770da02a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
@@ -29,11 +29,14 @@ use triomphe::Arc;
 
 use crate::{
     attr::Attrs,
-    body::{Body, BodyDiagnostic, BodySourceMap, ExprPtr, HygieneId, LabelPtr, PatPtr},
     builtin_type::BuiltinUint,
     data::adt::StructKind,
     db::DefDatabase,
     expander::Expander,
+    expr_store::{
+        Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder,
+        ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, PatPtr,
+    },
     hir::{
         format_args::{
             self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind,
@@ -55,11 +58,11 @@ use crate::{
 
 type FxIndexSet<K> = indexmap::IndexSet<K, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
 
-pub(super) fn lower(
+pub(super) fn lower_body(
     db: &dyn DefDatabase,
     owner: DefWithBodyId,
     expander: Expander,
-    params: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
+    parameters: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
     body: Option<ast::Expr>,
     krate: CrateId,
     is_async_fn: bool,
@@ -75,35 +78,146 @@ pub(super) fn lower(
         };
         Arc::clone(span_map)
     });
-    ExprCollector {
-        db,
-        owner,
-        krate,
-        def_map: expander.module.def_map(db),
-        source_map: BodySourceMap::default(),
-        ast_id_map: db.ast_id_map(expander.current_file_id()),
-        body: Body::default(),
-        expander,
-        current_try_block_label: None,
-        is_lowering_coroutine: false,
-        label_ribs: Vec::new(),
-        current_binding_owner: None,
-        awaitable_context: None,
-        current_span_map: span_map,
-        current_block_legacy_macro_defs_count: FxHashMap::default(),
-    }
-    .collect(params, body, is_async_fn)
+
+    let mut self_param = None;
+    let mut source_map_self_param = None;
+    let mut params = vec![];
+    let mut collector = ExprCollector::new(db, owner, expander, krate, span_map);
+
+    let skip_body = match owner {
+        DefWithBodyId::FunctionId(it) => db.attrs(it.into()),
+        DefWithBodyId::StaticId(it) => db.attrs(it.into()),
+        DefWithBodyId::ConstId(it) => db.attrs(it.into()),
+        DefWithBodyId::InTypeConstId(_) => Attrs::EMPTY,
+        DefWithBodyId::VariantId(it) => db.attrs(it.into()),
+    }
+    .rust_analyzer_tool()
+    .any(|attr| *attr.path() == tool_path![skip]);
+    // If #[rust_analyzer::skip] annotated, only construct enough information for the signature
+    // and skip the body.
+    if skip_body {
+        if let Some((param_list, mut attr_enabled)) = parameters {
+            if let Some(self_param_syn) =
+                param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
+            {
+                let is_mutable =
+                    self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none();
+                let binding_id: la_arena::Idx<Binding> = collector.alloc_binding(
+                    Name::new_symbol_root(sym::self_.clone()),
+                    BindingAnnotation::new(is_mutable, false),
+                );
+                self_param = Some(binding_id);
+                source_map_self_param =
+                    Some(collector.expander.in_file(AstPtr::new(&self_param_syn)));
+            }
+            params = param_list
+                .params()
+                .zip(attr_enabled)
+                .filter(|(_, enabled)| *enabled)
+                .map(|_| collector.missing_pat())
+                .collect();
+        };
+        let body_expr = collector.missing_expr();
+        return (
+            Body {
+                store: collector.store.finish(),
+                params: params.into_boxed_slice(),
+                self_param,
+                body_expr,
+            },
+            BodySourceMap { self_param: source_map_self_param, store: collector.source_map },
+        );
+    }
+
+    if let Some((param_list, mut attr_enabled)) = parameters {
+        if let Some(self_param_syn) =
+            param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
+        {
+            let is_mutable =
+                self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none();
+            let binding_id: la_arena::Idx<Binding> = collector.alloc_binding(
+                Name::new_symbol_root(sym::self_.clone()),
+                BindingAnnotation::new(is_mutable, false),
+            );
+            let hygiene = self_param_syn
+                .name()
+                .map(|name| collector.hygiene_id_for(name.syntax().text_range().start()))
+                .unwrap_or(HygieneId::ROOT);
+            if !hygiene.is_root() {
+                collector.store.binding_hygiene.insert(binding_id, hygiene);
+            }
+            self_param = Some(binding_id);
+            source_map_self_param = Some(collector.expander.in_file(AstPtr::new(&self_param_syn)));
+        }
+
+        for (param, _) in param_list.params().zip(attr_enabled).filter(|(_, enabled)| *enabled) {
+            let param_pat = collector.collect_pat_top(param.pat());
+            params.push(param_pat);
+        }
+    };
+
+    let body_expr = collector.collect(
+        body,
+        if is_async_fn {
+            Awaitable::Yes
+        } else {
+            match owner {
+                DefWithBodyId::FunctionId(..) => Awaitable::No("non-async function"),
+                DefWithBodyId::StaticId(..) => Awaitable::No("static"),
+                DefWithBodyId::ConstId(..) | DefWithBodyId::InTypeConstId(..) => {
+                    Awaitable::No("constant")
+                }
+                DefWithBodyId::VariantId(..) => Awaitable::No("enum variant"),
+            }
+        },
+    );
+
+    (
+        Body {
+            store: collector.store.finish(),
+            params: params.into_boxed_slice(),
+            self_param,
+            body_expr,
+        },
+        BodySourceMap { self_param: source_map_self_param, store: collector.source_map },
+    )
 }
 
+#[allow(dead_code)]
+pub(super) fn lower(
+    db: &dyn DefDatabase,
+    owner: ExprStoreOwnerId,
+    expander: Expander,
+    body: Option<ast::Expr>,
+    krate: CrateId,
+) -> (ExpressionStore, ExpressionStoreSourceMap) {
+    // We cannot leave the root span map empty and let any identifier from it be treated as root,
+    // because when inside nested macros `SyntaxContextId`s from the outer macro will be interleaved
+    // with the inner macro, and that will cause confusion because they won't be the same as `ROOT`
+    // even though they should be the same. Also, when the body comes from multiple expansions, their
+    // hygiene is different.
+    let span_map = expander.current_file_id().macro_file().map(|_| {
+        let SpanMap::ExpansionSpanMap(span_map) = expander.span_map(db) else {
+            panic!("in a macro file there should be `ExpansionSpanMap`");
+        };
+        Arc::clone(span_map)
+    });
+    let mut expr_collector = ExprCollector::new(db, owner, expander, krate, span_map);
+    expr_collector.collect(body, Awaitable::No("?"));
+    (expr_collector.store.finish(), expr_collector.source_map)
+}
+
+type ExprStoreOwnerId = DefWithBodyId;
+
 struct ExprCollector<'a> {
     db: &'a dyn DefDatabase,
     expander: Expander,
-    owner: DefWithBodyId,
+    owner: ExprStoreOwnerId,
     def_map: Arc<DefMap>,
     ast_id_map: Arc<AstIdMap>,
     krate: CrateId,
-    body: Body,
-    source_map: BodySourceMap,
+    store: ExpressionStoreBuilder,
+    source_map: ExpressionStoreSourceMap,
 
     is_lowering_coroutine: bool,
 
@@ -157,6 +271,7 @@ impl RibKind {
     }
 }
 
+#[derive(PartialEq, Eq, Debug, Copy, Clone)]
 enum Awaitable {
     Yes,
     No(&'static str),
@@ -180,12 +295,12 @@ impl BindingList {
         let id = *self.map.entry((name, hygiene)).or_insert_with_key(|(name, _)| {
             let id = ec.alloc_binding(name.clone(), mode);
             if !hygiene.is_root() {
-                ec.body.binding_hygiene.insert(id, hygiene);
+                ec.store.binding_hygiene.insert(id, hygiene);
             }
             id
         });
-        if ec.body.bindings[id].mode != mode {
-            ec.body.bindings[id].problems = Some(BindingProblems::BoundInconsistently);
+        if ec.store.bindings[id].mode != mode {
+            ec.store.bindings[id].problems = Some(BindingProblems::BoundInconsistently);
         }
         self.check_is_used(ec, id);
         id
@@ -195,11 +310,11 @@ impl BindingList {
         match self.is_used.get(&id) {
             None => {
                 if self.reject_new {
-                    ec.body.bindings[id].problems = Some(BindingProblems::NotBoundAcrossAll);
+                    ec.store.bindings[id].problems = Some(BindingProblems::NotBoundAcrossAll);
                 }
             }
             Some(true) => {
-                ec.body.bindings[id].problems = Some(BindingProblems::BoundMoreThanOnce);
+                ec.store.bindings[id].problems = Some(BindingProblems::BoundMoreThanOnce);
             }
             Some(false) => {}
         }
@@ -208,93 +323,37 @@ impl BindingList {
 }
 
 impl ExprCollector<'_> {
-    fn collect(
-        mut self,
-        param_list: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
-        body: Option<ast::Expr>,
-        is_async_fn: bool,
-    ) -> (Body, BodySourceMap) {
-        let skip_body = match self.owner {
-            DefWithBodyId::FunctionId(it) => self.db.attrs(it.into()),
-            DefWithBodyId::StaticId(it) => self.db.attrs(it.into()),
-            DefWithBodyId::ConstId(it) => self.db.attrs(it.into()),
-            DefWithBodyId::InTypeConstId(_) => Attrs::EMPTY,
-            DefWithBodyId::VariantId(it) => self.db.attrs(it.into()),
+    fn new(
+        db: &dyn DefDatabase,
+        owner: ExprStoreOwnerId,
+        expander: Expander,
+        krate: CrateId,
+        span_map: Option<Arc<ExpansionSpanMap>>,
+    ) -> ExprCollector<'_> {
+        ExprCollector {
+            db,
+            owner,
+            krate,
+            def_map: expander.module.def_map(db),
+            source_map: ExpressionStoreSourceMap::default(),
+            ast_id_map: db.ast_id_map(expander.current_file_id()),
+            store: ExpressionStoreBuilder::default(),
+            expander,
+            current_try_block_label: None,
+            is_lowering_coroutine: false,
+            label_ribs: Vec::new(),
+            current_binding_owner: None,
+            awaitable_context: None,
+            current_span_map: span_map,
+            current_block_legacy_macro_defs_count: FxHashMap::default(),
         }
-        .rust_analyzer_tool()
-        .any(|attr| *attr.path() == tool_path![skip]);
-        // If #[rust_analyzer::skip] annotated, only construct enough information for the signature
-        // and skip the body.
-        if skip_body {
-            self.body.body_expr = self.missing_expr();
-            if let Some((param_list, mut attr_enabled)) = param_list {
-                if let Some(self_param) =
-                    param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
-                {
-                    let is_mutable =
-                        self_param.mut_token().is_some() && self_param.amp_token().is_none();
-                    let binding_id: la_arena::Idx<Binding> = self.alloc_binding(
-                        Name::new_symbol_root(sym::self_.clone()),
-                        BindingAnnotation::new(is_mutable, false),
-                    );
-                    self.body.self_param = Some(binding_id);
-                    self.source_map.self_param =
-                        Some(self.expander.in_file(AstPtr::new(&self_param)));
-                }
-                self.body.params = param_list
-                    .params()
-                    .zip(attr_enabled)
-                    .filter(|(_, enabled)| *enabled)
-                    .map(|_| self.missing_pat())
-                    .collect();
-            };
-            return (self.body, self.source_map);
-        }
-
-        self.awaitable_context.replace(if is_async_fn {
-            Awaitable::Yes
-        } else {
-            match self.owner {
-                DefWithBodyId::FunctionId(..) => Awaitable::No("non-async function"),
-                DefWithBodyId::StaticId(..) => Awaitable::No("static"),
-                DefWithBodyId::ConstId(..) | DefWithBodyId::InTypeConstId(..) => {
-                    Awaitable::No("constant")
-                }
-                DefWithBodyId::VariantId(..) => Awaitable::No("enum variant"),
-            }
-        });
-        if let Some((param_list, mut attr_enabled)) = param_list {
-            let mut params = vec![];
-            if let Some(self_param) =
-                param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
-            {
-                let is_mutable =
-                    self_param.mut_token().is_some() && self_param.amp_token().is_none();
-                let binding_id: la_arena::Idx<Binding> = self.alloc_binding(
-                    Name::new_symbol_root(sym::self_.clone()),
-                    BindingAnnotation::new(is_mutable, false),
-                );
-                let hygiene = self_param
-                    .name()
-                    .map(|name| self.hygiene_id_for(name.syntax().text_range().start()))
-                    .unwrap_or(HygieneId::ROOT);
-                if !hygiene.is_root() {
-                    self.body.binding_hygiene.insert(binding_id, hygiene);
-                }
-                self.body.self_param = Some(binding_id);
-                self.source_map.self_param = Some(self.expander.in_file(AstPtr::new(&self_param)));
-            }
+    }
 
-            for (param, _) in param_list.params().zip(attr_enabled).filter(|(_, enabled)| *enabled)
-            {
-                let param_pat = self.collect_pat_top(param.pat());
-                params.push(param_pat);
-            }
-            self.body.params = params.into_boxed_slice();
-        };
-        self.body.body_expr = self.with_label_rib(RibKind::Closure, |this| {
-            if is_async_fn {
-                match body {
+    fn collect(&mut self, expr: Option<ast::Expr>, awaitable: Awaitable) -> ExprId {
+        self.awaitable_context.replace(awaitable);
+        self.with_label_rib(RibKind::Closure, |this| {
+            if awaitable == Awaitable::Yes {
+                match expr {
                     Some(e) => {
                         let syntax_ptr = AstPtr::new(&e);
                         let expr = this.collect_expr(e);
@@ -306,15 +365,13 @@ impl ExprCollector<'_> {
                     None => this.missing_expr(),
                 }
             } else {
-                this.collect_expr_opt(body)
+                this.collect_expr_opt(expr)
             }
-        });
-
-        (self.body, self.source_map)
+        })
     }
 
     fn ctx(&mut self) -> LowerCtx<'_> {
-        self.expander.ctx(self.db, &mut self.body.types, &mut self.source_map.types)
+        self.expander.ctx(self.db, &mut self.store.types, &mut self.source_map.types)
     }
 
     fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
@@ -390,7 +447,7 @@ impl ExprCollector<'_> {
                                 parent: this.owner,
                                 root: inner_expr,
                             });
-                            this.body.exprs[result_expr_id] = Expr::Const(it);
+                            this.store.exprs[result_expr_id] = Expr::Const(it);
                             this.current_binding_owner = prev_binding_owner;
                             result_expr_id
                         })
@@ -480,7 +537,7 @@ impl ExprCollector<'_> {
                     .unwrap_or((Expr::Missing, HygieneId::ROOT));
                 let expr_id = self.alloc_expr(path, syntax_ptr);
                 if !hygiene.is_root() {
-                    self.body.expr_hygiene.insert(expr_id, hygiene);
+                    self.store.ident_hygiene.insert(expr_id.into(), hygiene);
                 }
                 expr_id
             }
@@ -562,10 +619,12 @@ impl ExprCollector<'_> {
             ast::Expr::AwaitExpr(e) => {
                 let expr = self.collect_expr_opt(e.expr());
                 if let Awaitable::No(location) = self.is_lowering_awaitable_block() {
-                    self.source_map.diagnostics.push(BodyDiagnostic::AwaitOutsideOfAsync {
-                        node: InFile::new(self.expander.current_file_id(), AstPtr::new(&e)),
-                        location: location.to_string(),
-                    });
+                    self.source_map.diagnostics.push(
+                        ExpressionStoreDiagnostics::AwaitOutsideOfAsync {
+                            node: InFile::new(self.expander.current_file_id(), AstPtr::new(&e)),
+                            location: location.to_string(),
+                        },
+                    );
                 }
                 self.alloc_expr(Expr::Await { expr }, syntax_ptr)
             }
@@ -646,7 +705,7 @@ impl ExprCollector<'_> {
                 this.is_lowering_coroutine = prev_is_lowering_coroutine;
                 this.current_binding_owner = prev_binding_owner;
                 this.current_try_block_label = prev_try_block_label;
-                this.body.exprs[result_expr_id] = Expr::Closure {
+                this.store.exprs[result_expr_id] = Expr::Closure {
                     args: args.into(),
                     arg_types: arg_types.into(),
                     ret_type,
@@ -752,7 +811,7 @@ impl ExprCollector<'_> {
     }
 
     fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
-        self.expander.parse_path(self.db, path, &mut self.body.types, &mut self.source_map.types)
+        self.expander.parse_path(self.db, path, &mut self.store.types, &mut self.source_map.types)
     }
 
     fn collect_expr_path(&mut self, e: ast::PathExpr) -> Option<(Path, HygieneId)> {
@@ -781,7 +840,7 @@ impl ExprCollector<'_> {
             let src = self.expander.in_file(AstPtr::new(&expr).wrap_left());
             let expr = self.collect_expr(expr);
             // Do not use `alloc_pat_from_expr()` here, it will override the entry in `expr_map`.
-            let id = self.body.pats.alloc(Pat::Expr(expr));
+            let id = self.store.pats.alloc(Pat::Expr(expr));
             self.source_map.pat_map_back.insert(id, src);
             id
         })
@@ -835,7 +894,7 @@ impl ExprCollector<'_> {
                     .unwrap_or((Pat::Missing, HygieneId::ROOT));
                 let pat_id = self.alloc_pat_from_expr(path, syntax_ptr);
                 if !hygiene.is_root() {
-                    self.body.pat_hygiene.insert(pat_id, hygiene);
+                    self.store.ident_hygiene.insert(pat_id.into(), hygiene);
                 }
                 pat_id
             }
@@ -967,7 +1026,7 @@ impl ExprCollector<'_> {
     ) -> ExprId {
         let (id, prev_owner) = self.initialize_binding_owner(syntax_ptr);
         let tmp = job(self);
-        self.body.exprs[id] = mem::replace(&mut self.body.exprs[tmp], Expr::Missing);
+        self.store.exprs[id] = mem::replace(&mut self.store.exprs[tmp], Expr::Missing);
         self.current_binding_owner = prev_owner;
         id
     }
@@ -979,8 +1038,9 @@ impl ExprCollector<'_> {
         let Some(try_from_output) = self.lang_path(LangItem::TryTraitFromOutput) else {
             return self.collect_block(e);
         };
-        let label = self
-            .alloc_label_desugared(Label { name: Name::generate_new_name(self.body.labels.len()) });
+        let label = self.alloc_label_desugared(Label {
+            name: Name::generate_new_name(self.store.labels.len()),
+        });
         let old_label = self.current_try_block_label.replace(label);
 
         let ptr = AstPtr::new(&e).upcast();
@@ -1006,7 +1066,7 @@ impl ExprCollector<'_> {
                 )
             }
         };
-        let Expr::Block { tail, .. } = &mut self.body.exprs[expr_id] else {
+        let Expr::Block { tail, .. } = &mut self.store.exprs[expr_id] else {
             unreachable!("block was lowered to non-block");
         };
         *tail = Some(next_tail);
@@ -1112,7 +1172,7 @@ impl ExprCollector<'_> {
                 this.collect_expr_opt(e.loop_body().map(|it| it.into()))
             }),
         };
-        let iter_name = Name::generate_new_name(self.body.exprs.len());
+        let iter_name = Name::generate_new_name(self.store.exprs.len());
         let iter_expr = self.alloc_expr(Expr::Path(Path::from(iter_name.clone())), syntax_ptr);
         let iter_expr_mut = self.alloc_expr(
             Expr::Ref { expr: iter_expr, rawness: Rawness::Ref, mutability: Mutability::Mut },
@@ -1177,7 +1237,7 @@ impl ExprCollector<'_> {
         let try_branch = self.alloc_expr(Expr::Path(try_branch), syntax_ptr);
         let expr = self
             .alloc_expr(Expr::Call { callee: try_branch, args: Box::new([operand]) }, syntax_ptr);
-        let continue_name = Name::generate_new_name(self.body.bindings.len());
+        let continue_name = Name::generate_new_name(self.store.bindings.len());
         let continue_binding =
             self.alloc_binding(continue_name.clone(), BindingAnnotation::Unannotated);
         let continue_bpat =
@@ -1192,7 +1252,7 @@ impl ExprCollector<'_> {
             guard: None,
             expr: self.alloc_expr(Expr::Path(Path::from(continue_name)), syntax_ptr),
         };
-        let break_name = Name::generate_new_name(self.body.bindings.len());
+        let break_name = Name::generate_new_name(self.store.bindings.len());
         let break_binding = self.alloc_binding(break_name.clone(), BindingAnnotation::Unannotated);
         let break_bpat = self.alloc_pat_desugared(Pat::Bind { id: break_binding, subpat: None });
         self.add_definition_to_binding(break_binding, break_bpat);
@@ -1261,17 +1321,19 @@ impl ExprCollector<'_> {
             Ok(res) => res,
             Err(UnresolvedMacro { path }) => {
                 if record_diagnostics {
-                    self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall {
-                        node: InFile::new(outer_file, syntax_ptr),
-                        path,
-                    });
+                    self.source_map.diagnostics.push(
+                        ExpressionStoreDiagnostics::UnresolvedMacroCall {
+                            node: InFile::new(outer_file, syntax_ptr),
+                            path,
+                        },
+                    );
                 }
                 return collector(self, None);
             }
         };
         if record_diagnostics {
             if let Some(err) = res.err {
-                self.source_map.diagnostics.push(BodyDiagnostic::MacroError {
+                self.source_map.diagnostics.push(ExpressionStoreDiagnostics::MacroError {
                     node: InFile::new(outer_file, syntax_ptr),
                     err,
                 });
@@ -1464,7 +1526,7 @@ impl ExprCollector<'_> {
         let (module, def_map) =
             match block_id.map(|block_id| (self.db.block_def_map(block_id), block_id)) {
                 Some((def_map, block_id)) => {
-                    self.body.block_scopes.push(block_id);
+                    self.store.block_scopes.push(block_id);
                     (def_map.module_id(DefMap::ROOT), def_map)
                 }
                 None => (self.expander.module, self.def_map.clone()),
@@ -1621,7 +1683,7 @@ impl ExprCollector<'_> {
                     pats.push(self.collect_pat(rest, binding_list));
                     for (&id, &is_used) in binding_list.is_used.iter() {
                         if !is_used {
-                            self.body.bindings[id].problems =
+                            self.store.bindings[id].problems =
                                 Some(BindingProblems::NotBoundAcrossAll);
                         }
                     }
@@ -1825,7 +1887,7 @@ impl ExprCollector<'_> {
                     return Some(());
                 }
 
-                self.source_map.diagnostics.push(BodyDiagnostic::InactiveCode {
+                self.source_map.diagnostics.push(ExpressionStoreDiagnostics::InactiveCode {
                     node: self.expander.in_file(SyntaxNodePtr::new(owner.syntax())),
                     cfg,
                     opts: self.expander.cfg_options().clone(),
@@ -1853,7 +1915,7 @@ impl ExprCollector<'_> {
     fn resolve_label(
         &self,
         lifetime: Option<ast::Lifetime>,
-    ) -> Result<Option<LabelId>, BodyDiagnostic> {
+    ) -> Result<Option<LabelId>, ExpressionStoreDiagnostics> {
         let Some(lifetime) = lifetime else { return Ok(None) };
         let (mut hygiene_id, mut hygiene_info) = match &self.current_span_map {
             None => (HygieneId::ROOT, None),
@@ -1877,7 +1939,7 @@ impl ExprCollector<'_> {
                         return if self.is_label_valid_from_rib(rib_idx) {
                             Ok(Some(*id))
                         } else {
-                            Err(BodyDiagnostic::UnreachableLabel {
+                            Err(ExpressionStoreDiagnostics::UnreachableLabel {
                                 name,
                                 node: self.expander.in_file(AstPtr::new(&lifetime)),
                             })
@@ -1903,7 +1965,7 @@ impl ExprCollector<'_> {
             }
         }
 
-        Err(BodyDiagnostic::UndeclaredLabel {
+        Err(ExpressionStoreDiagnostics::UndeclaredLabel {
             name,
             node: self.expander.in_file(AstPtr::new(&lifetime)),
         })
@@ -1934,7 +1996,7 @@ impl ExprCollector<'_> {
         f: impl FnOnce(&mut Self) -> T,
     ) -> T {
         self.label_ribs.push(LabelRib::new(RibKind::Normal(
-            self.body[label].name.clone(),
+            self.store.labels[label].name.clone(),
             label,
             hygiene,
         )));
@@ -2023,7 +2085,7 @@ impl ExprCollector<'_> {
                                 );
                         }
                         if !hygiene.is_root() {
-                            self.body.expr_hygiene.insert(expr_id, hygiene);
+                            self.store.ident_hygiene.insert(expr_id.into(), hygiene);
                         }
                         expr_id
                     },
@@ -2171,17 +2233,27 @@ impl ExprCollector<'_> {
         let unsafe_arg_new = self.alloc_expr_desugared(Expr::Path(unsafe_arg_new));
         let unsafe_arg_new =
             self.alloc_expr_desugared(Expr::Call { callee: unsafe_arg_new, args: Box::default() });
-        let unsafe_arg_new = self.alloc_expr_desugared(Expr::Unsafe {
+        let mut unsafe_arg_new = self.alloc_expr_desugared(Expr::Unsafe {
             id: None,
-            // We collect the unused expressions here so that we still infer them instead of
-            // dropping them out of the expression tree
-            statements: fmt
-                .orphans
-                .into_iter()
-                .map(|expr| Statement::Expr { expr, has_semi: true })
-                .collect(),
+            statements: Box::new([]),
             tail: Some(unsafe_arg_new),
         });
+        if !fmt.orphans.is_empty() {
+            unsafe_arg_new = self.alloc_expr_desugared(Expr::Block {
+                id: None,
+                // We collect the unused expressions here so that we still infer them instead of
+                // dropping them out of the expression tree. We cannot store them in the `Unsafe`
+                // block because then unsafe blocks within them will get a false "unused unsafe"
+                // diagnostic (rustc has a notion of builtin unsafe blocks, but we don't).
+                statements: fmt
+                    .orphans
+                    .into_iter()
+                    .map(|expr| Statement::Expr { expr, has_semi: true })
+                    .collect(),
+                tail: Some(unsafe_arg_new),
+                label: None,
+            });
+        }
 
         let idx = self.alloc_expr(
             Expr::Call {
@@ -2417,7 +2489,7 @@ fn pat_literal_to_hir(lit: &ast::LiteralPat) -> Option<(Literal, ast::Literal)>
 impl ExprCollector<'_> {
     fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
         let src = self.expander.in_file(ptr);
-        let id = self.body.exprs.alloc(expr);
+        let id = self.store.exprs.alloc(expr);
         self.source_map.expr_map_back.insert(id, src);
         self.source_map.expr_map.insert(src, id.into());
         id
@@ -2425,11 +2497,11 @@ impl ExprCollector<'_> {
     // FIXME: desugared exprs don't have ptr, that's wrong and should be fixed.
     // Migrate to alloc_expr_desugared_with_ptr and then rename back
     fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
-        self.body.exprs.alloc(expr)
+        self.store.exprs.alloc(expr)
     }
     fn alloc_expr_desugared_with_ptr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
         let src = self.expander.in_file(ptr);
-        let id = self.body.exprs.alloc(expr);
+        let id = self.store.exprs.alloc(expr);
         self.source_map.expr_map_back.insert(id, src);
         // We intentionally don't fill this as it could overwrite a non-desugared entry
         // self.source_map.expr_map.insert(src, id);
@@ -2440,45 +2512,45 @@ impl ExprCollector<'_> {
     }
 
     fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
-        let binding = self.body.bindings.alloc(Binding { name, mode, problems: None });
+        let binding = self.store.bindings.alloc(Binding { name, mode, problems: None });
         if let Some(owner) = self.current_binding_owner {
-            self.body.binding_owners.insert(binding, owner);
+            self.store.binding_owners.insert(binding, owner);
         }
         binding
     }
 
     fn alloc_pat_from_expr(&mut self, pat: Pat, ptr: ExprPtr) -> PatId {
         let src = self.expander.in_file(ptr);
-        let id = self.body.pats.alloc(pat);
+        let id = self.store.pats.alloc(pat);
         self.source_map.expr_map.insert(src, id.into());
         self.source_map.pat_map_back.insert(id, src.map(AstPtr::wrap_left));
         id
     }
     fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {
         let src = self.expander.in_file(ptr);
-        let id = self.body.pats.alloc(pat);
+        let id = self.store.pats.alloc(pat);
         self.source_map.pat_map_back.insert(id, src.map(AstPtr::wrap_right));
         self.source_map.pat_map.insert(src, id);
         id
     }
     // FIXME: desugared pats don't have ptr, that's wrong and should be fixed somehow.
     fn alloc_pat_desugared(&mut self, pat: Pat) -> PatId {
-        self.body.pats.alloc(pat)
+        self.store.pats.alloc(pat)
     }
     fn missing_pat(&mut self) -> PatId {
-        self.body.pats.alloc(Pat::Missing)
+        self.store.pats.alloc(Pat::Missing)
     }
 
     fn alloc_label(&mut self, label: Label, ptr: LabelPtr) -> LabelId {
         let src = self.expander.in_file(ptr);
-        let id = self.body.labels.alloc(label);
+        let id = self.store.labels.alloc(label);
         self.source_map.label_map_back.insert(id, src);
         self.source_map.label_map.insert(src, id);
         id
     }
     // FIXME: desugared labels don't have ptr, that's wrong and should be fixed somehow.
     fn alloc_label_desugared(&mut self, label: Label) -> LabelId {
-        self.body.labels.alloc(label)
+        self.store.labels.alloc(label)
     }
 
     fn is_lowering_awaitable_block(&self) -> &Awaitable {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
index 994ba2aa069..032c18688ea 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
@@ -9,7 +9,7 @@ use syntax::{
 use tt::TextRange;
 
 use crate::{
-    body::lower::{ExprCollector, FxIndexSet},
+    expr_store::lower::{ExprCollector, FxIndexSet},
     hir::{AsmOperand, AsmOptions, Expr, ExprId, InlineAsm, InlineAsmRegOrRegClass},
 };
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
index 52b91b522a4..6a0b1e51979 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
@@ -60,7 +60,7 @@ pub(super) fn print_body_hir(
 
     let mut p = Printer {
         db,
-        body,
+        store: body,
         buf: header,
         indent_level: 0,
         line_format: LineFormat::Newline,
@@ -103,14 +103,14 @@ pub(super) fn print_body_hir(
 
 pub(super) fn print_expr_hir(
     db: &dyn DefDatabase,
-    body: &Body,
+    store: &ExpressionStore,
     _owner: DefWithBodyId,
     expr: ExprId,
     edition: Edition,
 ) -> String {
     let mut p = Printer {
         db,
-        body,
+        store,
         buf: String::new(),
         indent_level: 0,
         line_format: LineFormat::Newline,
@@ -122,7 +122,7 @@ pub(super) fn print_expr_hir(
 
 pub(super) fn print_pat_hir(
     db: &dyn DefDatabase,
-    body: &Body,
+    store: &ExpressionStore,
     _owner: DefWithBodyId,
     pat: PatId,
     oneline: bool,
@@ -130,7 +130,7 @@ pub(super) fn print_pat_hir(
 ) -> String {
     let mut p = Printer {
         db,
-        body,
+        store,
         buf: String::new(),
         indent_level: 0,
         line_format: if oneline { LineFormat::Oneline } else { LineFormat::Newline },
@@ -157,7 +157,7 @@ macro_rules! wln {
 
 struct Printer<'a> {
     db: &'a dyn DefDatabase,
-    body: &'a Body,
+    store: &'a ExpressionStore,
     buf: String,
     indent_level: usize,
     line_format: LineFormat,
@@ -233,7 +233,7 @@ impl Printer<'_> {
     }
 
     fn print_expr(&mut self, expr: ExprId) {
-        let expr = &self.body[expr];
+        let expr = &self.store[expr];
 
         match expr {
             Expr::Missing => w!(self, "�"),
@@ -241,7 +241,7 @@ impl Printer<'_> {
             Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"),
             Expr::OffsetOf(offset_of) => {
                 w!(self, "builtin#offset_of(");
-                self.print_type_ref(offset_of.container, &self.body.types);
+                self.print_type_ref(offset_of.container, &self.store.types);
                 let edition = self.edition;
                 w!(
                     self,
@@ -271,7 +271,7 @@ impl Printer<'_> {
             }
             Expr::Loop { body, label } => {
                 if let Some(lbl) = label {
-                    w!(self, "{}: ", self.body[*lbl].name.display(self.db.upcast(), self.edition));
+                    w!(self, "{}: ", self.store[*lbl].name.display(self.db.upcast(), self.edition));
                 }
                 w!(self, "loop ");
                 self.print_expr(*body);
@@ -295,7 +295,7 @@ impl Printer<'_> {
                 if let Some(args) = generic_args {
                     w!(self, "::<");
                     let edition = self.edition;
-                    print_generic_args(self.db, args, &self.body.types, self, edition).unwrap();
+                    print_generic_args(self.db, args, &self.store.types, self, edition).unwrap();
                     w!(self, ">");
                 }
                 w!(self, "(");
@@ -330,13 +330,13 @@ impl Printer<'_> {
             Expr::Continue { label } => {
                 w!(self, "continue");
                 if let Some(lbl) = label {
-                    w!(self, " {}", self.body[*lbl].name.display(self.db.upcast(), self.edition));
+                    w!(self, " {}", self.store[*lbl].name.display(self.db.upcast(), self.edition));
                 }
             }
             Expr::Break { expr, label } => {
                 w!(self, "break");
                 if let Some(lbl) = label {
-                    w!(self, " {}", self.body[*lbl].name.display(self.db.upcast(), self.edition));
+                    w!(self, " {}", self.store[*lbl].name.display(self.db.upcast(), self.edition));
                 }
                 if let Some(expr) = expr {
                     self.whitespace();
@@ -404,7 +404,7 @@ impl Printer<'_> {
             Expr::Cast { expr, type_ref } => {
                 self.print_expr(*expr);
                 w!(self, " as ");
-                self.print_type_ref(*type_ref, &self.body.types);
+                self.print_type_ref(*type_ref, &self.store.types);
             }
             Expr::Ref { expr, rawness, mutability } => {
                 w!(self, "&");
@@ -492,13 +492,13 @@ impl Printer<'_> {
                     self.print_pat(*pat);
                     if let Some(ty) = ty {
                         w!(self, ": ");
-                        self.print_type_ref(*ty, &self.body.types);
+                        self.print_type_ref(*ty, &self.store.types);
                     }
                 }
                 w!(self, "|");
                 if let Some(ret_ty) = ret_type {
                     w!(self, " -> ");
-                    self.print_type_ref(*ret_ty, &self.body.types);
+                    self.print_type_ref(*ret_ty, &self.store.types);
                 }
                 self.whitespace();
                 self.print_expr(*body);
@@ -534,7 +534,7 @@ impl Printer<'_> {
             Expr::Literal(lit) => self.print_literal(lit),
             Expr::Block { id: _, statements, tail, label } => {
                 let label = label.map(|lbl| {
-                    format!("{}: ", self.body[lbl].name.display(self.db.upcast(), self.edition))
+                    format!("{}: ", self.store[lbl].name.display(self.db.upcast(), self.edition))
                 });
                 self.print_block(label.as_deref(), statements, tail);
             }
@@ -581,7 +581,7 @@ impl Printer<'_> {
     }
 
     fn print_pat(&mut self, pat: PatId) {
-        let pat = &self.body[pat];
+        let pat = &self.store[pat];
 
         match pat {
             Pat::Missing => w!(self, "�"),
@@ -623,9 +623,9 @@ impl Printer<'_> {
                         let field_name = arg.name.display(self.db.upcast(), edition).to_string();
 
                         let mut same_name = false;
-                        if let Pat::Bind { id, subpat: None } = &self.body[arg.pat] {
+                        if let Pat::Bind { id, subpat: None } = &self.store[arg.pat] {
                             if let Binding { name, mode: BindingAnnotation::Unannotated, .. } =
-                                &self.body.bindings[*id]
+                                &self.store.bindings[*id]
                             {
                                 if name.as_str() == field_name {
                                     same_name = true;
@@ -734,7 +734,7 @@ impl Printer<'_> {
                 self.print_pat(*pat);
                 if let Some(ty) = type_ref {
                     w!(self, ": ");
-                    self.print_type_ref(*ty, &self.body.types);
+                    self.print_type_ref(*ty, &self.store.types);
                 }
                 if let Some(init) = initializer {
                     w!(self, " = ");
@@ -799,11 +799,11 @@ impl Printer<'_> {
 
     fn print_path(&mut self, path: &Path) {
         let edition = self.edition;
-        print_path(self.db, path, &self.body.types, self, edition).unwrap();
+        print_path(self.db, path, &self.store.types, self, edition).unwrap();
     }
 
     fn print_binding(&mut self, id: BindingId) {
-        let Binding { name, mode, .. } = &self.body.bindings[id];
+        let Binding { name, mode, .. } = &self.store.bindings[id];
         let mode = match mode {
             BindingAnnotation::Unannotated => "",
             BindingAnnotation::Mutable => "mut ",
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs
index 08af470b965..859a706177a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs
@@ -4,8 +4,8 @@ use la_arena::{Arena, ArenaMap, Idx, IdxRange, RawIdx};
 use triomphe::Arc;
 
 use crate::{
-    body::{Body, HygieneId},
     db::DefDatabase,
+    expr_store::{Body, ExpressionStore, HygieneId},
     hir::{Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement},
     BlockId, ConstBlockId, DefWithBodyId,
 };
@@ -53,7 +53,7 @@ pub struct ScopeData {
 impl ExprScopes {
     pub(crate) fn expr_scopes_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<ExprScopes> {
         let body = db.body(def);
-        let mut scopes = ExprScopes::new(&body, |const_block| {
+        let mut scopes = ExprScopes::new_body(&body, |const_block| {
             db.lookup_intern_anonymous_const(const_block).root
         });
         scopes.shrink_to_fit();
@@ -104,7 +104,7 @@ fn empty_entries(idx: usize) -> IdxRange<ScopeEntry> {
 }
 
 impl ExprScopes {
-    fn new(
+    fn new_body(
         body: &Body,
         resolve_const_block: impl (Fn(ConstBlockId) -> ExprId) + Copy,
     ) -> ExprScopes {
@@ -179,28 +179,28 @@ impl ExprScopes {
 
     fn add_bindings(
         &mut self,
-        body: &Body,
+        store: &ExpressionStore,
         scope: ScopeId,
         binding: BindingId,
         hygiene: HygieneId,
     ) {
-        let Binding { name, .. } = &body.bindings[binding];
+        let Binding { name, .. } = &store.bindings[binding];
         let entry = self.scope_entries.alloc(ScopeEntry { name: name.clone(), binding, hygiene });
         self.scopes[scope].entries =
             IdxRange::new_inclusive(self.scopes[scope].entries.start()..=entry);
     }
 
-    fn add_pat_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) {
-        let pattern = &body[pat];
+    fn add_pat_bindings(&mut self, store: &ExpressionStore, scope: ScopeId, pat: PatId) {
+        let pattern = &store[pat];
         if let Pat::Bind { id, .. } = *pattern {
-            self.add_bindings(body, scope, id, body.binding_hygiene(id));
+            self.add_bindings(store, scope, id, store.binding_hygiene(id));
         }
 
-        pattern.walk_child_pats(|pat| self.add_pat_bindings(body, scope, pat));
+        pattern.walk_child_pats(|pat| self.add_pat_bindings(store, scope, pat));
     }
 
-    fn add_params_bindings(&mut self, body: &Body, scope: ScopeId, params: &[PatId]) {
-        params.iter().for_each(|pat| self.add_pat_bindings(body, scope, *pat));
+    fn add_params_bindings(&mut self, store: &ExpressionStore, scope: ScopeId, params: &[PatId]) {
+        params.iter().for_each(|pat| self.add_pat_bindings(store, scope, *pat));
     }
 
     fn set_scope(&mut self, node: ExprId, scope: ScopeId) {
@@ -218,7 +218,7 @@ impl ExprScopes {
 fn compute_block_scopes(
     statements: &[Statement],
     tail: Option<ExprId>,
-    body: &Body,
+    store: &ExpressionStore,
     scopes: &mut ExprScopes,
     scope: &mut ScopeId,
     resolve_const_block: impl (Fn(ConstBlockId) -> ExprId) + Copy,
@@ -227,17 +227,17 @@ fn compute_block_scopes(
         match stmt {
             Statement::Let { pat, initializer, else_branch, .. } => {
                 if let Some(expr) = initializer {
-                    compute_expr_scopes(*expr, body, scopes, scope, resolve_const_block);
+                    compute_expr_scopes(*expr, store, scopes, scope, resolve_const_block);
                 }
                 if let Some(expr) = else_branch {
-                    compute_expr_scopes(*expr, body, scopes, scope, resolve_const_block);
+                    compute_expr_scopes(*expr, store, scopes, scope, resolve_const_block);
                 }
 
                 *scope = scopes.new_scope(*scope);
-                scopes.add_pat_bindings(body, *scope, *pat);
+                scopes.add_pat_bindings(store, *scope, *pat);
             }
             Statement::Expr { expr, .. } => {
-                compute_expr_scopes(*expr, body, scopes, scope, resolve_const_block);
+                compute_expr_scopes(*expr, store, scopes, scope, resolve_const_block);
             }
             Statement::Item(Item::MacroDef(macro_id)) => {
                 *scope = scopes.new_macro_def_scope(*scope, macro_id.clone());
@@ -246,32 +246,32 @@ fn compute_block_scopes(
         }
     }
     if let Some(expr) = tail {
-        compute_expr_scopes(expr, body, scopes, scope, resolve_const_block);
+        compute_expr_scopes(expr, store, scopes, scope, resolve_const_block);
     }
 }
 
 fn compute_expr_scopes(
     expr: ExprId,
-    body: &Body,
+    store: &ExpressionStore,
     scopes: &mut ExprScopes,
     scope: &mut ScopeId,
     resolve_const_block: impl (Fn(ConstBlockId) -> ExprId) + Copy,
 ) {
     let make_label =
-        |label: &Option<LabelId>| label.map(|label| (label, body.labels[label].name.clone()));
+        |label: &Option<LabelId>| label.map(|label| (label, store.labels[label].name.clone()));
 
     let compute_expr_scopes = |scopes: &mut ExprScopes, expr: ExprId, scope: &mut ScopeId| {
-        compute_expr_scopes(expr, body, scopes, scope, resolve_const_block)
+        compute_expr_scopes(expr, store, scopes, scope, resolve_const_block)
     };
 
     scopes.set_scope(expr, *scope);
-    match &body[expr] {
+    match &store[expr] {
         Expr::Block { statements, tail, id, label } => {
             let mut scope = scopes.new_block_scope(*scope, *id, make_label(label));
             // Overwrite the old scope for the block expr, so that every block scope can be found
             // via the block itself (important for blocks that only contain items, no expressions).
             scopes.set_scope(expr, scope);
-            compute_block_scopes(statements, *tail, body, scopes, &mut scope, resolve_const_block);
+            compute_block_scopes(statements, *tail, store, scopes, &mut scope, resolve_const_block);
         }
         Expr::Const(id) => {
             let mut scope = scopes.root_scope();
@@ -282,7 +282,7 @@ fn compute_expr_scopes(
             // Overwrite the old scope for the block expr, so that every block scope can be found
             // via the block itself (important for blocks that only contain items, no expressions).
             scopes.set_scope(expr, scope);
-            compute_block_scopes(statements, *tail, body, scopes, &mut scope, resolve_const_block);
+            compute_block_scopes(statements, *tail, store, scopes, &mut scope, resolve_const_block);
         }
         Expr::Loop { body: body_expr, label } => {
             let mut scope = scopes.new_labeled_scope(*scope, make_label(label));
@@ -290,14 +290,14 @@ fn compute_expr_scopes(
         }
         Expr::Closure { args, body: body_expr, .. } => {
             let mut scope = scopes.new_scope(*scope);
-            scopes.add_params_bindings(body, scope, args);
+            scopes.add_params_bindings(store, scope, args);
             compute_expr_scopes(scopes, *body_expr, &mut scope);
         }
         Expr::Match { expr, arms } => {
             compute_expr_scopes(scopes, *expr, scope);
             for arm in arms.iter() {
                 let mut scope = scopes.new_scope(*scope);
-                scopes.add_pat_bindings(body, scope, arm.pat);
+                scopes.add_pat_bindings(store, scope, arm.pat);
                 if let Some(guard) = arm.guard {
                     scope = scopes.new_scope(scope);
                     compute_expr_scopes(scopes, guard, &mut scope);
@@ -316,9 +316,9 @@ fn compute_expr_scopes(
         &Expr::Let { pat, expr } => {
             compute_expr_scopes(scopes, expr, scope);
             *scope = scopes.new_scope(*scope);
-            scopes.add_pat_bindings(body, *scope, pat);
+            scopes.add_pat_bindings(store, *scope, pat);
         }
-        _ => body.walk_child_exprs(expr, |e| compute_expr_scopes(scopes, e, scope)),
+        _ => store.walk_child_exprs(expr, |e| compute_expr_scopes(scopes, e, scope)),
     };
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs
index edc7c4c1f21..9bf1ddb4793 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests.rs
@@ -1,6 +1,7 @@
 mod block;
 
 use expect_test::{expect, Expect};
+use la_arena::RawIdx;
 use test_fixture::WithFixture;
 
 use crate::{test_db::TestDB, ModuleDefId};
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs
index e136dd18a55..e136dd18a55 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/block.rs
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
index 7b3f1d06d21..e2b36da79b2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
@@ -433,7 +433,7 @@ impl GenericParams {
             GenericDefId::TraitAliasId(id) => id_to_generics(db, id, enabled_params),
             GenericDefId::TypeAliasId(id) => id_to_generics(db, id, enabled_params),
             GenericDefId::ImplId(id) => id_to_generics(db, id, enabled_params),
-            GenericDefId::ConstId(_) => (
+            GenericDefId::ConstId(_) | GenericDefId::StaticId(_) => (
                 Arc::new(GenericParams {
                     type_or_consts: Default::default(),
                     lifetimes: Default::default(),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
index 85963469430..0dcddf162b2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
@@ -19,7 +19,7 @@ use std::fmt;
 
 use hir_expand::{name::Name, MacroDefId};
 use intern::Symbol;
-use la_arena::{Idx, RawIdx};
+use la_arena::Idx;
 use rustc_apfloat::ieee::{Half as f16, Quad as f128};
 use syntax::ast;
 use type_ref::TypeRefId;
@@ -37,13 +37,10 @@ pub type BindingId = Idx<Binding>;
 
 pub type ExprId = Idx<Expr>;
 
-/// FIXME: this is a hacky function which should be removed
-pub(crate) fn dummy_expr_id() -> ExprId {
-    ExprId::from_raw(RawIdx::from(u32::MAX))
-}
-
 pub type PatId = Idx<Pat>;
 
+// FIXME: Encode this as a single u32, we won't ever reach all 32 bits especially given these counts
+// are local to the body.
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub enum ExprOrPatId {
     ExprId(ExprId),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
index 34635997bdf..6137bd34d64 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
@@ -519,7 +519,7 @@ mod tests {
                 crate_graph[krate]
                     .display_name
                     .as_ref()
-                    .is_some_and(|it| &**it.crate_name() == crate_name)
+                    .is_some_and(|it| it.crate_name().as_str() == crate_name)
             })
             .expect("could not find crate");
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index b5bf2feb82a..8d5b3eeb28e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -937,7 +937,7 @@ pub struct Param {
 
 bitflags::bitflags! {
     #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
-    pub(crate) struct FnFlags: u8 {
+    pub(crate) struct FnFlags: u16 {
         const HAS_SELF_PARAM = 1 << 0;
         const HAS_BODY = 1 << 1;
         const HAS_DEFAULT_KW = 1 << 2;
@@ -946,6 +946,12 @@ bitflags::bitflags! {
         const HAS_UNSAFE_KW = 1 << 5;
         const IS_VARARGS = 1 << 6;
         const HAS_SAFE_KW = 1 << 7;
+        /// The `#[target_feature]` attribute is necessary to check safety (with RFC 2396),
+        /// but keeping it for all functions will consume a lot of memory when there are
+        /// only very few functions with it. So we only encode its existence here, and lookup
+        /// it if needed.
+        const HAS_TARGET_FEATURE = 1 << 8;
+        const DEPRECATED_SAFE_2024 = 1 << 9;
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
index 38733577d1c..59f51db9f74 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
@@ -502,4 +502,5 @@ language_item_table! {
 
     String,                  sym::String,              string,                     Target::Struct,         GenericRequirement::None;
     CStr,                    sym::CStr,                c_str,                      Target::Struct,         GenericRequirement::None;
+    Ordering,                sym::Ordering,            ordering,                   Target::Enum,           GenericRequirement::None;
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index c78818c642c..c8efd904320 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -42,7 +42,7 @@ pub mod lang_item;
 
 pub mod hir;
 pub use self::hir::type_ref;
-pub mod body;
+pub mod expr_store;
 pub mod resolver;
 
 pub mod nameres;
@@ -693,6 +693,7 @@ impl TypeOwnerId {
         Some(match self {
             TypeOwnerId::FunctionId(it) => GenericDefId::FunctionId(it),
             TypeOwnerId::ConstId(it) => GenericDefId::ConstId(it),
+            TypeOwnerId::StaticId(it) => GenericDefId::StaticId(it),
             TypeOwnerId::AdtId(it) => GenericDefId::AdtId(it),
             TypeOwnerId::TraitId(it) => GenericDefId::TraitId(it),
             TypeOwnerId::TraitAliasId(it) => GenericDefId::TraitAliasId(it),
@@ -701,7 +702,7 @@ impl TypeOwnerId {
             TypeOwnerId::EnumVariantId(it) => {
                 GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
             }
-            TypeOwnerId::InTypeConstId(_) | TypeOwnerId::StaticId(_) => return None,
+            TypeOwnerId::InTypeConstId(_) => return None,
         })
     }
 }
@@ -743,6 +744,7 @@ impl From<GenericDefId> for TypeOwnerId {
             GenericDefId::TypeAliasId(it) => it.into(),
             GenericDefId::ImplId(it) => it.into(),
             GenericDefId::ConstId(it) => it.into(),
+            GenericDefId::StaticId(it) => it.into(),
         }
     }
 }
@@ -851,7 +853,7 @@ impl GeneralConstId {
     pub fn generic_def(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
         match self {
             GeneralConstId::ConstId(it) => Some(it.into()),
-            GeneralConstId::StaticId(_) => None,
+            GeneralConstId::StaticId(it) => Some(it.into()),
             GeneralConstId::ConstBlockId(it) => it.lookup(db).parent.as_generic_def_id(db),
             GeneralConstId::InTypeConstId(it) => it.lookup(db).owner.as_generic_def_id(db),
         }
@@ -897,7 +899,7 @@ impl DefWithBodyId {
     pub fn as_generic_def_id(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
         match self {
             DefWithBodyId::FunctionId(f) => Some(f.into()),
-            DefWithBodyId::StaticId(_) => None,
+            DefWithBodyId::StaticId(s) => Some(s.into()),
             DefWithBodyId::ConstId(c) => Some(c.into()),
             DefWithBodyId::VariantId(c) => Some(c.lookup(db).parent.into()),
             // FIXME: stable rust doesn't allow generics in constants, but we should
@@ -922,23 +924,28 @@ impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
 pub enum GenericDefId {
-    FunctionId(FunctionId),
     AdtId(AdtId),
-    TraitId(TraitId),
-    TraitAliasId(TraitAliasId),
-    TypeAliasId(TypeAliasId),
-    ImplId(ImplId),
     // consts can have type parameters from their parents (i.e. associated consts of traits)
     ConstId(ConstId),
+    FunctionId(FunctionId),
+    ImplId(ImplId),
+    // can't actually have generics currently, but they might in the future
+    // More importantly, this completes the set of items that contain type references
+    // which is to be used by the signature expression store in the future.
+    StaticId(StaticId),
+    TraitAliasId(TraitAliasId),
+    TraitId(TraitId),
+    TypeAliasId(TypeAliasId),
 }
 impl_from!(
-    FunctionId,
     AdtId(StructId, EnumId, UnionId),
-    TraitId,
-    TraitAliasId,
-    TypeAliasId,
+    ConstId,
+    FunctionId,
     ImplId,
-    ConstId
+    StaticId,
+    TraitAliasId,
+    TraitId,
+    TypeAliasId
     for GenericDefId
 );
 
@@ -969,6 +976,7 @@ impl GenericDefId {
             GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
             GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
             GenericDefId::ConstId(it) => (it.lookup(db).id.file_id(), None),
+            GenericDefId::StaticId(it) => (it.lookup(db).id.file_id(), None),
         }
     }
 
@@ -1350,6 +1358,7 @@ impl HasModule for GenericDefId {
             GenericDefId::TypeAliasId(it) => it.module(db),
             GenericDefId::ImplId(it) => it.module(db),
             GenericDefId::ConstId(it) => it.module(db),
+            GenericDefId::StaticId(it) => it.module(db),
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
index 39d383f0159..3b6e3c5916e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
@@ -337,7 +337,7 @@ impl DefMap {
     pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: CrateId) -> Arc<DefMap> {
         let crate_graph = db.crate_graph();
         let krate = &crate_graph[crate_id];
-        let name = krate.display_name.as_deref().unwrap_or_default();
+        let name = krate.display_name.as_deref().map(Symbol::as_str).unwrap_or_default();
         let _p = tracing::info_span!("crate_def_map_query", ?name).entered();
 
         let module_data = ModuleData::new(
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index 8c556d8a8c3..7e13ae2f7a1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -10,13 +10,13 @@ use smallvec::{smallvec, SmallVec};
 use triomphe::Arc;
 
 use crate::{
-    body::{
-        scope::{ExprScopes, ScopeId},
-        HygieneId,
-    },
     builtin_type::BuiltinType,
     data::ExternCrateDeclData,
     db::DefDatabase,
+    expr_store::{
+        scope::{ExprScopes, ScopeId},
+        HygieneId,
+    },
     generics::{GenericParams, TypeOrConstParamData},
     hir::{BindingId, ExprId, LabelId},
     item_scope::{BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, BUILTIN_SCOPE},
@@ -1264,6 +1264,7 @@ impl HasResolver for GenericDefId {
             GenericDefId::TypeAliasId(inner) => inner.resolver(db),
             GenericDefId::ImplId(inner) => inner.resolver(db),
             GenericDefId::ConstId(inner) => inner.resolver(db),
+            GenericDefId::StaticId(inner) => inner.resolver(db),
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
index 848870c3a38..21e5fb5ef9e 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
@@ -262,6 +262,6 @@ impl AsName for ast::FieldKind {
 
 impl AsName for base_db::Dependency {
     fn as_name(&self) -> Name {
-        Name::new_root(&self.name)
+        Name::new_symbol_root((*self.name).clone())
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs
index 6ff7831fd81..c744fbce77b 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs
@@ -41,9 +41,9 @@ pub fn prettify_macro_expansion(
                 } else if let Some(dep) =
                     target_crate.dependencies.iter().find(|dep| dep.crate_id == macro_def_crate)
                 {
-                    make::tokens::ident(&dep.name)
+                    make::tokens::ident(dep.name.as_str())
                 } else if let Some(crate_name) = &crate_graph[macro_def_crate].display_name {
-                    make::tokens::ident(crate_name.crate_name())
+                    make::tokens::ident(crate_name.crate_name().as_str())
                 } else {
                     return dollar_crate.clone();
                 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
index 62feca5f8cb..e0e366f4501 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
@@ -194,7 +194,11 @@ pub(crate) fn deref_by_trait(
     }
 
     let trait_id = || {
-        if use_receiver_trait {
+        // FIXME: Remove the `false` once `Receiver` needs to be stabilized, doing so will
+        // effectively bump the MSRV of rust-analyzer to 1.84 due to 1.83 and below lacking the
+        // blanked impl on `Deref`.
+        #[expect(clippy::overly_complex_bool_expr)]
+        if use_receiver_trait && false {
             if let Some(receiver) =
                 db.lang_item(table.trait_env.krate, LangItem::Receiver).and_then(|l| l.as_trait())
             {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
index 142766c039b..7839589994b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
@@ -3,7 +3,7 @@
 use base_db::{ra_salsa::Cycle, CrateId};
 use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex};
 use hir_def::{
-    body::{Body, HygieneId},
+    expr_store::{Body, HygieneId},
     hir::{Expr, ExprId},
     path::Path,
     resolver::{Resolver, ValueNs},
@@ -124,6 +124,7 @@ pub(crate) fn path_to_const<'g>(
             ConstScalar::UnevaluatedConst(c.into(), Substitution::empty(Interner)),
             expected_ty,
         )),
+        // FIXME: With feature(adt_const_params), we also need to consider other things here, e.g. struct constructors.
         _ => None,
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
index 7f9f0c0de19..0b5f1319243 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
@@ -36,7 +36,7 @@ use crate::{
 };
 
 pub(crate) use hir_def::{
-    body::Body,
+    expr_store::Body,
     hir::{Expr, ExprId, MatchArm, Pat, PatId, Statement},
     LocalFieldId, VariantId,
 };
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
index c5d8c956615..b0f9fc53e29 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
@@ -11,7 +11,8 @@ pub(crate) mod pat_analysis;
 
 use chalk_ir::Mutability;
 use hir_def::{
-    body::Body, data::adt::VariantData, hir::PatId, AdtId, EnumVariantId, LocalFieldId, VariantId,
+    data::adt::VariantData, expr_store::Body, hir::PatId, AdtId, EnumVariantId, LocalFieldId,
+    VariantId,
 };
 use hir_expand::name::Name;
 use span::Edition;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
index 6bba83fac98..ac849b0762d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -5,28 +5,31 @@ use std::mem;
 
 use either::Either;
 use hir_def::{
-    body::Body,
+    expr_store::Body,
     hir::{Expr, ExprId, ExprOrPatId, Pat, PatId, Statement, UnaryOp},
     path::Path,
     resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
     type_ref::Rawness,
-    AdtId, DefWithBodyId, FieldId, VariantId,
+    AdtId, DefWithBodyId, FieldId, FunctionId, VariantId,
 };
+use span::Edition;
 
 use crate::{
-    db::HirDatabase, utils::is_fn_unsafe_to_call, InferenceResult, Interner, TyExt, TyKind,
+    db::HirDatabase, utils::is_fn_unsafe_to_call, InferenceResult, Interner, TargetFeatures, TyExt,
+    TyKind,
 };
 
-/// Returns `(unsafe_exprs, fn_is_unsafe)`.
-///
-/// If `fn_is_unsafe` is false, `unsafe_exprs` are hard errors. If true, they're `unsafe_op_in_unsafe_fn`.
-pub fn missing_unsafe(
-    db: &dyn HirDatabase,
-    def: DefWithBodyId,
-) -> (Vec<(ExprOrPatId, UnsafetyReason)>, bool) {
+#[derive(Debug, Default)]
+pub struct MissingUnsafeResult {
+    pub unsafe_exprs: Vec<(ExprOrPatId, UnsafetyReason)>,
+    /// If `fn_is_unsafe` is false, `unsafe_exprs` are hard errors. If true, they're `unsafe_op_in_unsafe_fn`.
+    pub fn_is_unsafe: bool,
+    pub deprecated_safe_calls: Vec<ExprId>,
+}
+
+pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafeResult {
     let _p = tracing::info_span!("missing_unsafe").entered();
 
-    let mut res = Vec::new();
     let is_unsafe = match def {
         DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe(),
         DefWithBodyId::StaticId(_)
@@ -35,11 +38,19 @@ pub fn missing_unsafe(
         | DefWithBodyId::InTypeConstId(_) => false,
     };
 
+    let mut res = MissingUnsafeResult { fn_is_unsafe: is_unsafe, ..MissingUnsafeResult::default() };
     let body = db.body(def);
     let infer = db.infer(def);
-    let mut callback = |node, inside_unsafe_block, reason| {
-        if inside_unsafe_block == InsideUnsafeBlock::No {
-            res.push((node, reason));
+    let mut callback = |diag| match diag {
+        UnsafeDiagnostic::UnsafeOperation { node, inside_unsafe_block, reason } => {
+            if inside_unsafe_block == InsideUnsafeBlock::No {
+                res.unsafe_exprs.push((node, reason));
+            }
+        }
+        UnsafeDiagnostic::DeprecatedSafe2024 { node, inside_unsafe_block } => {
+            if inside_unsafe_block == InsideUnsafeBlock::No {
+                res.deprecated_safe_calls.push(node)
+            }
         }
     };
     let mut visitor = UnsafeVisitor::new(db, &infer, &body, def, &mut callback);
@@ -54,7 +65,7 @@ pub fn missing_unsafe(
         }
     }
 
-    (res, is_unsafe)
+    res
 }
 
 #[derive(Debug, Clone, Copy)]
@@ -73,15 +84,31 @@ pub enum InsideUnsafeBlock {
     Yes,
 }
 
+#[derive(Debug)]
+enum UnsafeDiagnostic {
+    UnsafeOperation {
+        node: ExprOrPatId,
+        inside_unsafe_block: InsideUnsafeBlock,
+        reason: UnsafetyReason,
+    },
+    /// A lint.
+    DeprecatedSafe2024 { node: ExprId, inside_unsafe_block: InsideUnsafeBlock },
+}
+
 pub fn unsafe_expressions(
     db: &dyn HirDatabase,
     infer: &InferenceResult,
     def: DefWithBodyId,
     body: &Body,
     current: ExprId,
-    unsafe_expr_cb: &mut dyn FnMut(ExprOrPatId, InsideUnsafeBlock, UnsafetyReason),
+    callback: &mut dyn FnMut(InsideUnsafeBlock),
 ) {
-    let mut visitor = UnsafeVisitor::new(db, infer, body, def, unsafe_expr_cb);
+    let mut visitor_callback = |diag| {
+        if let UnsafeDiagnostic::UnsafeOperation { inside_unsafe_block, .. } = diag {
+            callback(inside_unsafe_block);
+        }
+    };
+    let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut visitor_callback);
     _ = visitor.resolver.update_to_inner_scope(db.upcast(), def, current);
     visitor.walk_expr(current);
 }
@@ -95,7 +122,10 @@ struct UnsafeVisitor<'a> {
     inside_unsafe_block: InsideUnsafeBlock,
     inside_assignment: bool,
     inside_union_destructure: bool,
-    unsafe_expr_cb: &'a mut dyn FnMut(ExprOrPatId, InsideUnsafeBlock, UnsafetyReason),
+    callback: &'a mut dyn FnMut(UnsafeDiagnostic),
+    def_target_features: TargetFeatures,
+    // FIXME: This needs to be the edition of the span of each call.
+    edition: Edition,
 }
 
 impl<'a> UnsafeVisitor<'a> {
@@ -104,9 +134,14 @@ impl<'a> UnsafeVisitor<'a> {
         infer: &'a InferenceResult,
         body: &'a Body,
         def: DefWithBodyId,
-        unsafe_expr_cb: &'a mut dyn FnMut(ExprOrPatId, InsideUnsafeBlock, UnsafetyReason),
+        unsafe_expr_cb: &'a mut dyn FnMut(UnsafeDiagnostic),
     ) -> Self {
         let resolver = def.resolver(db.upcast());
+        let def_target_features = match def {
+            DefWithBodyId::FunctionId(func) => TargetFeatures::from_attrs(&db.attrs(func.into())),
+            _ => TargetFeatures::default(),
+        };
+        let edition = db.crate_graph()[resolver.module().krate()].edition;
         Self {
             db,
             infer,
@@ -116,12 +151,34 @@ impl<'a> UnsafeVisitor<'a> {
             inside_unsafe_block: InsideUnsafeBlock::No,
             inside_assignment: false,
             inside_union_destructure: false,
-            unsafe_expr_cb,
+            callback: unsafe_expr_cb,
+            def_target_features,
+            edition,
         }
     }
 
-    fn call_cb(&mut self, node: ExprOrPatId, reason: UnsafetyReason) {
-        (self.unsafe_expr_cb)(node, self.inside_unsafe_block, reason);
+    fn on_unsafe_op(&mut self, node: ExprOrPatId, reason: UnsafetyReason) {
+        (self.callback)(UnsafeDiagnostic::UnsafeOperation {
+            node,
+            inside_unsafe_block: self.inside_unsafe_block,
+            reason,
+        });
+    }
+
+    fn check_call(&mut self, node: ExprId, func: FunctionId) {
+        let unsafety = is_fn_unsafe_to_call(self.db, func, &self.def_target_features, self.edition);
+        match unsafety {
+            crate::utils::Unsafety::Safe => {}
+            crate::utils::Unsafety::Unsafe => {
+                self.on_unsafe_op(node.into(), UnsafetyReason::UnsafeFnCall)
+            }
+            crate::utils::Unsafety::DeprecatedSafe2024 => {
+                (self.callback)(UnsafeDiagnostic::DeprecatedSafe2024 {
+                    node,
+                    inside_unsafe_block: self.inside_unsafe_block,
+                })
+            }
+        }
     }
 
     fn walk_pats_top(&mut self, pats: impl Iterator<Item = PatId>, parent_expr: ExprId) {
@@ -146,7 +203,9 @@ impl<'a> UnsafeVisitor<'a> {
                 | Pat::Ref { .. }
                 | Pat::Box { .. }
                 | Pat::Expr(..)
-                | Pat::ConstBlock(..) => self.call_cb(current.into(), UnsafetyReason::UnionField),
+                | Pat::ConstBlock(..) => {
+                    self.on_unsafe_op(current.into(), UnsafetyReason::UnionField)
+                }
                 // `Or` only wraps other patterns, and `Missing`/`Wild` do not constitute a read.
                 Pat::Missing | Pat::Wild | Pat::Or(_) => {}
             }
@@ -180,9 +239,13 @@ impl<'a> UnsafeVisitor<'a> {
         let inside_assignment = mem::replace(&mut self.inside_assignment, false);
         match expr {
             &Expr::Call { callee, .. } => {
-                if let Some(func) = self.infer[callee].as_fn_def(self.db) {
-                    if is_fn_unsafe_to_call(self.db, func) {
-                        self.call_cb(current.into(), UnsafetyReason::UnsafeFnCall);
+                let callee = &self.infer[callee];
+                if let Some(func) = callee.as_fn_def(self.db) {
+                    self.check_call(current, func);
+                }
+                if let TyKind::Function(fn_ptr) = callee.kind(Interner) {
+                    if fn_ptr.sig.safety == chalk_ir::Safety::Unsafe {
+                        self.on_unsafe_op(current.into(), UnsafetyReason::UnsafeFnCall);
                     }
                 }
             }
@@ -209,18 +272,13 @@ impl<'a> UnsafeVisitor<'a> {
                 }
             }
             Expr::MethodCall { .. } => {
-                if self
-                    .infer
-                    .method_resolution(current)
-                    .map(|(func, _)| is_fn_unsafe_to_call(self.db, func))
-                    .unwrap_or(false)
-                {
-                    self.call_cb(current.into(), UnsafetyReason::UnsafeFnCall);
+                if let Some((func, _)) = self.infer.method_resolution(current) {
+                    self.check_call(current, func);
                 }
             }
             Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
                 if let TyKind::Raw(..) = &self.infer[*expr].kind(Interner) {
-                    self.call_cb(current.into(), UnsafetyReason::RawPtrDeref);
+                    self.on_unsafe_op(current.into(), UnsafetyReason::RawPtrDeref);
                 }
             }
             Expr::Unsafe { .. } => {
@@ -235,7 +293,7 @@ impl<'a> UnsafeVisitor<'a> {
                 self.walk_pats_top(std::iter::once(target), current);
                 self.inside_assignment = old_inside_assignment;
             }
-            Expr::InlineAsm(_) => self.call_cb(current.into(), UnsafetyReason::InlineAsm),
+            Expr::InlineAsm(_) => self.on_unsafe_op(current.into(), UnsafetyReason::InlineAsm),
             // rustc allows union assignment to propagate through field accesses and casts.
             Expr::Cast { .. } => self.inside_assignment = inside_assignment,
             Expr::Field { .. } => {
@@ -244,7 +302,7 @@ impl<'a> UnsafeVisitor<'a> {
                     if let Some(Either::Left(FieldId { parent: VariantId::UnionId(_), .. })) =
                         self.infer.field_resolution(current)
                     {
-                        self.call_cb(current.into(), UnsafetyReason::UnionField);
+                        self.on_unsafe_op(current.into(), UnsafetyReason::UnionField);
                     }
                 }
             }
@@ -279,9 +337,9 @@ impl<'a> UnsafeVisitor<'a> {
         if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
             let static_data = self.db.static_data(id);
             if static_data.mutable {
-                self.call_cb(node, UnsafetyReason::MutableStatic);
+                self.on_unsafe_op(node, UnsafetyReason::MutableStatic);
             } else if static_data.is_extern && !static_data.has_safe_kw {
-                self.call_cb(node, UnsafetyReason::ExternStatic);
+                self.on_unsafe_op(node, UnsafetyReason::ExternStatic);
             }
         }
     }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
index abbf2a4f2ef..18cf6e5ce36 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
@@ -262,7 +262,8 @@ fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<Generic
         GenericDefId::FunctionId(it) => it.lookup(db).container,
         GenericDefId::TypeAliasId(it) => it.lookup(db).container,
         GenericDefId::ConstId(it) => it.lookup(db).container,
-        GenericDefId::AdtId(_)
+        GenericDefId::StaticId(_)
+        | GenericDefId::AdtId(_)
         | GenericDefId::TraitId(_)
         | GenericDefId::ImplId(_)
         | GenericDefId::TraitAliasId(_) => return None,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index 25bb3a76de2..617ebba8811 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -34,9 +34,9 @@ use chalk_ir::{
 };
 use either::Either;
 use hir_def::{
-    body::{Body, HygieneId},
     builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
     data::{ConstData, StaticData},
+    expr_store::{Body, HygieneId},
     hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
     lang_item::{LangItem, LangItemTarget},
     layout::Integer,
@@ -466,6 +466,9 @@ pub struct InferenceResult {
     pub type_of_for_iterator: FxHashMap<ExprId, Ty>,
     type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
     /// Whether there are any type-mismatching errors in the result.
+    // FIXME: This isn't as useful as initially thought due to us falling back placeholders to
+    // `TyKind::Error`.
+    // Which will then mark this field.
     pub(crate) has_errors: bool,
     /// Interned common types to return references to.
     // FIXME: Move this into `InferenceContext`
@@ -943,7 +946,7 @@ impl<'a> InferenceContext<'a> {
             let ty = self.insert_type_vars(ty);
             let ty = self.normalize_associated_types_in(ty);
 
-            self.infer_top_pat(*pat, &ty);
+            self.infer_top_pat(*pat, &ty, None);
             if ty
                 .data(Interner)
                 .flags
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
index 21d0be6ed5f..eb193686e96 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
@@ -374,6 +374,7 @@ enum PointerKind {
 
 fn pointer_kind(ty: &Ty, table: &mut InferenceTable<'_>) -> Result<Option<PointerKind>, ()> {
     let ty = table.resolve_ty_shallow(ty);
+    let ty = table.normalize_associated_types_in(ty);
 
     if table.is_sized(&ty) {
         return Ok(Some(PointerKind::Thin));
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs
index 032dc37899d..b85378531ad 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs
@@ -5,7 +5,7 @@
 use std::cell::RefCell;
 use std::ops::{Deref, DerefMut};
 
-use hir_def::body::HygieneId;
+use hir_def::expr_store::HygieneId;
 use hir_def::hir::ExprOrPatId;
 use hir_def::path::{Path, PathSegment, PathSegments};
 use hir_def::resolver::{ResolveValueResult, Resolver, TypeNs};
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index b951443897c..86e5afdb509 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -43,9 +43,9 @@ use crate::{
     primitive::{self, UintTy},
     static_lifetime, to_chalk_trait_id,
     traits::FnTrait,
-    Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, CallableSig, FnAbi, FnPointer,
-    FnSig, FnSubst, Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty,
-    TyBuilder, TyExt, TyKind,
+    Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, CallableSig, DeclContext,
+    DeclOrigin, FnAbi, FnPointer, FnSig, FnSubst, Interner, Rawness, Scalar, Substitution,
+    TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind,
 };
 
 use super::{
@@ -334,7 +334,11 @@ impl InferenceContext<'_> {
                     ExprIsRead::No
                 };
                 let input_ty = self.infer_expr(expr, &Expectation::none(), child_is_read);
-                self.infer_top_pat(pat, &input_ty);
+                self.infer_top_pat(
+                    pat,
+                    &input_ty,
+                    Some(DeclContext { origin: DeclOrigin::LetExpr }),
+                );
                 self.result.standard_types.bool_.clone()
             }
             Expr::Block { statements, tail, label, id } => {
@@ -461,7 +465,7 @@ impl InferenceContext<'_> {
 
                 // Now go through the argument patterns
                 for (arg_pat, arg_ty) in args.iter().zip(&sig_tys) {
-                    self.infer_top_pat(*arg_pat, arg_ty);
+                    self.infer_top_pat(*arg_pat, arg_ty, None);
                 }
 
                 // FIXME: lift these out into a struct
@@ -582,7 +586,7 @@ impl InferenceContext<'_> {
                     let mut all_arms_diverge = Diverges::Always;
                     for arm in arms.iter() {
                         let input_ty = self.resolve_ty_shallow(&input_ty);
-                        self.infer_top_pat(arm.pat, &input_ty);
+                        self.infer_top_pat(arm.pat, &input_ty, None);
                     }
 
                     let expected = expected.adjust_for_branches(&mut self.table);
@@ -927,7 +931,7 @@ impl InferenceContext<'_> {
                     let resolver_guard =
                         self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, tgt_expr);
                     self.inside_assignment = true;
-                    self.infer_top_pat(target, &rhs_ty);
+                    self.infer_top_pat(target, &rhs_ty, None);
                     self.inside_assignment = false;
                     self.resolver.reset_to_guard(resolver_guard);
                 }
@@ -1632,8 +1636,11 @@ impl InferenceContext<'_> {
                                 decl_ty
                             };
 
-                            this.infer_top_pat(*pat, &ty);
+                            let decl = DeclContext {
+                                origin: DeclOrigin::LocalDecl { has_else: else_branch.is_some() },
+                            };
 
+                            this.infer_top_pat(*pat, &ty, Some(decl));
                             if let Some(expr) = else_branch {
                                 let previous_diverges =
                                     mem::replace(&mut this.diverges, Diverges::Maybe);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
index 00398f019da..5ff22bea34d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -3,23 +3,24 @@
 use std::iter::repeat_with;
 
 use hir_def::{
-    body::Body,
+    expr_store::Body,
     hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, Literal, Pat, PatId},
     path::Path,
+    HasModule,
 };
 use hir_expand::name::Name;
 use stdx::TupleExt;
 
 use crate::{
-    consteval::{try_const_usize, usize_const},
+    consteval::{self, try_const_usize, usize_const},
     infer::{
         coerce::CoerceNever, expr::ExprIsRead, BindingMode, Expectation, InferenceContext,
         TypeMismatch,
     },
     lower::lower_to_chalk_mutability,
     primitive::UintTy,
-    static_lifetime, InferenceDiagnostic, Interner, Mutability, Scalar, Substitution, Ty,
-    TyBuilder, TyExt, TyKind,
+    static_lifetime, DeclContext, DeclOrigin, InferenceDiagnostic, Interner, Mutability, Scalar,
+    Substitution, Ty, TyBuilder, TyExt, TyKind,
 };
 
 impl InferenceContext<'_> {
@@ -34,6 +35,7 @@ impl InferenceContext<'_> {
         id: PatId,
         ellipsis: Option<u32>,
         subs: &[PatId],
+        decl: Option<DeclContext>,
     ) -> Ty {
         let (ty, def) = self.resolve_variant(id.into(), path, true);
         let var_data = def.map(|it| it.variant_data(self.db.upcast()));
@@ -92,13 +94,13 @@ impl InferenceContext<'_> {
                         }
                     };
 
-                    self.infer_pat(subpat, &expected_ty, default_bm);
+                    self.infer_pat(subpat, &expected_ty, default_bm, decl);
                 }
             }
             None => {
                 let err_ty = self.err_ty();
                 for &inner in subs {
-                    self.infer_pat(inner, &err_ty, default_bm);
+                    self.infer_pat(inner, &err_ty, default_bm, decl);
                 }
             }
         }
@@ -114,6 +116,7 @@ impl InferenceContext<'_> {
         default_bm: BindingMode,
         id: PatId,
         subs: impl ExactSizeIterator<Item = (Name, PatId)>,
+        decl: Option<DeclContext>,
     ) -> Ty {
         let (ty, def) = self.resolve_variant(id.into(), path, false);
         if let Some(variant) = def {
@@ -162,13 +165,13 @@ impl InferenceContext<'_> {
                         }
                     };
 
-                    self.infer_pat(inner, &expected_ty, default_bm);
+                    self.infer_pat(inner, &expected_ty, default_bm, decl);
                 }
             }
             None => {
                 let err_ty = self.err_ty();
                 for (_, inner) in subs {
-                    self.infer_pat(inner, &err_ty, default_bm);
+                    self.infer_pat(inner, &err_ty, default_bm, decl);
                 }
             }
         }
@@ -185,6 +188,7 @@ impl InferenceContext<'_> {
         default_bm: BindingMode,
         ellipsis: Option<u32>,
         subs: &[PatId],
+        decl: Option<DeclContext>,
     ) -> Ty {
         let expected = self.resolve_ty_shallow(expected);
         let expectations = match expected.as_tuple() {
@@ -209,12 +213,12 @@ impl InferenceContext<'_> {
 
         // Process pre
         for (ty, pat) in inner_tys.iter_mut().zip(pre) {
-            *ty = self.infer_pat(*pat, ty, default_bm);
+            *ty = self.infer_pat(*pat, ty, default_bm, decl);
         }
 
         // Process post
         for (ty, pat) in inner_tys.iter_mut().skip(pre.len() + n_uncovered_patterns).zip(post) {
-            *ty = self.infer_pat(*pat, ty, default_bm);
+            *ty = self.infer_pat(*pat, ty, default_bm, decl);
         }
 
         TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
@@ -223,11 +227,17 @@ impl InferenceContext<'_> {
 
     /// The resolver needs to be updated to the surrounding expression when inside assignment
     /// (because there, `Pat::Path` can refer to a variable).
-    pub(super) fn infer_top_pat(&mut self, pat: PatId, expected: &Ty) {
-        self.infer_pat(pat, expected, BindingMode::default());
+    pub(super) fn infer_top_pat(&mut self, pat: PatId, expected: &Ty, decl: Option<DeclContext>) {
+        self.infer_pat(pat, expected, BindingMode::default(), decl);
     }
 
-    fn infer_pat(&mut self, pat: PatId, expected: &Ty, mut default_bm: BindingMode) -> Ty {
+    fn infer_pat(
+        &mut self,
+        pat: PatId,
+        expected: &Ty,
+        mut default_bm: BindingMode,
+        decl: Option<DeclContext>,
+    ) -> Ty {
         let mut expected = self.resolve_ty_shallow(expected);
 
         if matches!(&self.body[pat], Pat::Ref { .. }) || self.inside_assignment {
@@ -261,11 +271,11 @@ impl InferenceContext<'_> {
 
         let ty = match &self.body[pat] {
             Pat::Tuple { args, ellipsis } => {
-                self.infer_tuple_pat_like(&expected, default_bm, *ellipsis, args)
+                self.infer_tuple_pat_like(&expected, default_bm, *ellipsis, args, decl)
             }
             Pat::Or(pats) => {
                 for pat in pats.iter() {
-                    self.infer_pat(*pat, &expected, default_bm);
+                    self.infer_pat(*pat, &expected, default_bm, decl);
                 }
                 expected.clone()
             }
@@ -274,6 +284,7 @@ impl InferenceContext<'_> {
                 lower_to_chalk_mutability(mutability),
                 &expected,
                 default_bm,
+                decl,
             ),
             Pat::TupleStruct { path: p, args: subpats, ellipsis } => self
                 .infer_tuple_struct_pat_like(
@@ -283,10 +294,11 @@ impl InferenceContext<'_> {
                     pat,
                     *ellipsis,
                     subpats,
+                    decl,
                 ),
             Pat::Record { path: p, args: fields, ellipsis: _ } => {
                 let subs = fields.iter().map(|f| (f.name.clone(), f.pat));
-                self.infer_record_pat_like(p.as_deref(), &expected, default_bm, pat, subs)
+                self.infer_record_pat_like(p.as_deref(), &expected, default_bm, pat, subs, decl)
             }
             Pat::Path(path) => {
                 let ty = self.infer_path(path, pat.into()).unwrap_or_else(|| self.err_ty());
@@ -319,10 +331,10 @@ impl InferenceContext<'_> {
                 }
             }
             Pat::Bind { id, subpat } => {
-                return self.infer_bind_pat(pat, *id, default_bm, *subpat, &expected);
+                return self.infer_bind_pat(pat, *id, default_bm, *subpat, &expected, decl);
             }
             Pat::Slice { prefix, slice, suffix } => {
-                self.infer_slice_pat(&expected, prefix, slice, suffix, default_bm)
+                self.infer_slice_pat(&expected, prefix, slice, suffix, default_bm, decl)
             }
             Pat::Wild => expected.clone(),
             Pat::Range { .. } => {
@@ -345,7 +357,7 @@ impl InferenceContext<'_> {
                         _ => (self.result.standard_types.unknown.clone(), None),
                     };
 
-                    let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
+                    let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm, decl);
                     let mut b = TyBuilder::adt(self.db, box_adt).push(inner_ty);
 
                     if let Some(alloc_ty) = alloc_ty {
@@ -420,6 +432,7 @@ impl InferenceContext<'_> {
         mutability: Mutability,
         expected: &Ty,
         default_bm: BindingMode,
+        decl: Option<DeclContext>,
     ) -> Ty {
         let (expectation_type, expectation_lt) = match expected.as_reference() {
             Some((inner_ty, lifetime, _exp_mut)) => (inner_ty.clone(), lifetime.clone()),
@@ -433,7 +446,7 @@ impl InferenceContext<'_> {
                 (inner_ty, inner_lt)
             }
         };
-        let subty = self.infer_pat(inner_pat, &expectation_type, default_bm);
+        let subty = self.infer_pat(inner_pat, &expectation_type, default_bm, decl);
         TyKind::Ref(mutability, expectation_lt, subty).intern(Interner)
     }
 
@@ -444,6 +457,7 @@ impl InferenceContext<'_> {
         default_bm: BindingMode,
         subpat: Option<PatId>,
         expected: &Ty,
+        decl: Option<DeclContext>,
     ) -> Ty {
         let Binding { mode, .. } = self.body.bindings[binding];
         let mode = if mode == BindingAnnotation::Unannotated {
@@ -454,7 +468,7 @@ impl InferenceContext<'_> {
         self.result.binding_modes.insert(pat, mode);
 
         let inner_ty = match subpat {
-            Some(subpat) => self.infer_pat(subpat, expected, default_bm),
+            Some(subpat) => self.infer_pat(subpat, expected, default_bm, decl),
             None => expected.clone(),
         };
         let inner_ty = self.insert_type_vars_shallow(inner_ty);
@@ -478,14 +492,28 @@ impl InferenceContext<'_> {
         slice: &Option<PatId>,
         suffix: &[PatId],
         default_bm: BindingMode,
+        decl: Option<DeclContext>,
     ) -> Ty {
+        let expected = self.resolve_ty_shallow(expected);
+
+        // If `expected` is an infer ty, we try to equate it to an array if the given pattern
+        // allows it. See issue #16609
+        if self.pat_is_irrefutable(decl) && expected.is_ty_var() {
+            if let Some(resolved_array_ty) =
+                self.try_resolve_slice_ty_to_array_ty(prefix, suffix, slice)
+            {
+                self.unify(&expected, &resolved_array_ty);
+            }
+        }
+
+        let expected = self.resolve_ty_shallow(&expected);
         let elem_ty = match expected.kind(Interner) {
             TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
             _ => self.err_ty(),
         };
 
         for &pat_id in prefix.iter().chain(suffix.iter()) {
-            self.infer_pat(pat_id, &elem_ty, default_bm);
+            self.infer_pat(pat_id, &elem_ty, default_bm, decl);
         }
 
         if let &Some(slice_pat_id) = slice {
@@ -499,7 +527,7 @@ impl InferenceContext<'_> {
                 _ => TyKind::Slice(elem_ty.clone()),
             }
             .intern(Interner);
-            self.infer_pat(slice_pat_id, &rest_pat_ty, default_bm);
+            self.infer_pat(slice_pat_id, &rest_pat_ty, default_bm, decl);
         }
 
         match expected.kind(Interner) {
@@ -528,7 +556,7 @@ impl InferenceContext<'_> {
         self.infer_expr(expr, &Expectation::has_type(expected.clone()), ExprIsRead::Yes)
     }
 
-    fn is_non_ref_pat(&mut self, body: &hir_def::body::Body, pat: PatId) -> bool {
+    fn is_non_ref_pat(&mut self, body: &hir_def::expr_store::Body, pat: PatId) -> bool {
         match &body[pat] {
             Pat::Tuple { .. }
             | Pat::TupleStruct { .. }
@@ -553,6 +581,59 @@ impl InferenceContext<'_> {
             | Pat::Expr(_) => false,
         }
     }
+
+    fn try_resolve_slice_ty_to_array_ty(
+        &mut self,
+        before: &[PatId],
+        suffix: &[PatId],
+        slice: &Option<PatId>,
+    ) -> Option<Ty> {
+        if !slice.is_none() {
+            return None;
+        }
+
+        let len = before.len() + suffix.len();
+        let size =
+            consteval::usize_const(self.db, Some(len as u128), self.owner.krate(self.db.upcast()));
+
+        let elem_ty = self.table.new_type_var();
+        let array_ty = TyKind::Array(elem_ty.clone(), size).intern(Interner);
+        Some(array_ty)
+    }
+
+    /// Used to determine whether we can infer the expected type in the slice pattern to be of type array.
+    /// This is only possible if we're in an irrefutable pattern. If we were to allow this in refutable
+    /// patterns we wouldn't e.g. report ambiguity in the following situation:
+    ///
+    /// ```ignore(rust)
+    ///    struct Zeroes;
+    ///    const ARR: [usize; 2] = [0; 2];
+    ///    const ARR2: [usize; 2] = [2; 2];
+    ///
+    ///    impl Into<&'static [usize; 2]> for Zeroes {
+    ///        fn into(self) -> &'static [usize; 2] {
+    ///            &ARR
+    ///        }
+    ///    }
+    ///
+    ///    impl Into<&'static [usize]> for Zeroes {
+    ///        fn into(self) -> &'static [usize] {
+    ///            &ARR2
+    ///        }
+    ///    }
+    ///
+    ///    fn main() {
+    ///        let &[a, b]: &[usize] = Zeroes.into() else {
+    ///           ..
+    ///        };
+    ///    }
+    /// ```
+    ///
+    /// If we're in an irrefutable pattern we prefer the array impl candidate given that
+    /// the slice impl candidate would be rejected anyway (if no ambiguity existed).
+    fn pat_is_irrefutable(&self, decl_ctxt: Option<DeclContext>) -> bool {
+        matches!(decl_ctxt, Some(DeclContext { origin: DeclOrigin::LocalDecl { has_else: false } }))
+    }
 }
 
 pub(super) fn contains_explicit_ref_binding(body: &Body, pat_id: PatId) -> bool {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
index 73bcefaf2a9..36ec60a7a2f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
@@ -86,10 +86,9 @@ impl InferenceContext<'_> {
             }
         };
 
-        let generic_def_id = value_def.to_generic_def_id(self.db);
-        let Some(generic_def) = generic_def_id else {
-            // `value_def` is the kind of item that can never be generic (i.e. statics, at least
-            // currently). We can just skip the binders to get its type.
+        let generic_def = value_def.to_generic_def_id(self.db);
+        if let GenericDefId::StaticId(_) = generic_def {
+            // `Static` is the kind of item that can never be generic currently. We can just skip the binders to get its type.
             let (ty, binders) = self.db.value_ty(value_def)?.into_value_and_skipped_binders();
             stdx::always!(binders.is_empty(Interner), "non-empty binders for non-generic def",);
             return Some(ValuePathResolution::NonGeneric(ty));
@@ -122,7 +121,7 @@ impl InferenceContext<'_> {
         }
 
         let parent_substs = self_subst.or_else(|| {
-            let generics = generics(self.db.upcast(), generic_def_id?);
+            let generics = generics(self.db.upcast(), generic_def);
             let parent_params_len = generics.parent_generics()?.len();
             let parent_args = &substs[substs.len() - parent_params_len..];
             Some(Substitution::from_iter(Interner, parent_args))
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 3c18ea92816..55d81875a2b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -100,7 +100,9 @@ pub use mapping::{
 };
 pub use method_resolution::check_orphan_rules;
 pub use traits::TraitEnvironment;
-pub use utils::{all_super_traits, direct_super_traits, is_fn_unsafe_to_call};
+pub use utils::{
+    all_super_traits, direct_super_traits, is_fn_unsafe_to_call, TargetFeatures, Unsafety,
+};
 pub use variance::Variance;
 
 pub use chalk_ir::{
@@ -1047,3 +1049,20 @@ pub fn known_const_to_ast(
     }
     Some(make::expr_const_value(konst.display(db, edition).to_string().as_str()))
 }
+
+#[derive(Debug, Copy, Clone)]
+pub(crate) enum DeclOrigin {
+    LetExpr,
+    /// from `let x = ..`
+    LocalDecl {
+        has_else: bool,
+    },
+}
+
+/// Provides context for checking patterns in declarations. More specifically this
+/// allows us to infer array types if the pattern is irrefutable and allows us to infer
+/// the size of the array. See issue rust-lang/rust#76342.
+#[derive(Debug, Copy, Clone)]
+pub(crate) struct DeclContext {
+    pub(crate) origin: DeclOrigin,
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 432b8f4d94e..db13e1fd354 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -23,10 +23,10 @@ use chalk_ir::{
 
 use either::Either;
 use hir_def::{
-    body::HygieneId,
     builtin_type::BuiltinType,
     data::{adt::StructKind, TraitFlags},
     expander::Expander,
+    expr_store::HygieneId,
     generics::{
         GenericParamDataRef, TypeOrConstParamData, TypeParamProvenance, WherePredicate,
         WherePredicateTypeTarget,
@@ -2471,14 +2471,14 @@ pub enum ValueTyDefId {
 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
 
 impl ValueTyDefId {
-    pub(crate) fn to_generic_def_id(self, db: &dyn HirDatabase) -> Option<GenericDefId> {
+    pub(crate) fn to_generic_def_id(self, db: &dyn HirDatabase) -> GenericDefId {
         match self {
-            Self::FunctionId(id) => Some(id.into()),
-            Self::StructId(id) => Some(id.into()),
-            Self::UnionId(id) => Some(id.into()),
-            Self::EnumVariantId(var) => Some(var.lookup(db.upcast()).parent.into()),
-            Self::ConstId(id) => Some(id.into()),
-            Self::StaticId(_) => None,
+            Self::FunctionId(id) => id.into(),
+            Self::StructId(id) => id.into(),
+            Self::UnionId(id) => id.into(),
+            Self::EnumVariantId(var) => var.lookup(db.upcast()).parent.into(),
+            Self::ConstId(id) => id.into(),
+            Self::StaticId(id) => id.into(),
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
index 1cea67ee964..db94351dcc9 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
@@ -4,6 +4,7 @@
 //! and the corresponding code mostly in rustc_hir_analysis/check/method/probe.rs.
 use std::ops::ControlFlow;
 
+use arrayvec::ArrayVec;
 use base_db::CrateId;
 use chalk_ir::{cast::Cast, UniverseIndex, WithKind};
 use hir_def::{
@@ -732,15 +733,27 @@ fn lookup_impl_assoc_item_for_trait_ref(
     let self_ty = trait_ref.self_type_parameter(Interner);
     let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?;
     let impls = db.trait_impls_in_deps(env.krate);
-    let self_impls = match self_ty.kind(Interner) {
-        TyKind::Adt(id, _) => {
-            id.0.module(db.upcast()).containing_block().and_then(|it| db.trait_impls_in_block(it))
+
+    let trait_module = hir_trait_id.module(db.upcast());
+    let type_module = match self_ty_fp {
+        TyFingerprint::Adt(adt_id) => Some(adt_id.module(db.upcast())),
+        TyFingerprint::ForeignType(type_id) => {
+            Some(from_foreign_def_id(type_id).module(db.upcast()))
         }
+        TyFingerprint::Dyn(trait_id) => Some(trait_id.module(db.upcast())),
         _ => None,
     };
+
+    let def_blocks: ArrayVec<_, 2> =
+        [trait_module.containing_block(), type_module.and_then(|it| it.containing_block())]
+            .into_iter()
+            .flatten()
+            .filter_map(|block_id| db.trait_impls_in_block(block_id))
+            .collect();
+
     let impls = impls
         .iter()
-        .chain(self_impls.as_ref())
+        .chain(&def_blocks)
         .flat_map(|impls| impls.for_trait_and_self_ty(hir_trait_id, self_ty_fp));
 
     let table = InferenceTable::new(db, env);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
index 59c583afb2a..84d8950b1aa 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
@@ -16,7 +16,7 @@ use base_db::CrateId;
 use chalk_ir::Mutability;
 use either::Either;
 use hir_def::{
-    body::Body,
+    expr_store::Body,
     hir::{BindingAnnotation, BindingId, Expr, ExprId, Ordering, PatId},
     DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId,
 };
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index dcae6877ba8..6b20522cf34 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -6,9 +6,9 @@ use base_db::CrateId;
 use chalk_ir::{cast::Cast, Mutability};
 use either::Either;
 use hir_def::{
-    body::HygieneId,
     builtin_type::BuiltinType,
     data::adt::{StructFlags, VariantData},
+    expr_store::HygieneId,
     lang_item::LangItem,
     layout::{TagEncoding, Variants},
     resolver::{HasResolver, TypeNs, ValueNs},
@@ -1644,14 +1644,15 @@ impl Evaluator<'_> {
             Variants::Multiple { tag, tag_encoding, variants, .. } => {
                 let size = tag.size(&*self.target_data_layout).bytes_usize();
                 let offset = layout.fields.offset(0).bytes_usize(); // The only field on enum variants is the tag field
+                let is_signed = tag.is_signed();
                 match tag_encoding {
                     TagEncoding::Direct => {
                         let tag = &bytes[offset..offset + size];
-                        Ok(i128::from_le_bytes(pad16(tag, false)))
+                        Ok(i128::from_le_bytes(pad16(tag, is_signed)))
                     }
                     TagEncoding::Niche { untagged_variant, niche_start, .. } => {
                         let tag = &bytes[offset..offset + size];
-                        let candidate_tag = i128::from_le_bytes(pad16(tag, false))
+                        let candidate_tag = i128::from_le_bytes(pad16(tag, is_signed))
                             .wrapping_sub(*niche_start as i128)
                             as usize;
                         let idx = variants
@@ -2943,10 +2944,10 @@ pub fn render_const_using_debug_impl(
     // a3 = ::core::fmt::Arguments::new_v1(a1, a2)
     // FIXME: similarly, we should call function here, not directly working with memory.
     let a3 = evaluator.heap_allocate(evaluator.ptr_size() * 6, evaluator.ptr_size())?;
-    evaluator.write_memory(a3.offset(2 * evaluator.ptr_size()), &a1.to_bytes())?;
+    evaluator.write_memory(a3, &a1.to_bytes())?;
+    evaluator.write_memory(a3.offset(evaluator.ptr_size()), &[1])?;
+    evaluator.write_memory(a3.offset(2 * evaluator.ptr_size()), &a2.to_bytes())?;
     evaluator.write_memory(a3.offset(3 * evaluator.ptr_size()), &[1])?;
-    evaluator.write_memory(a3.offset(4 * evaluator.ptr_size()), &a2.to_bytes())?;
-    evaluator.write_memory(a3.offset(5 * evaluator.ptr_size()), &[1])?;
     let Some(ValueNs::FunctionId(format_fn)) = resolver.resolve_path_in_value_ns_fully(
         db.upcast(),
         &hir_def::path::Path::from_known_path_with_no_generic(path![std::fmt::format]),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
index 0a78f4a5b24..38b189a517f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
@@ -1,11 +1,12 @@
 //! Interpret intrinsics, lang items and `extern "C"` wellknown functions which their implementation
 //! is not available.
 //!
-use std::cmp;
+use std::cmp::{self, Ordering};
 
 use chalk_ir::TyKind;
 use hir_def::{
     builtin_type::{BuiltinInt, BuiltinUint},
+    lang_item::LangItemTarget,
     resolver::HasResolver,
 };
 use hir_expand::name::Name;
@@ -1317,6 +1318,82 @@ impl Evaluator<'_> {
                 self.write_memory_using_ref(dst, size)?.fill(val);
                 Ok(())
             }
+            "ptr_metadata" => {
+                let [ptr] = args else {
+                    return Err(MirEvalError::InternalError(
+                        "ptr_metadata args are not provided".into(),
+                    ));
+                };
+                let arg = ptr.interval.get(self)?.to_owned();
+                let metadata = &arg[self.ptr_size()..];
+                destination.write_from_bytes(self, metadata)?;
+                Ok(())
+            }
+            "three_way_compare" => {
+                let [lhs, rhs] = args else {
+                    return Err(MirEvalError::InternalError(
+                        "three_way_compare args are not provided".into(),
+                    ));
+                };
+                let Some(ty) =
+                    generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
+                else {
+                    return Err(MirEvalError::InternalError(
+                        "three_way_compare generic arg is not provided".into(),
+                    ));
+                };
+                let signed = match ty.as_builtin().unwrap() {
+                    BuiltinType::Int(_) => true,
+                    BuiltinType::Uint(_) => false,
+                    _ => {
+                        return Err(MirEvalError::InternalError(
+                            "three_way_compare expects an integral type".into(),
+                        ))
+                    }
+                };
+                let rhs = rhs.get(self)?;
+                let lhs = lhs.get(self)?;
+                let mut result = Ordering::Equal;
+                for (l, r) in lhs.iter().zip(rhs).rev() {
+                    let it = l.cmp(r);
+                    if it != Ordering::Equal {
+                        result = it;
+                        break;
+                    }
+                }
+                if signed {
+                    if let Some((&l, &r)) = lhs.iter().zip(rhs).next_back() {
+                        if l != r {
+                            result = (l as i8).cmp(&(r as i8));
+                        }
+                    }
+                }
+                if let Some(LangItemTarget::EnumId(e)) =
+                    self.db.lang_item(self.crate_id, LangItem::Ordering)
+                {
+                    let ty = self.db.ty(e.into());
+                    let r = self
+                        .compute_discriminant(ty.skip_binders().clone(), &[result as i8 as u8])?;
+                    destination.write_from_bytes(self, &r.to_le_bytes()[0..destination.size])?;
+                    Ok(())
+                } else {
+                    Err(MirEvalError::InternalError("Ordering enum not found".into()))
+                }
+            }
+            "aggregate_raw_ptr" => {
+                let [data, meta] = args else {
+                    return Err(MirEvalError::InternalError(
+                        "aggregate_raw_ptr args are not provided".into(),
+                    ));
+                };
+                destination.write_from_interval(self, data.interval)?;
+                Interval {
+                    addr: destination.addr.offset(data.interval.size),
+                    size: destination.size - data.interval.size,
+                }
+                .write_from_interval(self, meta.interval)?;
+                Ok(())
+            }
             _ if needs_override => not_supported!("intrinsic {name} is not implemented"),
             _ => return Ok(false),
         }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 1d1044df6e9..549450e9beb 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -5,8 +5,8 @@ use std::{fmt::Write, iter, mem};
 use base_db::ra_salsa::Cycle;
 use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind};
 use hir_def::{
-    body::{Body, HygieneId},
     data::adt::{StructKind, VariantData},
+    expr_store::{Body, HygieneId},
     hir::{
         ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal,
         LiteralOrConst, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField,
@@ -2156,7 +2156,7 @@ pub fn lower_to_mir(
     // need to take this input explicitly.
     root_expr: ExprId,
 ) -> Result<MirBody> {
-    if infer.has_errors {
+    if infer.type_mismatches().next().is_some() {
         return Err(MirLowerError::HasErrors);
     }
     let mut ctx = MirLowerCtx::new(db, owner, body, infer);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
index 06765a104cb..2a26101ac43 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
@@ -6,7 +6,7 @@ use std::{
 };
 
 use either::Either;
-use hir_def::{body::Body, hir::BindingId};
+use hir_def::{expr_store::Body, hir::BindingId};
 use hir_expand::{name::Name, Lookup};
 use la_arena::ArenaMap;
 use span::Edition;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs
index 00da9b25176..69ec35f406d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs
@@ -18,8 +18,8 @@ use std::sync::LazyLock;
 use base_db::SourceDatabaseFileInputExt as _;
 use expect_test::Expect;
 use hir_def::{
-    body::{Body, BodySourceMap},
     db::DefDatabase,
+    expr_store::{Body, BodySourceMap},
     hir::{ExprId, Pat, PatId},
     item_scope::ItemScope,
     nameres::DefMap,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
index 8866de22dfb..e5f791ea6ff 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
@@ -2163,9 +2163,9 @@ impl Receiver for Bar {
 fn main() {
     let bar = Bar;
     let _v1 = bar.foo1();
-      //^^^ type: i32
+      //^^^ type: {unknown}
     let _v2 = bar.foo2();
-      //^^^ type: bool
+      //^^^ type: {unknown}
 }
 "#,
     );
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
index 15636604570..50a1ecd006d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
@@ -3814,3 +3814,50 @@ async fn foo(a: (), b: i32) -> u32 {
         "#,
     );
 }
+
+#[test]
+fn irrefutable_slices() {
+    check_infer(
+        r#"
+//- minicore: from
+struct A;
+
+impl From<A> for [u8; 2] {
+    fn from(a: A) -> Self {
+        [0; 2]
+    }
+}
+impl From<A> for [u8; 3] {
+    fn from(a: A) -> Self {
+        [0; 3]
+    }
+}
+
+
+fn main() {
+    let a = A;
+    let [b, c] = a.into();
+}
+"#,
+        expect![[r#"
+            50..51 'a': A
+            64..86 '{     ...     }': [u8; 2]
+            74..80 '[0; 2]': [u8; 2]
+            75..76 '0': u8
+            78..79 '2': usize
+            128..129 'a': A
+            142..164 '{     ...     }': [u8; 3]
+            152..158 '[0; 3]': [u8; 3]
+            153..154 '0': u8
+            156..157 '3': usize
+            179..224 '{     ...o(); }': ()
+            189..190 'a': A
+            193..194 'A': A
+            204..210 '[b, c]': [u8; 2]
+            205..206 'b': u8
+            208..209 'c': u8
+            213..214 'a': A
+            213..221 'a.into()': [u8; 2]
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
index bf7892f69bd..c131e97bc4c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -9,19 +9,22 @@ use chalk_ir::{
     DebruijnIndex,
 };
 use hir_def::{
+    attr::Attrs,
     db::DefDatabase,
     generics::{WherePredicate, WherePredicateTypeTarget},
     lang_item::LangItem,
     resolver::{HasResolver, TypeNs},
+    tt,
     type_ref::{TraitBoundModifier, TypeRef},
     EnumId, EnumVariantId, FunctionId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId,
     TypeOrConstParamId,
 };
 use hir_expand::name::Name;
-use intern::sym;
+use intern::{sym, Symbol};
 use rustc_abi::TargetDataLayout;
 use rustc_hash::FxHashSet;
 use smallvec::{smallvec, SmallVec};
+use span::Edition;
 use stdx::never;
 
 use crate::{
@@ -264,10 +267,65 @@ impl<'a> ClosureSubst<'a> {
     }
 }
 
-pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
+#[derive(Debug, Default)]
+pub struct TargetFeatures {
+    enabled: FxHashSet<Symbol>,
+}
+
+impl TargetFeatures {
+    pub fn from_attrs(attrs: &Attrs) -> Self {
+        let enabled = attrs
+            .by_key(&sym::target_feature)
+            .tt_values()
+            .filter_map(|tt| {
+                match tt.token_trees().flat_tokens() {
+                    [
+                        tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)),
+                        tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })),
+                        tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, symbol: features, .. })),
+                    ] if enable_ident.sym == sym::enable => Some(features),
+                    _ => None,
+                }
+            })
+            .flat_map(|features| features.as_str().split(',').map(Symbol::intern))
+            .collect();
+        Self { enabled }
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Unsafety {
+    Safe,
+    Unsafe,
+    /// A lint.
+    DeprecatedSafe2024,
+}
+
+pub fn is_fn_unsafe_to_call(
+    db: &dyn HirDatabase,
+    func: FunctionId,
+    caller_target_features: &TargetFeatures,
+    call_edition: Edition,
+) -> Unsafety {
     let data = db.function_data(func);
     if data.is_unsafe() {
-        return true;
+        return Unsafety::Unsafe;
+    }
+
+    if data.has_target_feature() {
+        // RFC 2396 <https://rust-lang.github.io/rfcs/2396-target-feature-1.1.html>.
+        let callee_target_features = TargetFeatures::from_attrs(&db.attrs(func.into()));
+        if !caller_target_features.enabled.is_superset(&callee_target_features.enabled) {
+            return Unsafety::Unsafe;
+        }
+    }
+
+    if data.is_deprecated_safe_2024() {
+        if call_edition.at_least_2024() {
+            return Unsafety::Unsafe;
+        } else {
+            return Unsafety::DeprecatedSafe2024;
+        }
     }
 
     let loc = func.lookup(db.upcast());
@@ -279,14 +337,22 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
             if is_intrinsic_block {
                 // legacy intrinsics
                 // extern "rust-intrinsic" intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
-                !db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists()
+                if db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists() {
+                    Unsafety::Safe
+                } else {
+                    Unsafety::Unsafe
+                }
             } else {
                 // Function in an `extern` block are always unsafe to call, except when
                 // it is marked as `safe`.
-                !data.is_safe()
+                if data.is_safe() {
+                    Unsafety::Safe
+                } else {
+                    Unsafety::Unsafe
+                }
             }
         }
-        _ => false,
+        _ => Unsafety::Safe,
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
index afd163fbd96..3a22158ce6f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
@@ -1028,6 +1028,7 @@ struct FixedPoint<T, U, V>(&'static FixedPoint<(), T, U>, V);
                         }
                         GenericDefId::ImplId(_) => return None,
                         GenericDefId::ConstId(_) => return None,
+                        GenericDefId::StaticId(_) => return None,
                     },
                 ))
             })
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
index fc77d1889c8..64e982c42d7 100644
--- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -271,11 +271,17 @@ pub struct PrivateField {
     pub field: Field,
 }
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum UnsafeLint {
+    HardError,
+    UnsafeOpInUnsafeFn,
+    DeprecatedSafe2024,
+}
+
 #[derive(Debug)]
 pub struct MissingUnsafe {
     pub node: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
-    /// If true, the diagnostics is an `unsafe_op_in_unsafe_fn` lint instead of a hard error.
-    pub only_lint: bool,
+    pub lint: UnsafeLint,
     pub reason: UnsafetyReason,
 }
 
@@ -411,7 +417,7 @@ impl AnyDiagnostic {
     pub(crate) fn body_validation_diagnostic(
         db: &dyn HirDatabase,
         diagnostic: BodyValidationDiagnostic,
-        source_map: &hir_def::body::BodySourceMap,
+        source_map: &hir_def::expr_store::BodySourceMap,
     ) -> Option<AnyDiagnostic> {
         match diagnostic {
             BodyValidationDiagnostic::RecordMissingFields { record, variant, missed_fields } => {
@@ -547,7 +553,7 @@ impl AnyDiagnostic {
         def: DefWithBodyId,
         d: &InferenceDiagnostic,
         outer_types_source_map: &TypesSourceMap,
-        source_map: &hir_def::body::BodySourceMap,
+        source_map: &hir_def::expr_store::BodySourceMap,
     ) -> Option<AnyDiagnostic> {
         let expr_syntax = |expr| {
             source_map.expr_syntax(expr).inspect_err(|_| stdx::never!("synthetic syntax")).ok()
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index b29c91694d3..6f4168ab086 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -80,7 +80,9 @@ impl HirDisplay for Function {
         if data.is_async() {
             f.write_str("async ")?;
         }
-        if self.is_unsafe_to_call(db) {
+        // FIXME: This will show `unsafe` for functions that are `#[target_feature]` but not unsafe
+        // (they are conditionally unsafe to call). We probably should show something else.
+        if self.is_unsafe_to_call(db, None, f.edition()) {
             f.write_str("unsafe ")?;
         }
         if let Some(abi) = &data.abi {
diff --git a/src/tools/rust-analyzer/crates/hir/src/from_id.rs b/src/tools/rust-analyzer/crates/hir/src/from_id.rs
index 2ad39817b2f..537401afdc3 100644
--- a/src/tools/rust-analyzer/crates/hir/src/from_id.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/from_id.rs
@@ -183,6 +183,7 @@ impl From<GenericDef> for GenericDefId {
             GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id),
             GenericDef::Impl(it) => GenericDefId::ImplId(it.id),
             GenericDef::Const(it) => GenericDefId::ConstId(it.id),
+            GenericDef::Static(it) => GenericDefId::StaticId(it.id),
         }
     }
 }
@@ -197,6 +198,7 @@ impl From<GenericDefId> for GenericDef {
             GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
             GenericDefId::ImplId(it) => GenericDef::Impl(it.into()),
             GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
+            GenericDefId::StaticId(it) => GenericDef::Static(it.into()),
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 0cbc75726bf..56090bc6b60 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -42,8 +42,8 @@ use arrayvec::ArrayVec;
 use base_db::{CrateDisplayName, CrateId, CrateOrigin};
 use either::Either;
 use hir_def::{
-    body::BodyDiagnostic,
     data::{adt::VariantData, TraitFlags},
+    expr_store::ExpressionStoreDiagnostics,
     generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
     hir::{BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat},
     item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
@@ -1892,10 +1892,10 @@ impl DefWithBody {
 
         for diag in source_map.diagnostics() {
             acc.push(match diag {
-                BodyDiagnostic::InactiveCode { node, cfg, opts } => {
+                ExpressionStoreDiagnostics::InactiveCode { node, cfg, opts } => {
                     InactiveCode { node: *node, cfg: cfg.clone(), opts: opts.clone() }.into()
                 }
-                BodyDiagnostic::MacroError { node, err } => {
+                ExpressionStoreDiagnostics::MacroError { node, err } => {
                     let RenderedExpandError { message, error, kind } =
                         err.render_to_string(db.upcast());
 
@@ -1919,20 +1919,22 @@ impl DefWithBody {
                     }
                     .into()
                 }
-                BodyDiagnostic::UnresolvedMacroCall { node, path } => UnresolvedMacroCall {
-                    macro_call: (*node).map(|ast_ptr| ast_ptr.into()),
-                    precise_location: None,
-                    path: path.clone(),
-                    is_bang: true,
+                ExpressionStoreDiagnostics::UnresolvedMacroCall { node, path } => {
+                    UnresolvedMacroCall {
+                        macro_call: (*node).map(|ast_ptr| ast_ptr.into()),
+                        precise_location: None,
+                        path: path.clone(),
+                        is_bang: true,
+                    }
+                    .into()
                 }
-                .into(),
-                BodyDiagnostic::AwaitOutsideOfAsync { node, location } => {
+                ExpressionStoreDiagnostics::AwaitOutsideOfAsync { node, location } => {
                     AwaitOutsideOfAsync { node: *node, location: location.clone() }.into()
                 }
-                BodyDiagnostic::UnreachableLabel { node, name } => {
+                ExpressionStoreDiagnostics::UnreachableLabel { node, name } => {
                     UnreachableLabel { node: *node, name: name.clone() }.into()
                 }
-                BodyDiagnostic::UndeclaredLabel { node, name } => {
+                ExpressionStoreDiagnostics::UndeclaredLabel { node, name } => {
                     UndeclaredLabel { node: *node, name: name.clone() }.into()
                 }
             });
@@ -1976,16 +1978,40 @@ impl DefWithBody {
             );
         }
 
-        let (unsafe_exprs, only_lint) = hir_ty::diagnostics::missing_unsafe(db, self.into());
-        for (node, reason) in unsafe_exprs {
+        let missing_unsafe = hir_ty::diagnostics::missing_unsafe(db, self.into());
+        for (node, reason) in missing_unsafe.unsafe_exprs {
             match source_map.expr_or_pat_syntax(node) {
-                Ok(node) => acc.push(MissingUnsafe { node, only_lint, reason }.into()),
+                Ok(node) => acc.push(
+                    MissingUnsafe {
+                        node,
+                        lint: if missing_unsafe.fn_is_unsafe {
+                            UnsafeLint::UnsafeOpInUnsafeFn
+                        } else {
+                            UnsafeLint::HardError
+                        },
+                        reason,
+                    }
+                    .into(),
+                ),
                 Err(SyntheticSyntax) => {
                     // FIXME: Here and elsewhere in this file, the `expr` was
                     // desugared, report or assert that this doesn't happen.
                 }
             }
         }
+        for node in missing_unsafe.deprecated_safe_calls {
+            match source_map.expr_syntax(node) {
+                Ok(node) => acc.push(
+                    MissingUnsafe {
+                        node: node.map(|it| it.wrap_left()),
+                        lint: UnsafeLint::DeprecatedSafe2024,
+                        reason: UnsafetyReason::UnsafeFnCall,
+                    }
+                    .into(),
+                ),
+                Err(SyntheticSyntax) => never!("synthetic DeprecatedSafe2024"),
+            }
+        }
 
         if let Ok(borrowck_results) = db.borrowck(self.into()) {
             for borrowck_result in borrowck_results.iter() {
@@ -2361,8 +2387,19 @@ impl Function {
         db.attrs(self.id.into()).is_unstable()
     }
 
-    pub fn is_unsafe_to_call(self, db: &dyn HirDatabase) -> bool {
-        hir_ty::is_fn_unsafe_to_call(db, self.id)
+    pub fn is_unsafe_to_call(
+        self,
+        db: &dyn HirDatabase,
+        caller: Option<Function>,
+        call_edition: Edition,
+    ) -> bool {
+        let target_features = caller
+            .map(|caller| hir_ty::TargetFeatures::from_attrs(&db.attrs(caller.id.into())))
+            .unwrap_or_default();
+        matches!(
+            hir_ty::is_fn_unsafe_to_call(db, self.id, &target_features, call_edition),
+            hir_ty::Unsafety::Unsafe
+        )
     }
 
     /// Whether this function declaration has a definition.
@@ -3453,6 +3490,7 @@ pub enum GenericDef {
     Impl(Impl),
     // consts can have type parameters from their parents (i.e. associated consts of traits)
     Const(Const),
+    Static(Static),
 }
 impl_from!(
     Function,
@@ -3461,7 +3499,8 @@ impl_from!(
     TraitAlias,
     TypeAlias,
     Impl,
-    Const
+    Const,
+    Static
     for GenericDef
 );
 
@@ -3511,6 +3550,7 @@ impl GenericDef {
             GenericDef::TypeAlias(it) => it.id.into(),
             GenericDef::Impl(it) => it.id.into(),
             GenericDef::Const(it) => it.id.into(),
+            GenericDef::Static(it) => it.id.into(),
         }
     }
 
@@ -3568,6 +3608,7 @@ impl GenericDef {
                     item_tree_source_maps.impl_(id.value).generics()
                 }
                 GenericDefId::ConstId(_) => return,
+                GenericDefId::StaticId(_) => return,
             },
         };
 
@@ -4624,17 +4665,6 @@ impl Type {
         Type { env: TraitEnvironment::empty(krate), ty }
     }
 
-    pub fn reference(inner: &Type, m: Mutability) -> Type {
-        inner.derived(
-            TyKind::Ref(
-                if m.is_mut() { hir_ty::Mutability::Mut } else { hir_ty::Mutability::Not },
-                hir_ty::error_lifetime(),
-                inner.ty.clone(),
-            )
-            .intern(Interner),
-        )
-    }
-
     fn new(db: &dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Type {
         let resolver = lexical_env.resolver(db.upcast());
         let environment = resolver
@@ -4866,6 +4896,17 @@ impl Type {
         self.normalize_trait_assoc_type(db, &[], iterator_item.into())
     }
 
+    pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool {
+        let Some(iterator_trait) =
+            db.lang_item(self.env.krate, LangItem::Iterator).and_then(|it| it.as_trait())
+        else {
+            return false;
+        };
+        let canonical_ty =
+            Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
+        method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, iterator_trait)
+    }
+
     /// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
     pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<Type> {
         let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| {
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index 09470bed9cf..882a27182f0 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -2040,6 +2040,13 @@ impl SemanticsScope<'_> {
         Crate { id: self.resolver.krate() }
     }
 
+    pub fn containing_function(&self) -> Option<Function> {
+        self.resolver.body_owner().and_then(|owner| match owner {
+            DefWithBodyId::FunctionId(id) => Some(id.into()),
+            _ => None,
+        })
+    }
+
     pub(crate) fn resolver(&self) -> &Resolver {
         &self.resolver
     }
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index b699ccde412..23e7518883b 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -14,7 +14,7 @@ use crate::{
 };
 use either::Either;
 use hir_def::{
-    body::{
+    expr_store::{
         scope::{ExprScopes, ScopeId},
         Body, BodySourceMap, HygieneId,
     },
@@ -1105,16 +1105,9 @@ impl SourceAnalyzer {
             if let Some(expanded_expr) = sm.macro_expansion_expr(macro_expr) {
                 let mut is_unsafe = false;
                 let mut walk_expr = |expr_id| {
-                    unsafe_expressions(
-                        db,
-                        infer,
-                        *def,
-                        body,
-                        expr_id,
-                        &mut |_, inside_unsafe_block, _| {
-                            is_unsafe |= inside_unsafe_block == InsideUnsafeBlock::No
-                        },
-                    )
+                    unsafe_expressions(db, infer, *def, body, expr_id, &mut |inside_unsafe_block| {
+                        is_unsafe |= inside_unsafe_block == InsideUnsafeBlock::No
+                    })
                 };
                 match expanded_expr {
                     ExprOrPatId::ExprId(expanded_expr) => walk_expr(expanded_expr),
@@ -1259,7 +1252,11 @@ fn scope_for(
     node: InFile<&SyntaxNode>,
 ) -> Option<ScopeId> {
     node.ancestors_with_macros(db.upcast())
-        .take_while(|it| !ast::Item::can_cast(it.kind()) || ast::MacroCall::can_cast(it.kind()))
+        .take_while(|it| {
+            !ast::Item::can_cast(it.kind())
+                || ast::MacroCall::can_cast(it.kind())
+                || ast::Use::can_cast(it.kind())
+        })
         .filter_map(|it| it.map(ast::Expr::cast).transpose())
         .filter_map(|it| source_map.node_expr(it.as_ref())?.as_expr())
         .find_map(|it| scopes.scope_for(it))
diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search.rs b/src/tools/rust-analyzer/crates/hir/src/term_search.rs
index 6f845137084..af72179305c 100644
--- a/src/tools/rust-analyzer/crates/hir/src/term_search.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/term_search.rs
@@ -145,7 +145,7 @@ impl LookupTable {
                 self.data
                     .iter()
                     .find(|(t, _)| {
-                        Type::reference(t, Mutability::Shared).could_unify_with_deeply(db, ty)
+                        t.add_reference(Mutability::Shared).could_unify_with_deeply(db, ty)
                     })
                     .map(|(t, it)| {
                         it.exprs(t)
diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs
index 1b0e6f8bd5b..847304d503a 100644
--- a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs
@@ -15,6 +15,7 @@ use hir_ty::mir::BorrowKind;
 use hir_ty::TyBuilder;
 use itertools::Itertools;
 use rustc_hash::FxHashSet;
+use span::Edition;
 
 use crate::{
     Adt, AssocItem, GenericDef, GenericParam, HasAttrs, HasVisibility, Impl, ModuleDef, ScopeDef,
@@ -365,7 +366,7 @@ pub(super) fn free_function<'a, DB: HirDatabase>(
                         let ret_ty = it.ret_type_with_args(db, generics.iter().cloned());
                         // Filter out private and unsafe functions
                         if !it.is_visible_from(db, module)
-                            || it.is_unsafe_to_call(db)
+                            || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME)
                             || it.is_unstable(db)
                             || ctx.config.enable_borrowcheck && ret_ty.contains_reference(db)
                             || ret_ty.is_raw_ptr()
@@ -470,7 +471,10 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
             }
 
             // Filter out private and unsafe functions
-            if !it.is_visible_from(db, module) || it.is_unsafe_to_call(db) || it.is_unstable(db) {
+            if !it.is_visible_from(db, module)
+                || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME)
+                || it.is_unstable(db)
+            {
                 return None;
             }
 
@@ -658,7 +662,10 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
             }
 
             // Filter out private and unsafe functions
-            if !it.is_visible_from(db, module) || it.is_unsafe_to_call(db) || it.is_unstable(db) {
+            if !it.is_visible_from(db, module)
+                || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME)
+                || it.is_unstable(db)
+            {
                 return None;
             }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
index 70fb5680052..491727a30a8 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
@@ -15,7 +15,7 @@ use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKin
 
 // Assist: apply_demorgan
 //
-// Apply https://en.wikipedia.org/wiki/De_Morgan%27s_laws[De Morgan's law].
+// Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws).
 // This transforms expressions of the form `!l || !r` into `!(l && r)`.
 // This also works with `&&`. This assist can only be applied with the cursor
 // on either `||` or `&&`.
@@ -131,7 +131,7 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
 
 // Assist: apply_demorgan_iterator
 //
-// Apply https://en.wikipedia.org/wiki/De_Morgan%27s_laws[De Morgan's law] to
+// Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to
 // `Iterator::all` and `Iterator::any`.
 //
 // This transforms expressions of the form `!iter.any(|x| predicate(x))` into
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
index d86948818b1..a92a000c3fb 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
@@ -38,7 +38,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel};
 // use super::AssistContext;
 // ```
 //
-// .Import Granularity
+// #### Import Granularity
 //
 // It is possible to configure how use-trees are merged with the `imports.granularity.group` setting.
 // It has the following configurations:
@@ -54,7 +54,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel};
 //
 // In `VS Code` the configuration for this is `rust-analyzer.imports.granularity.group`.
 //
-// .Import Prefix
+// #### Import Prefix
 //
 // The style of imports in the same crate is configurable through the `imports.prefix` setting.
 // It has the following configurations:
@@ -68,7 +68,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel};
 //
 // In `VS Code` the configuration for this is `rust-analyzer.imports.prefix`.
 //
-// image::https://user-images.githubusercontent.com/48062697/113020673-b85be580-917a-11eb-9022-59585f35d4f8.gif[]
+// ![Auto Import](https://user-images.githubusercontent.com/48062697/113020673-b85be580-917a-11eb-9022-59585f35d4f8.gif)
 
 // Assist: auto_import
 //
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index 3c84f83906a..f6e516db888 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -140,8 +140,10 @@ fn edit_struct_references(
         match_ast! {
             match node {
                 ast::TupleStructPat(tuple_struct_pat) => {
+                    let file_range = ctx.sema.original_range_opt(&node)?;
+                    edit.edit_file(file_range.file_id);
                     edit.replace(
-                        tuple_struct_pat.syntax().text_range(),
+                        file_range.range,
                         ast::make::record_pat_with_fields(
                             tuple_struct_pat.path()?,
                             ast::make::record_pat_field_list(tuple_struct_pat.fields().zip(names).map(
@@ -924,4 +926,102 @@ pub struct Foo { #[my_custom_attr] field1: u32 }
 "#,
         );
     }
+
+    #[test]
+    fn convert_in_macro_pattern_args() {
+        check_assist(
+            convert_tuple_struct_to_named_struct,
+            r#"
+macro_rules! foo {
+    ($expression:expr, $pattern:pat) => {
+        match $expression {
+            $pattern => true,
+            _ => false
+        }
+    };
+}
+enum Expr {
+    A$0(usize),
+}
+fn main() {
+    let e = Expr::A(0);
+    foo!(e, Expr::A(0));
+}
+"#,
+            r#"
+macro_rules! foo {
+    ($expression:expr, $pattern:pat) => {
+        match $expression {
+            $pattern => true,
+            _ => false
+        }
+    };
+}
+enum Expr {
+    A { field1: usize },
+}
+fn main() {
+    let e = Expr::A { field1: 0 };
+    foo!(e, Expr::A { field1: 0 });
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn convert_in_multi_file_macro_pattern_args() {
+        check_assist(
+            convert_tuple_struct_to_named_struct,
+            r#"
+//- /main.rs
+mod foo;
+
+enum Test {
+    A$0(i32)
+}
+
+//- /foo.rs
+use crate::Test;
+
+macro_rules! foo {
+    ($expression:expr, $pattern:pat) => {
+        match $expression {
+            $pattern => true,
+            _ => false
+        }
+    };
+}
+
+fn foo() {
+    let a = Test::A(0);
+    foo!(a, Test::A(0));
+}
+"#,
+            r#"
+//- /main.rs
+mod foo;
+
+enum Test {
+    A { field1: i32 }
+}
+
+//- /foo.rs
+use crate::Test;
+
+macro_rules! foo {
+    ($expression:expr, $pattern:pat) => {
+        match $expression {
+            $pattern => true,
+            _ => false
+        }
+    };
+}
+
+fn foo() {
+    let a = Test::A { field1: 0 };
+    foo!(a, Test::A { field1: 0 });
+}
+"#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 54e42f126bc..4b0fa704a22 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -1,4 +1,4 @@
-//! Generated by `cargo codegen assists-doc-tests`, do not edit by hand.
+//! Generated by `cargo xtask codegen assists-doc-tests`, do not edit by hand.
 
 use super::check_doc_test;
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index 78ff4417913..c1332d99bff 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -793,8 +793,8 @@ pub(crate) fn convert_reference_type(
 }
 
 fn could_deref_to_target(ty: &hir::Type, target: &hir::Type, db: &dyn HirDatabase) -> bool {
-    let ty_ref = hir::Type::reference(ty, hir::Mutability::Shared);
-    let target_ref = hir::Type::reference(target, hir::Mutability::Shared);
+    let ty_ref = ty.add_reference(hir::Mutability::Shared);
+    let target_ref = target.add_reference(hir::Mutability::Shared);
     ty_ref.could_coerce_to(db, &target_ref)
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs
index d12654665ce..b38b9ac1f53 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs
@@ -89,7 +89,7 @@ pub(crate) fn complete_dot(
         acc.add_method(ctx, dot_access, func, None, None)
     });
 
-    if ctx.config.enable_auto_iter {
+    if ctx.config.enable_auto_iter && !receiver_ty.strip_references().impls_iterator(ctx.db) {
         // FIXME:
         // Checking for the existence of `iter()` is complicated in our setup, because we need to substitute
         // its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`.
@@ -1500,9 +1500,31 @@ fn main() {
     bar.$0
 }
 "#,
+            expect![[r#""#]],
+        );
+    }
+
+    #[test]
+    fn no_iter_suggestion_on_iterator() {
+        check_no_kw(
+            r#"
+//- minicore: iterator
+struct MyIter;
+impl Iterator for MyIter {
+    type Item = ();
+    fn next(&mut self) -> Option<Self::Item> { None }
+}
+
+fn main() {
+    MyIter.$0
+}
+"#,
             expect![[r#"
-    me foo() fn(self: Bar)
-"#]],
+                me by_ref() (as Iterator)                             fn(&mut self) -> &mut Self
+                me into_iter() (as IntoIterator)    fn(self) -> <Self as IntoIterator>::IntoIter
+                me next() (as Iterator)        fn(&mut self) -> Option<<Self as Iterator>::Item>
+                me nth(…) (as Iterator) fn(&mut self, usize) -> Option<<Self as Iterator>::Item>
+            "#]],
         );
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs
index 24243f57b46..b5555e66102 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs
@@ -83,19 +83,19 @@ use crate::{
 // NOTE: currently, if an assoc item comes from a trait that's not currently imported, and it also has an unresolved and/or partially-qualified path,
 // no imports will be proposed.
 //
-// .Fuzzy search details
+// #### Fuzzy search details
 //
 // To avoid an excessive amount of the results returned, completion input is checked for inclusion in the names only
 // (i.e. in `HashMap` in the `std::collections::HashMap` path).
 // For the same reasons, avoids searching for any path imports for inputs with their length less than 2 symbols
 // (but shows all associated items for any input length).
 //
-// .Import configuration
+// #### Import configuration
 //
 // It is possible to configure how use-trees are merged with the `imports.granularity.group` setting.
 // Mimics the corresponding behavior of the `Auto Import` feature.
 //
-// .LSP and performance implications
+// #### LSP and performance implications
 //
 // The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the `additionalTextEdits`
 // (case-sensitive) resolve client capability in its client capabilities.
@@ -103,7 +103,7 @@ use crate::{
 // For clients with no such support, all edits have to be calculated on the completion request, including the fuzzy search completion ones,
 // which might be slow ergo the feature is automatically disabled.
 //
-// .Feature toggle
+// #### Feature toggle
 //
 // The feature can be forcefully turned off in the settings with the `rust-analyzer.completion.autoimport.enable` flag.
 // Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corresponding
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs
index 2755329bb31..c612170eb54 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs
@@ -14,7 +14,7 @@
 // ** `logw` -> `log::warn!(...)`
 // ** `loge` -> `log::error!(...)`
 //
-// image::https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif[]
+// ![Format String Completion](https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif)
 
 use ide_db::{
     syntax_helpers::format_string_exprs::{parse_format_exprs, with_placeholders, Arg},
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
index 2f1860cbb59..7862b258789 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -442,6 +442,8 @@ pub(crate) struct CompletionContext<'a> {
     pub(crate) krate: hir::Crate,
     /// The module of the `scope`.
     pub(crate) module: hir::Module,
+    /// The function where we're completing, if inside a function.
+    pub(crate) containing_function: Option<hir::Function>,
     /// Whether nightly toolchain is used. Cached since this is looked up a lot.
     pub(crate) is_nightly: bool,
     /// The edition of the current crate
@@ -760,6 +762,7 @@ impl<'a> CompletionContext<'a> {
 
         let krate = scope.krate();
         let module = scope.module();
+        let containing_function = scope.containing_function();
         let edition = krate.edition(db);
 
         let toolchain = db.toolchain_channel(krate.into());
@@ -874,6 +877,7 @@ impl<'a> CompletionContext<'a> {
             token,
             krate,
             module,
+            containing_function,
             is_nightly,
             edition,
             expected_name,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
index f5a50ae8190..eecd412bc43 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -59,7 +59,7 @@ pub(super) fn expand_and_analyze(
     // make the offset point to the start of the original token, as that is what the
     // intermediate offsets calculated in expansion always points to
     let offset = offset - relative_offset;
-    let expansion = expand(
+    let expansion = expand_maybe_stop(
         sema,
         original_file.clone(),
         speculative_file.clone(),
@@ -118,7 +118,7 @@ fn token_at_offset_ignore_whitespace(file: &SyntaxNode, offset: TextSize) -> Opt
 /// that we check, we subtract `COMPLETION_MARKER.len()`. This may not be accurate because proc macros
 /// can insert the text of the completion marker in other places while removing the span, but this is
 /// the best we can do.
-fn expand(
+fn expand_maybe_stop(
     sema: &Semantics<'_, RootDatabase>,
     original_file: SyntaxNode,
     speculative_file: SyntaxNode,
@@ -126,23 +126,48 @@ fn expand(
     fake_ident_token: SyntaxToken,
     relative_offset: TextSize,
 ) -> Option<ExpansionResult> {
-    let _p = tracing::info_span!("CompletionContext::expand").entered();
+    if let result @ Some(_) = expand(
+        sema,
+        original_file.clone(),
+        speculative_file.clone(),
+        original_offset,
+        fake_ident_token.clone(),
+        relative_offset,
+    ) {
+        return result;
+    }
 
+    // This needs to come after the recursive call, because our "inside macro" detection is subtly wrong
+    // with regard to attribute macros named `test` that are not std's test. So hopefully we will expand
+    // them successfully above and be able to analyze.
     // Left biased since there may already be an identifier token there, and we appended to it.
     if !sema.might_be_inside_macro_call(&fake_ident_token)
         && token_at_offset_ignore_whitespace(&original_file, original_offset + relative_offset)
             .is_some_and(|original_token| !sema.might_be_inside_macro_call(&original_token))
     {
         // Recursion base case.
-        return Some(ExpansionResult {
+        Some(ExpansionResult {
             original_file,
             speculative_file,
             original_offset,
             speculative_offset: fake_ident_token.text_range().start(),
             fake_ident_token,
             derive_ctx: None,
-        });
+        })
+    } else {
+        None
     }
+}
+
+fn expand(
+    sema: &Semantics<'_, RootDatabase>,
+    original_file: SyntaxNode,
+    speculative_file: SyntaxNode,
+    original_offset: TextSize,
+    fake_ident_token: SyntaxToken,
+    relative_offset: TextSize,
+) -> Option<ExpansionResult> {
+    let _p = tracing::info_span!("CompletionContext::expand").entered();
 
     let parent_item =
         |item: &ast::Item| item.syntax().ancestors().skip(1).find_map(ast::Item::cast);
@@ -197,7 +222,7 @@ fn expand(
                             // stop here to prevent problems from happening
                             return None;
                         }
-                        let result = expand(
+                        let result = expand_maybe_stop(
                             sema,
                             actual_expansion.clone(),
                             fake_expansion.clone(),
@@ -317,7 +342,7 @@ fn expand(
                                     // stop here to prevent problems from happening
                                     return None;
                                 }
-                                let result = expand(
+                                let result = expand_maybe_stop(
                                     sema,
                                     actual_expansion.clone(),
                                     fake_expansion.clone(),
@@ -386,7 +411,7 @@ fn expand(
                         // stop here to prevent problems from happening
                         return None;
                     }
-                    let result = expand(
+                    let result = expand_maybe_stop(
                         sema,
                         actual_expansion.clone(),
                         fake_expansion.clone(),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
index 8051d48ca5f..a1f2eaeb1b6 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
@@ -106,11 +106,13 @@ impl CompletionFieldsToResolve {
 //
 // There also snippet completions:
 //
-// .Expressions
+// #### Expressions
+//
 // - `pd` -> `eprintln!(" = {:?}", );`
 // - `ppd` -> `eprintln!(" = {:#?}", );`
 //
-// .Items
+// #### Items
+//
 // - `tfn` -> `#[test] fn feature(){}`
 // - `tmod` ->
 // ```rust
@@ -127,7 +129,7 @@ impl CompletionFieldsToResolve {
 // Those are the additional completion options with automatic `use` import and options from all project importable items,
 // fuzzy matched against the completion input.
 //
-// image::https://user-images.githubusercontent.com/48062697/113020667-b72ab880-917a-11eb-8778-716cf26a0eb3.gif[]
+// ![Magic Completions](https://user-images.githubusercontent.com/48062697/113020667-b72ab880-917a-11eb-8778-716cf26a0eb3.gif)
 
 /// Main entry point for completion. We run completion as a two-phase process.
 ///
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
index c3354902c3b..fd90613964a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
@@ -144,7 +144,7 @@ fn render(
     let detail = if ctx.completion.config.full_function_signatures {
         detail_full(db, func, ctx.completion.edition)
     } else {
-        detail(db, func, ctx.completion.edition)
+        detail(ctx.completion, func, ctx.completion.edition)
     };
     item.set_documentation(ctx.docs(func))
         .set_deprecated(ctx.is_deprecated(func) || ctx.is_deprecated_assoc_item(func))
@@ -307,26 +307,26 @@ fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type) -> &'sta
     ""
 }
 
-fn detail(db: &dyn HirDatabase, func: hir::Function, edition: Edition) -> String {
-    let mut ret_ty = func.ret_type(db);
+fn detail(ctx: &CompletionContext<'_>, func: hir::Function, edition: Edition) -> String {
+    let mut ret_ty = func.ret_type(ctx.db);
     let mut detail = String::new();
 
-    if func.is_const(db) {
+    if func.is_const(ctx.db) {
         format_to!(detail, "const ");
     }
-    if func.is_async(db) {
+    if func.is_async(ctx.db) {
         format_to!(detail, "async ");
-        if let Some(async_ret) = func.async_ret_type(db) {
+        if let Some(async_ret) = func.async_ret_type(ctx.db) {
             ret_ty = async_ret;
         }
     }
-    if func.is_unsafe_to_call(db) {
+    if func.is_unsafe_to_call(ctx.db, ctx.containing_function, ctx.edition) {
         format_to!(detail, "unsafe ");
     }
 
-    format_to!(detail, "fn({})", params_display(db, func, edition));
+    format_to!(detail, "fn({})", params_display(ctx.db, func, edition));
     if !ret_ty.is_unit() {
-        format_to!(detail, " -> {}", ret_ty.display(db, edition));
+        format_to!(detail, " -> {}", ret_ty.display(ctx.db, edition));
     }
     detail
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
index 866b83a6146..07f33a826e4 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
@@ -8,8 +8,7 @@
 //
 // A custom snippet can be defined by adding it to the `rust-analyzer.completion.snippets.custom` object respectively.
 //
-// [source,json]
-// ----
+// ```json
 // {
 //   "rust-analyzer.completion.snippets.custom": {
 //     "thread spawn": {
@@ -25,7 +24,7 @@
 //     }
 //   }
 // }
-// ----
+// ```
 //
 // In the example above:
 //
@@ -39,6 +38,7 @@
 // * `description` is an optional description of the snippet, if unset the snippet name will be used.
 //
 // * `requires` is an optional list of item paths that have to be resolvable in the current crate where the completion is rendered.
+
 // On failure of resolution the snippet won't be applicable, otherwise the snippet will insert an import for the items on insertion if
 // the items aren't yet in scope.
 //
@@ -55,8 +55,8 @@
 //
 // For the VSCode editor, rust-analyzer also ships with a small set of defaults which can be removed
 // by overwriting the settings object mentioned above, the defaults are:
-// [source,json]
-// ----
+//
+// ```json
 // {
 //     "Arc::new": {
 //         "postfix": "arc",
@@ -98,7 +98,7 @@
 //         "scope": "expr"
 //     }
 // }
-// ----
+// ````
 
 use hir::{ModPath, Name, Symbol};
 use ide_db::imports::import_assets::LocatedImport;
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
index 663a038580d..37557512837 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
@@ -1986,3 +1986,53 @@ fn foo() {
         "#]],
     );
 }
+
+#[test]
+fn non_std_test_attr_macro() {
+    check(
+        r#"
+//- proc_macros: identity
+use proc_macros::identity as test;
+
+#[test]
+fn foo() {
+    $0
+}
+    "#,
+        expect![[r#"
+            fn foo()  fn()
+            md proc_macros
+            bt u32     u32
+            kw async
+            kw const
+            kw crate::
+            kw enum
+            kw extern
+            kw false
+            kw fn
+            kw for
+            kw if
+            kw if let
+            kw impl
+            kw let
+            kw loop
+            kw match
+            kw mod
+            kw return
+            kw self::
+            kw static
+            kw struct
+            kw trait
+            kw true
+            kw type
+            kw union
+            kw unsafe
+            kw use
+            kw while
+            kw while let
+            sn macro_rules
+            sn pd
+            sn ppd
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
index 35e3a8d9bf7..46ff4fbf9e9 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
@@ -44,12 +44,11 @@ impl RootDatabase {
     //
     // Clears rust-analyzer's internal database and prints memory usage statistics.
     //
-    // |===
-    // | Editor  | Action Name
-    //
+    // | Editor  | Action Name |
+    // |---------|-------------|
     // | VS Code | **rust-analyzer: Memory Usage (Clears Database)**
-    // |===
-    // image::https://user-images.githubusercontent.com/48062697/113065592-08559f00-91b1-11eb-8c96-64b88068ec02.gif[]
+
+    // ![Memory Usage](https://user-images.githubusercontent.com/48062697/113065592-08559f00-91b1-11eb-8c96-64b88068ec02.gif)
     pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes, usize)> {
         let mut acc: Vec<(String, Bytes, usize)> = vec![];
 
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
index d12bda0816f..bad53608056 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
@@ -986,6 +986,7 @@ impl From<GenericDef> for Definition {
             GenericDef::TypeAlias(it) => it.into(),
             GenericDef::Impl(it) => it.into(),
             GenericDef::Const(it) => it.into(),
+            GenericDef::Static(it) => it.into(),
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
index 0002fda0ba7..22dc3d9e29d 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
@@ -6,12 +6,13 @@ mod topologic_sort;
 
 use std::time::Duration;
 
-use hir::db::DefDatabase;
+use hir::{db::DefDatabase, Symbol};
+use itertools::Itertools;
 
 use crate::{
     base_db::{
         ra_salsa::{Database, ParallelDatabase, Snapshot},
-        Cancelled, CrateId, SourceDatabase, SourceRootDatabase,
+        Cancelled, CrateId, SourceDatabase,
     },
     symbol_index::SymbolsDatabase,
     FxIndexMap, RootDatabase,
@@ -21,11 +22,12 @@ use crate::{
 #[derive(Debug)]
 pub struct ParallelPrimeCachesProgress {
     /// the crates that we are currently priming.
-    pub crates_currently_indexing: Vec<String>,
+    pub crates_currently_indexing: Vec<Symbol>,
     /// the total number of crates we want to prime.
     pub crates_total: usize,
     /// the total number of crates that have finished priming
     pub crates_done: usize,
+    pub work_type: &'static str,
 }
 
 pub fn parallel_prime_caches(
@@ -47,41 +49,32 @@ pub fn parallel_prime_caches(
     };
 
     enum ParallelPrimeCacheWorkerProgress {
-        BeginCrate { crate_id: CrateId, crate_name: String },
+        BeginCrate { crate_id: CrateId, crate_name: Symbol },
         EndCrate { crate_id: CrateId },
     }
 
+    // We split off def map computation from other work,
+    // as the def map is the relevant one. Once the defmaps are computed
+    // the project is ready to go, the other indices are just nice to have for some IDE features.
+    #[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone)]
+    enum PrimingPhase {
+        DefMap,
+        ImportMap,
+        CrateSymbols,
+    }
+
     let (work_sender, progress_receiver) = {
         let (progress_sender, progress_receiver) = crossbeam_channel::unbounded();
         let (work_sender, work_receiver) = crossbeam_channel::unbounded();
-        let graph = graph.clone();
-        let local_roots = db.local_roots();
         let prime_caches_worker = move |db: Snapshot<RootDatabase>| {
-            while let Ok((crate_id, crate_name)) = work_receiver.recv() {
+            while let Ok((crate_id, crate_name, kind)) = work_receiver.recv() {
                 progress_sender
                     .send(ParallelPrimeCacheWorkerProgress::BeginCrate { crate_id, crate_name })?;
 
-                // Compute the DefMap and possibly ImportMap
-                let file_id = graph[crate_id].root_file_id;
-                let root_id = db.file_source_root(file_id);
-                if db.source_root(root_id).is_library {
-                    db.crate_def_map(crate_id);
-                } else {
-                    // This also computes the DefMap
-                    db.import_map(crate_id);
-                }
-
-                // Compute the symbol search index.
-                // This primes the cache for `ide_db::symbol_index::world_symbols()`.
-                //
-                // We do this for workspace crates only (members of local_roots), because doing it
-                // for all dependencies could be *very* unnecessarily slow in a large project.
-                //
-                // FIXME: We should do it unconditionally if the configuration is set to default to
-                // searching dependencies (rust-analyzer.workspace.symbol.search.scope), but we
-                // would need to pipe that configuration information down here.
-                if local_roots.contains(&root_id) {
-                    db.crate_symbols(crate_id.into());
+                match kind {
+                    PrimingPhase::DefMap => _ = db.crate_def_map(crate_id),
+                    PrimingPhase::ImportMap => _ = db.import_map(crate_id),
+                    PrimingPhase::CrateSymbols => _ = db.crate_symbols(crate_id.into()),
                 }
 
                 progress_sender.send(ParallelPrimeCacheWorkerProgress::EndCrate { crate_id })?;
@@ -112,16 +105,34 @@ pub fn parallel_prime_caches(
     let mut crates_currently_indexing =
         FxIndexMap::with_capacity_and_hasher(num_worker_threads, Default::default());
 
+    let mut additional_phases = vec![];
+
     while crates_done < crates_total {
         db.unwind_if_cancelled();
 
         for crate_id in &mut crates_to_prime {
-            work_sender
-                .send((
-                    crate_id,
-                    graph[crate_id].display_name.as_deref().unwrap_or_default().to_owned(),
-                ))
-                .ok();
+            let krate = &graph[crate_id];
+            let name = krate
+                .display_name
+                .as_deref()
+                .cloned()
+                .unwrap_or_else(|| Symbol::integer(crate_id.into_raw().into_u32() as usize));
+            if krate.origin.is_lang() {
+                additional_phases.push((crate_id, name.clone(), PrimingPhase::ImportMap));
+            } else if krate.origin.is_local() {
+                // Compute the symbol search index.
+                // This primes the cache for `ide_db::symbol_index::world_symbols()`.
+                //
+                // We do this for workspace crates only (members of local_roots), because doing it
+                // for all dependencies could be *very* unnecessarily slow in a large project.
+                //
+                // FIXME: We should do it unconditionally if the configuration is set to default to
+                // searching dependencies (rust-analyzer.workspace.symbol.search.scope), but we
+                // would need to pipe that configuration information down here.
+                additional_phases.push((crate_id, name.clone(), PrimingPhase::CrateSymbols));
+            }
+
+            work_sender.send((crate_id, name, PrimingPhase::DefMap)).ok();
         }
 
         // recv_timeout is somewhat a hack, we need a way to from this thread check to see if the current salsa revision
@@ -153,6 +164,50 @@ pub fn parallel_prime_caches(
             crates_currently_indexing: crates_currently_indexing.values().cloned().collect(),
             crates_done,
             crates_total,
+            work_type: "Indexing",
+        };
+
+        cb(progress);
+    }
+
+    let mut crates_done = 0;
+    let crates_total = additional_phases.len();
+    for w in additional_phases.into_iter().sorted_by_key(|&(_, _, phase)| phase) {
+        work_sender.send(w).ok();
+    }
+
+    while crates_done < crates_total {
+        db.unwind_if_cancelled();
+
+        // recv_timeout is somewhat a hack, we need a way to from this thread check to see if the current salsa revision
+        // is cancelled on a regular basis. workers will only exit if they are processing a task that is cancelled, or
+        // if this thread exits, and closes the work channel.
+        let worker_progress = match progress_receiver.recv_timeout(Duration::from_millis(10)) {
+            Ok(p) => p,
+            Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
+                continue;
+            }
+            Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
+                // our workers may have died from a cancelled task, so we'll check and re-raise here.
+                db.unwind_if_cancelled();
+                break;
+            }
+        };
+        match worker_progress {
+            ParallelPrimeCacheWorkerProgress::BeginCrate { crate_id, crate_name } => {
+                crates_currently_indexing.insert(crate_id, crate_name);
+            }
+            ParallelPrimeCacheWorkerProgress::EndCrate { crate_id } => {
+                crates_currently_indexing.swap_remove(&crate_id);
+                crates_done += 1;
+            }
+        };
+
+        let progress = ParallelPrimeCachesProgress {
+            crates_currently_indexing: crates_currently_indexing.values().cloned().collect(),
+            crates_done,
+            crates_total,
+            work_type: "Populating symbols",
         };
 
         cb(progress);
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
index 7fc563a4241..7963e8ae4f7 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -354,6 +354,7 @@ impl Definition {
                 hir::GenericDef::TypeAlias(it) => it.source(db).map(|src| src.syntax().cloned()),
                 hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()),
                 hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()),
+                hir::GenericDef::Static(it) => it.source(db).map(|src| src.syntax().cloned()),
             };
             return match def {
                 Some(def) => SearchScope::file_range(
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
index e5ce10a771e..bb4c289c908 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
@@ -193,11 +193,9 @@ impl<DB> std::ops::Deref for Snap<DB> {
 // `rust-analyzer.workspace.symbol.search.kind` settings. Symbols prefixed
 // with `__` are hidden from the search results unless configured otherwise.
 //
-// |===
-// | Editor  | Shortcut
-//
-// | VS Code | kbd:[Ctrl+T]
-// |===
+// | Editor  | Shortcut |
+// |---------|-----------|
+// | VS Code | <kbd>Ctrl+T</kbd>
 pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
     let _p = tracing::info_span!("world_symbols", query = ?query.query).entered();
 
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs
index bbdeb7cf085..246330e6efa 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs
@@ -12,7 +12,7 @@ use crate::{
 
 // Diagnostic: incorrect-ident-case
 //
-// This diagnostic is triggered if an item name doesn't follow https://doc.rust-lang.org/1.0.0/style/style/naming/README.html[Rust naming convention].
+// This diagnostic is triggered if an item name doesn't follow [Rust naming convention](https://doc.rust-lang.org/1.0.0/style/style/naming/README.html).
 pub(crate) fn incorrect_case(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Diagnostic {
     let code = match d.expected_case {
         CaseType::LowerSnakeCase => DiagnosticCode::RustcLint("non_snake_case"),
@@ -936,6 +936,7 @@ fn func() {
     fn override_lint_level() {
         check_diagnostics(
             r#"
+#![allow(unused_variables)]
 #[warn(nonstandard_style)]
 fn foo() {
     let BAR;
@@ -992,6 +993,7 @@ struct QUX;
 const foo: i32 = 0;
 fn BAR() {
     let BAZ;
+    _ = BAZ;
 }
         "#,
         );
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
index c7cdcf49820..5730508436d 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
@@ -1129,4 +1129,39 @@ fn main() {
         "#,
         );
     }
+
+    #[test]
+    fn regression_18682() {
+        check_diagnostics(
+            r#"
+//- minicore: coerce_unsized
+struct Flexible {
+    body: [u8],
+}
+
+trait Field {
+    type Type: ?Sized;
+}
+
+impl Field for Flexible {
+    type Type = [u8];
+}
+
+trait KnownLayout {
+    type MaybeUninit: ?Sized;
+}
+
+
+impl<T> KnownLayout for [T] {
+    type MaybeUninit = [T];
+}
+
+struct ZerocopyKnownLayoutMaybeUninit(<<Flexible as Field>::Type as KnownLayout>::MaybeUninit);
+
+fn test(ptr: *mut [u8]) -> *mut ZerocopyKnownLayoutMaybeUninit {
+    ptr as *mut _
+}
+"#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
index 8117401a534..323a5723d4a 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
@@ -1,5 +1,5 @@
 use hir::db::ExpandDatabase;
-use hir::{HirFileIdExt, UnsafetyReason};
+use hir::{HirFileIdExt, UnsafeLint, UnsafetyReason};
 use ide_db::text_edit::TextEdit;
 use ide_db::{assists::Assist, source_change::SourceChange};
 use syntax::{ast, SyntaxNode};
@@ -11,10 +11,10 @@ use crate::{fix, Diagnostic, DiagnosticCode, DiagnosticsContext};
 //
 // This diagnostic is triggered if an operation marked as `unsafe` is used outside of an `unsafe` function or block.
 pub(crate) fn missing_unsafe(ctx: &DiagnosticsContext<'_>, d: &hir::MissingUnsafe) -> Diagnostic {
-    let code = if d.only_lint {
-        DiagnosticCode::RustcLint("unsafe_op_in_unsafe_fn")
-    } else {
-        DiagnosticCode::RustcHardError("E0133")
+    let code = match d.lint {
+        UnsafeLint::HardError => DiagnosticCode::RustcHardError("E0133"),
+        UnsafeLint::UnsafeOpInUnsafeFn => DiagnosticCode::RustcLint("unsafe_op_in_unsafe_fn"),
+        UnsafeLint::DeprecatedSafe2024 => DiagnosticCode::RustcLint("deprecated_safe_2024"),
     };
     let operation = display_unsafety_reason(d.reason);
     Diagnostic::new_with_syntax_node_ptr(
@@ -585,25 +585,59 @@ fn main() {
             r#"
 //- /ed2021.rs crate:ed2021 edition:2021
 #[rustc_deprecated_safe_2024]
-unsafe fn safe() -> u8 {
+unsafe fn deprecated_safe() -> u8 {
     0
 }
+
 //- /ed2024.rs crate:ed2024 edition:2024
 #[rustc_deprecated_safe_2024]
-unsafe fn not_safe() -> u8 {
+unsafe fn deprecated_safe() -> u8 {
     0
 }
-//- /main.rs crate:main deps:ed2021,ed2024
+
+//- /dep1.rs crate:dep1 deps:ed2021,ed2024 edition:2021
+fn main() {
+    ed2021::deprecated_safe();
+    ed2024::deprecated_safe();
+}
+
+//- /dep2.rs crate:dep2 deps:ed2021,ed2024 edition:2024
+fn main() {
+    ed2021::deprecated_safe();
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
+    ed2024::deprecated_safe();
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
+}
+
+//- /dep3.rs crate:dep3 deps:ed2021,ed2024 edition:2021
+#![warn(deprecated_safe)]
+
 fn main() {
-    ed2021::safe();
-    ed2024::not_safe();
-  //^^^^^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
+    ed2021::deprecated_safe();
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^💡 warn: call to unsafe function is unsafe and requires an unsafe function or block
+    ed2024::deprecated_safe();
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^💡 warn: call to unsafe function is unsafe and requires an unsafe function or block
 }
             "#,
         )
     }
 
     #[test]
+    fn orphan_unsafe_format_args() {
+        // Checks that we don't place orphan arguments for formatting under an unsafe block.
+        check_diagnostics(
+            r#"
+//- minicore: fmt
+fn foo() {
+    let p = 0xDEADBEEF as *const i32;
+    format_args!("", *p);
+                  // ^^ error: dereference of raw pointer is unsafe and requires an unsafe function or block
+}
+        "#,
+        );
+    }
+
+    #[test]
     fn unsafe_op_in_unsafe_fn_allowed_by_default_in_edition_2021() {
         check_diagnostics(
             r#"
@@ -812,4 +846,36 @@ fn main() {
 "#,
         )
     }
+
+    #[test]
+    fn target_feature() {
+        check_diagnostics(
+            r#"
+#[target_feature(enable = "avx")]
+fn foo() {}
+
+#[target_feature(enable = "avx,avx2")]
+fn bar() {
+    foo();
+}
+
+fn baz() {
+    foo();
+ // ^^^^^ 💡 error: call to unsafe function is unsafe and requires an unsafe function or block
+}
+        "#,
+        );
+    }
+
+    #[test]
+    fn unsafe_fn_ptr_call() {
+        check_diagnostics(
+            r#"
+fn f(it: unsafe fn()){
+    it();
+ // ^^^^ 💡 error: call to unsafe function is unsafe and requires an unsafe function or block
+}
+        "#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs
index 13979791444..0e3c4c7aa36 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs
@@ -831,13 +831,14 @@ fn f() {
 
     #[test]
     fn or_pattern() {
-        // FIXME: `None` is inferred as unknown here for some reason
         check_diagnostics(
             r#"
 //- minicore: option
 fn f(_: i32) {}
 fn main() {
     let ((Some(mut x), None) | (_, Some(mut x))) = (None, Some(7)) else { return };
+             //^^^^^ 💡 warn: variable does not need to be mutable
+
     f(x);
 }
 "#,
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
index 56afb38cc81..73dcbc13b79 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
@@ -1,5 +1,5 @@
 use either::Either;
-use hir::{db::ExpandDatabase, CallableKind, ClosureStyle, HirDisplay, HirFileIdExt, InFile, Type};
+use hir::{db::ExpandDatabase, CallableKind, ClosureStyle, HirDisplay, HirFileIdExt, InFile};
 use ide_db::{
     famous_defs::FamousDefs,
     source_change::{SourceChange, SourceChangeBuilder},
@@ -88,7 +88,7 @@ fn add_reference(
     let range = ctx.sema.diagnostics_display_range((*expr_ptr).map(|it| it.into()));
 
     let (_, mutability) = d.expected.as_reference()?;
-    let actual_with_ref = Type::reference(&d.actual, mutability);
+    let actual_with_ref = d.actual.add_reference(mutability);
     if !actual_with_ref.could_coerce_to(ctx.sema.db, &d.expected) {
         return None;
     }
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
index 6b654f89345..889258c94c5 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
@@ -33,12 +33,10 @@
 //
 // Supported constraints:
 //
-// |===
-// | Constraint    | Restricts placeholder
-//
-// | kind(literal) | Is a literal (e.g. `42` or `"forty two"`)
-// | not(a)        | Negates the constraint `a`
-// |===
+// | Constraint    | Restricts placeholder |
+// |---------------|------------------------|
+// | kind(literal) | Is a literal (e.g. `42` or `"forty two"`) |
+// | not(a)        | Negates the constraint `a` |
 //
 // Available via the command `rust-analyzer.ssr`.
 //
@@ -52,11 +50,9 @@
 // String::from((y + 5).foo(z))
 // ```
 //
-// |===
-// | Editor  | Action Name
-//
-// | VS Code | **rust-analyzer: Structural Search Replace**
-// |===
+// | Editor  | Action Name |
+// |---------|--------------|
+// | VS Code | **rust-analyzer: Structural Search Replace** |
 //
 // Also available as an assist, by writing a comment containing the structural
 // search and replace rule. You will only see the assist if the comment can
diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
index 18f866eb9fc..006e6e8246e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
@@ -21,7 +21,7 @@ mod fn_references;
 // Provides user with annotations above items for looking up references or impl blocks
 // and running/debugging binaries.
 //
-// image::https://user-images.githubusercontent.com/48062697/113020672-b7c34f00-917a-11eb-8f6e-858735660a0e.png[]
+// ![Annotations](https://user-images.githubusercontent.com/48062697/113020672-b7c34f00-917a-11eb-8f6e-858735660a0e.png)
 #[derive(Debug, Hash, PartialEq, Eq)]
 pub struct Annotation {
     pub range: TextRange,
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
index cfd8919730a..e35e47e7471 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
@@ -122,11 +122,9 @@ pub(crate) fn remove_links(markdown: &str) -> String {
 // The simplest way to use this feature is via the context menu. Right-click on
 // the selected item. The context menu opens. Select **Open Docs**.
 //
-// |===
-// | Editor  | Action Name
-//
-// | VS Code | **rust-analyzer: Open Docs**
-// |===
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Open Docs** |
 pub(crate) fn external_docs(
     db: &RootDatabase,
     FilePosition { file_id, offset }: FilePosition,
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index 0ad894427b2..ad4308e06a1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -19,13 +19,11 @@ pub struct ExpandedMacro {
 //
 // Shows the full macro expansion of the macro at the current caret position.
 //
-// |===
-// | Editor  | Action Name
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Expand macro recursively at caret** |
 //
-// | VS Code | **rust-analyzer: Expand macro recursively at caret**
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif[]
+// ![Expand Macro Recursively](https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif)
 pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> {
     let sema = Semantics::new(db);
     let file = sema.parse_guess_edition(position.file_id);
diff --git a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
index 3d49082f285..76414854e91 100644
--- a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
@@ -17,13 +17,11 @@ use crate::FileRange;
 // Extends or shrinks the current selection to the encompassing syntactic construct
 // (expression, statement, item, module, etc). It works with multiple cursors.
 //
-// |===
-// | Editor  | Shortcut
+// | Editor  | Shortcut |
+// |---------|----------|
+// | VS Code | <kbd>Alt+Shift+→</kbd>, <kbd>Alt+Shift+←</kbd> |
 //
-// | VS Code | kbd:[Alt+Shift+→], kbd:[Alt+Shift+←]
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113020651-b42fc800-917a-11eb-8a4f-cf1a07859fac.gif[]
+// ![Expand and Shrink Selection](https://user-images.githubusercontent.com/48062697/113020651-b42fc800-917a-11eb-8a4f-cf1a07859fac.gif)
 pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange {
     let sema = Semantics::new(db);
     let src = sema.parse_guess_edition(frange.file_id);
diff --git a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs
index 37b3cb03b33..5ed21444307 100644
--- a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs
@@ -14,13 +14,11 @@ pub struct CrateInfo {
 //
 // Shows a view tree with all the dependencies of this project
 //
-// |===
-// | Editor  | Panel Name
+// | Editor  | Panel Name |
+// |---------|------------|
+// | VS Code | **Rust Dependencies** |
 //
-// | VS Code | **Rust Dependencies**
-// |===
-//
-// image::https://user-images.githubusercontent.com/5748995/229394139-2625beab-f4c9-484b-84ed-ad5dee0b1e1a.png[]
+// ![Show Dependency Tree](https://user-images.githubusercontent.com/5748995/229394139-2625beab-f4c9-484b-84ed-ad5dee0b1e1a.png)
 pub(crate) fn fetch_crates(db: &RootDatabase) -> FxIndexSet<CrateInfo> {
     let crate_graph = db.crate_graph();
     crate_graph
diff --git a/src/tools/rust-analyzer/crates/ide/src/file_structure.rs b/src/tools/rust-analyzer/crates/ide/src/file_structure.rs
index 50977ee840c..52fbab6fa12 100644
--- a/src/tools/rust-analyzer/crates/ide/src/file_structure.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/file_structure.rs
@@ -31,14 +31,11 @@ pub enum StructureNodeKind {
 // * draw breadcrumbs to describe the context around the cursor
 // * draw outline of the file
 //
-// |===
-// | Editor  | Shortcut
+// | Editor  | Shortcut |
+// |---------|----------|
+// | VS Code | <kbd>Ctrl+Shift+O</kbd> |
 //
-// | VS Code | kbd:[Ctrl+Shift+O]
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113020654-b42fc800-917a-11eb-8388-e7dc4d92b02e.gif[]
-
+// ![File Structure](https://user-images.githubusercontent.com/48062697/113020654-b42fc800-917a-11eb-8388-e7dc4d92b02e.gif)
 pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
     let mut res = Vec::new();
     let mut stack = Vec::new();
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index d18732a6b84..bdafb701ff5 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -31,13 +31,11 @@ use syntax::{
 //
 // For outline modules, this will navigate to the source file of the module.
 //
-// |===
-// | Editor  | Shortcut
+// | Editor  | Shortcut |
+// |---------|----------|
+// | VS Code | <kbd>F12</kbd> |
 //
-// | VS Code | kbd:[F12]
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif[]
+// ![Go to Definition](https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif)
 pub(crate) fn goto_definition(
     db: &RootDatabase,
     FilePosition { file_id, offset }: FilePosition,
@@ -3274,4 +3272,22 @@ fn f() {
         "#,
         );
     }
+
+    #[test]
+    fn use_inside_body() {
+        check(
+            r#"
+fn main() {
+    mod nice_module {
+        pub(super) struct NiceStruct;
+                       // ^^^^^^^^^^
+    }
+
+    use nice_module::NiceStruct$0;
+
+    let _ = NiceStruct;
+}
+    "#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
index e926378367e..e1d834b5d1c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
@@ -12,13 +12,11 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav};
 //
 // Navigates to the impl items of types.
 //
-// |===
-// | Editor  | Shortcut
+// | Editor  | Shortcut |
+// |---------|----------|
+// | VS Code | <kbd>Ctrl+F12</kbd>
 //
-// | VS Code | kbd:[Ctrl+F12]
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif[]
+// ![Go to Implementation](https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif)
 pub(crate) fn goto_implementation(
     db: &RootDatabase,
     FilePosition { file_id, offset }: FilePosition,
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
index 2610d6c8863..ddc274a8303 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
@@ -8,13 +8,11 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav};
 //
 // Navigates to the type of an identifier.
 //
-// |===
-// | Editor  | Action Name
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **Go to Type Definition** |
 //
-// | VS Code | **Go to Type Definition**
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif[]
+// ![Go to Type Definition](https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif)
 pub(crate) fn goto_type_definition(
     db: &RootDatabase,
     FilePosition { file_id, offset }: FilePosition,
diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
index 612bc36f628..6463206596a 100644
--- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
@@ -43,12 +43,12 @@ pub struct HighlightRelatedConfig {
 //
 // Highlights constructs related to the thing under the cursor:
 //
-// . if on an identifier, highlights all references to that identifier in the current file
-// .. additionally, if the identifier is a trait in a where clause, type parameter trait bound or use item, highlights all references to that trait's assoc items in the corresponding scope
-// . if on an `async` or `await` token, highlights all yield points for that async context
-// . if on a `return` or `fn` keyword, `?` character or `->` return type arrow, highlights all exit points for that context
-// . if on a `break`, `loop`, `while` or `for` token, highlights all break points for that loop or block context
-// . if on a `move` or `|` token that belongs to a closure, highlights all captures of the closure.
+// 1. if on an identifier, highlights all references to that identifier in the current file
+//      * additionally, if the identifier is a trait in a where clause, type parameter trait bound or use item, highlights all references to that trait's assoc items in the corresponding scope
+// 1. if on an `async` or `await` token, highlights all yield points for that async context
+// 1. if on a `return` or `fn` keyword, `?` character or `->` return type arrow, highlights all exit points for that context
+// 1. if on a `break`, `loop`, `while` or `for` token, highlights all break points for that loop or block context
+// 1. if on a `move` or `|` token that belongs to a closure, highlights all captures of the closure.
 //
 // Note: `?`, `|` and `->` do not currently trigger this behavior in the VSCode editor.
 pub(crate) fn highlight_related(
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 9d4c103fc2e..95a720e7e45 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -118,7 +118,7 @@ pub struct HoverResult {
 // Shows additional information, like the type of an expression or the documentation for a definition when "focusing" code.
 // Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
 //
-// image::https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif[]
+// ![Hover](https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif)
 pub(crate) fn hover(
     db: &RootDatabase,
     frange @ FileRange { file_id, range }: FileRange,
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index 40f3406b72d..c996230c3a1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -434,6 +434,7 @@ fn definition_owner_name(db: &RootDatabase, def: Definition, edition: Edition) -
                     None => it.name(db),
                 }
             }
+            hir::GenericDef::Static(it) => Some(it.name(db)),
         },
         Definition::DeriveHelper(derive_helper) => Some(derive_helper.derive().name(db)),
         d => {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
index 1f723c85df7..63039b1cd34 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -59,7 +59,7 @@ mod range_exclusive;
 //
 // Note: inlay hints for function argument names are heuristically omitted to reduce noise and will not appear if
 // any of the
-// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L92-L99[following criteria]
+// [following criteria](https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L92-L99)
 // are met:
 //
 // * the parameter name is a suffix of the function's name
@@ -68,13 +68,13 @@ mod range_exclusive;
 //   of argument with _ splitting it off
 // * the parameter name starts with `ra_fixture`
 // * the parameter name is a
-// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L200[well known name]
+// [well known name](https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L200)
 // in a unary function
 // * the parameter name is a
-// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L201[single character]
+// [single character](https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L201)
 // in a unary function
 //
-// image::https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png[]
+// ![Inlay hints](https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png)
 pub(crate) fn inlay_hints(
     db: &RootDatabase,
     file_id: FileId,
@@ -294,6 +294,7 @@ pub struct InlayHintsConfig {
     pub param_names_for_lifetime_elision_hints: bool,
     pub hide_named_constructor_hints: bool,
     pub hide_closure_initialization_hints: bool,
+    pub hide_closure_parameter_hints: bool,
     pub range_exclusive_hints: bool,
     pub closure_style: ClosureStyle,
     pub max_length: Option<usize>,
@@ -860,6 +861,7 @@ mod tests {
         binding_mode_hints: false,
         hide_named_constructor_hints: false,
         hide_closure_initialization_hints: false,
+        hide_closure_parameter_hints: false,
         closure_style: ClosureStyle::ImplFn,
         param_names_for_lifetime_elision_hints: false,
         max_length: None,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
index 2acd4021cc1..d3b95750f7e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
@@ -13,11 +13,7 @@ use ide_db::famous_defs::FamousDefs;
 
 use ide_db::text_edit::TextEditBuilder;
 use span::EditionedFileId;
-use stdx::never;
-use syntax::{
-    ast::{self, make, AstNode},
-    ted,
-};
+use syntax::ast::{self, prec::ExprPrecedence, AstNode};
 
 use crate::{
     AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintLabel, InlayHintLabelPart,
@@ -104,12 +100,14 @@ pub(super) fn hints(
     };
     let iter: &mut dyn Iterator<Item = _> = iter.as_mut().either(|it| it as _, |it| it as _);
 
+    let mut has_adjustments = false;
     let mut allow_edit = !postfix;
     for Adjustment { source, target, kind } in iter {
         if source == target {
             cov_mark::hit!(same_type_adjustment);
             continue;
         }
+        has_adjustments = true;
 
         // FIXME: Add some nicer tooltips to each of these
         let (text, coercion) = match kind {
@@ -172,6 +170,10 @@ pub(super) fn hints(
         };
         if postfix { &mut post } else { &mut pre }.label.append_part(label);
     }
+    if !has_adjustments {
+        return None;
+    }
+
     if !postfix && needs_inner_parens {
         pre.label.append_str("(");
     }
@@ -254,71 +256,31 @@ fn mode_and_needs_parens_for_adjustment_hints(
 /// Returns whatever we need to add parentheses on the inside and/or outside of `expr`,
 /// if we are going to add (`postfix`) adjustments hints to it.
 fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, bool) {
-    // This is a very miserable pile of hacks...
-    //
-    // `Expr::needs_parens_in` requires that the expression is the child of the other expression,
-    // that is supposed to be its parent.
-    //
-    // But we want to check what would happen if we add `*`/`.*` to the inner expression.
-    // To check for inner we need `` expr.needs_parens_in(`*expr`) ``,
-    // to check for outer we need `` `*expr`.needs_parens_in(parent) ``,
-    // where "expr" is the `expr` parameter, `*expr` is the edited `expr`,
-    // and "parent" is the parent of the original expression...
-    //
-    // For this we utilize mutable trees, which is a HACK, but it works.
-    //
-    // FIXME: comeup with a better API for `needs_parens_in`, so that we don't have to do *this*
-
-    // Make `&expr`/`expr?`
-    let dummy_expr = {
-        // `make::*` function go through a string, so they parse wrongly.
-        // for example `` make::expr_try(`|| a`) `` would result in a
-        // `|| (a?)` and not `(|| a)?`.
-        //
-        // Thus we need dummy parens to preserve the relationship we want.
-        // The parens are then simply ignored by the following code.
-        let dummy_paren = make::expr_paren(expr.clone());
-        if postfix {
-            make::expr_try(dummy_paren)
-        } else {
-            make::expr_ref(dummy_paren, false)
-        }
-    };
-
-    // Do the dark mutable tree magic.
-    // This essentially makes `dummy_expr` and `expr` switch places (families),
-    // so that `expr`'s parent is not `dummy_expr`'s parent.
-    let dummy_expr = dummy_expr.clone_for_update();
-    let expr = expr.clone_for_update();
-    ted::replace(expr.syntax(), dummy_expr.syntax());
-
-    let parent = dummy_expr.syntax().parent();
-    let Some(expr) = (|| {
-        if postfix {
-            let ast::Expr::TryExpr(e) = &dummy_expr else { return None };
-            let Some(ast::Expr::ParenExpr(e)) = e.expr() else { return None };
-
-            e.expr()
-        } else {
-            let ast::Expr::RefExpr(e) = &dummy_expr else { return None };
-            let Some(ast::Expr::ParenExpr(e)) = e.expr() else { return None };
-
-            e.expr()
-        }
-    })() else {
-        never!("broken syntax tree?\n{:?}\n{:?}", expr, dummy_expr);
-        return (true, true);
-    };
-
-    // At this point
-    // - `parent`     is the parent of the original expression
-    // - `dummy_expr` is the original expression wrapped in the operator we want (`*`/`.*`)
-    // - `expr`       is the clone of the original expression (with `dummy_expr` as the parent)
-
-    let needs_outer_parens = parent.is_some_and(|p| dummy_expr.needs_parens_in(p));
-    let needs_inner_parens = expr.needs_parens_in(dummy_expr.syntax().clone());
-
-    (needs_outer_parens, needs_inner_parens)
+    let prec = expr.precedence();
+    if postfix {
+        // postfix ops have higher precedence than any other operator, so we need to wrap
+        // any inner expression that is below (except for jumps if they don't have a value)
+        let needs_inner_parens = prec < ExprPrecedence::Unambiguous && {
+            prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value()
+        };
+        // given we are the higher precedence, no parent expression will have stronger requirements
+        let needs_outer_parens = false;
+        (needs_outer_parens, needs_inner_parens)
+    } else {
+        // We need to wrap all binary like things, thats everything below prefix except for jumps
+        let needs_inner_parens = prec < ExprPrecedence::Prefix && prec != ExprPrecedence::Jump;
+        let parent = expr
+            .syntax()
+            .parent()
+            .and_then(ast::Expr::cast)
+            // if we are already wrapped, great, no need to wrap again
+            .filter(|it| !matches!(it, ast::Expr::ParenExpr(_)))
+            .map(|it| it.precedence());
+        // if we have no parent, we don't need outer parens to disambiguate
+        // otherwise anything with higher precedence than what we insert needs to wrap us
+        let needs_outer_parens = parent.is_some_and(|prec| prec > ExprPrecedence::Prefix);
+        (needs_outer_parens, needs_inner_parens)
+    }
 }
 
 #[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
index 01a1a4545c4..c2986a9aa66 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
@@ -36,6 +36,9 @@ pub(super) fn hints(
                 if it.ty().is_some() {
                     return None;
                 }
+                if config.hide_closure_parameter_hints && it.syntax().ancestors().nth(2).is_none_or(|n| matches!(ast::Expr::cast(n), Some(ast::Expr::ClosureExpr(_)))) {
+                    return None;
+                }
                 Some(it.colon_token())
             },
             ast::LetStmt(it) => {
@@ -950,6 +953,36 @@ fn bar(f: impl FnOnce(u8) -> u8) -> impl FnOnce(u8) -> u8 {
     }
 
     #[test]
+    fn skip_closure_parameter_hints() {
+        check_with_config(
+            InlayHintsConfig {
+                type_hints: true,
+                hide_closure_parameter_hints: true,
+                ..DISABLED_CONFIG
+            },
+            r#"
+//- minicore: fn
+struct Foo;
+impl Foo {
+    fn foo(self: Self) {}
+    fn bar(self: &Self) {}
+}
+fn main() {
+    let closure = |x, y| x + y;
+    //  ^^^^^^^ impl Fn(i32, i32) -> {unknown}
+    closure(2, 3);
+    let point = (10, 20);
+    //  ^^^^^ (i32, i32)
+    let (x,      y) = point;
+      // ^ i32   ^ i32
+    Foo::foo(Foo);
+    Foo::bar(&Foo);
+}
+"#,
+        );
+    }
+
+    #[test]
     fn hint_truncation() {
         check_with_config(
             InlayHintsConfig { max_length: Some(8), ..TEST_CONFIG },
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs
index 3e91618d08e..9b981c0a3ac 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs
@@ -1,4 +1,4 @@
-//! Implementation of "closure return type" inlay hints.
+//! Implementation of "closure captures" inlay hints.
 //!
 //! Tests live in [`bind_pat`][super::bind_pat] module.
 use ide_db::famous_defs::FamousDefs;
diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs
index e0fdc3dd6f9..ae11072e34b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs
@@ -7,11 +7,9 @@ use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange};
 
 // Feature: Interpret A Function, Static Or Const.
 //
-// |===
-// | Editor  | Action Name
-//
-// | VS Code | **rust-analyzer: Interpret**
-// |===
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Interpret** |
 pub(crate) fn interpret(db: &RootDatabase, position: FilePosition) -> String {
     match find_and_interpret(db, position) {
         Some((duration, mut result)) => {
diff --git a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
index e4670177ecf..ea18a97070c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
@@ -21,17 +21,13 @@ pub struct JoinLinesConfig {
 //
 // Join selected lines into one, smartly fixing up whitespace, trailing commas, and braces.
 //
-// See
-// https://user-images.githubusercontent.com/1711539/124515923-4504e800-dde9-11eb-8d58-d97945a1a785.gif[this gif]
-// for the cases handled specially by joined lines.
+// See [this gif](https://user-images.githubusercontent.com/1711539/124515923-4504e800-dde9-11eb-8d58-d97945a1a785.gif) for the cases handled specially by joined lines.
 //
-// |===
-// | Editor  | Action Name
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Join lines** |
 //
-// | VS Code | **rust-analyzer: Join lines**
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113020661-b6922200-917a-11eb-87c4-b75acc028f11.gif[]
+// ![Join Lines](https://user-images.githubusercontent.com/48062697/113020661-b6922200-917a-11eb-87c4-b75acc028f11.gif)
 pub(crate) fn join_lines(
     config: &JoinLinesConfig,
     file: &SourceFile,
diff --git a/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs b/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
index 57356152836..67346ea9cf9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
@@ -9,13 +9,11 @@ use syntax::{
 // moves cursor to the matching brace. It uses the actual parser to determine
 // braces, so it won't confuse generics with comparisons.
 //
-// |===
-// | Editor  | Action Name
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Find matching brace** |
 //
-// | VS Code | **rust-analyzer: Find matching brace**
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113065573-04298180-91b1-11eb-8dec-d4e2a202f304.gif[]
+// ![Matching Brace](https://user-images.githubusercontent.com/48062697/113065573-04298180-91b1-11eb-8dec-d4e2a202f304.gif)
 pub(crate) fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> {
     const BRACES: &[SyntaxKind] =
         &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>], T![|], T![|]];
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index d97c12ebafb..66ea49a98a0 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -289,7 +289,10 @@ fn def_to_non_local_moniker(
     definition: Definition,
     from_crate: Crate,
 ) -> Option<Moniker> {
-    let module = definition.module(db)?;
+    let module = match definition {
+        Definition::Module(module) if module.is_crate_root() => module,
+        _ => definition.module(db)?,
+    };
     let krate = module.krate();
     let edition = krate.edition(db);
 
@@ -322,12 +325,18 @@ fn def_to_non_local_moniker(
                         name: name.display(db, edition).to_string(),
                         desc: def_to_kind(db, def).into(),
                     });
-                } else if reverse_description.is_empty() {
-                    // Don't allow the last descriptor to be absent.
-                    return None;
                 } else {
                     match def {
-                        Definition::Module(module) if module.is_crate_root() => {}
+                        Definition::Module(module) if module.is_crate_root() => {
+                            // only include `crate` namespace by itself because we prefer
+                            // `rust-analyzer cargo foo . bar/` over `rust-analyzer cargo foo . crate/bar/`
+                            if reverse_description.is_empty() {
+                                reverse_description.push(MonikerDescriptor {
+                                    name: "crate".to_owned(),
+                                    desc: MonikerDescriptorKind::Namespace,
+                                });
+                            }
+                        }
                         _ => {
                             tracing::error!(?def, "Encountered enclosing definition with no name");
                         }
@@ -340,6 +349,9 @@ fn def_to_non_local_moniker(
         };
         def = next_def;
     }
+    if reverse_description.is_empty() {
+        return None;
+    }
     reverse_description.reverse();
     let description = reverse_description;
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/move_item.rs b/src/tools/rust-analyzer/crates/ide/src/move_item.rs
index b0df9257ba1..3fb3a788b91 100644
--- a/src/tools/rust-analyzer/crates/ide/src/move_item.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/move_item.rs
@@ -17,14 +17,12 @@ pub enum Direction {
 //
 // Move item under cursor or selection up and down.
 //
-// |===
-// | Editor  | Action Name
-//
+// | Editor  | Action Name |
+// |---------|-------------|
 // | VS Code | **rust-analyzer: Move item up**
 // | VS Code | **rust-analyzer: Move item down**
-// |===
 //
-// image::https://user-images.githubusercontent.com/48062697/113065576-04298180-91b1-11eb-91ce-4505e99ed598.gif[]
+// ![Move Item](https://user-images.githubusercontent.com/48062697/113065576-04298180-91b1-11eb-91ce-4505e99ed598.gif)
 pub(crate) fn move_item(
     db: &RootDatabase,
     range: FileRange,
diff --git a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
index 7a0c28d925a..6d82f9b0634 100644
--- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
@@ -15,13 +15,11 @@ use crate::NavigationTarget;
 //
 // Navigates to the parent module of the current module.
 //
-// |===
-// | Editor  | Action Name
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Locate parent module** |
 //
-// | VS Code | **rust-analyzer: Locate parent module**
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113065580-04c21800-91b1-11eb-9a32-00086161c0bd.gif[]
+// ![Parent Module](https://user-images.githubusercontent.com/48062697/113065580-04c21800-91b1-11eb-9a32-00086161c0bd.gif)
 
 /// This returns `Vec` because a module may be included from several places.
 pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<NavigationTarget> {
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs
index b1079312d3b..069818d50e7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -43,13 +43,11 @@ pub struct Declaration {
 //
 // Shows all references of the item at the cursor location
 //
-// |===
-// | Editor  | Shortcut
+// | Editor  | Shortcut |
+// |---------|----------|
+// | VS Code | <kbd>Shift+Alt+F12</kbd> |
 //
-// | VS Code | kbd:[Shift+Alt+F12]
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113020670-b7c34f00-917a-11eb-8003-370ac5f2b3cb.gif[]
+// ![Find All References](https://user-images.githubusercontent.com/48062697/113020670-b7c34f00-917a-11eb-8003-370ac5f2b3cb.gif)
 pub(crate) fn find_all_refs(
     sema: &Semantics<'_, RootDatabase>,
     position: FilePosition,
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index 07dfd83c4eb..3e8295e3f08 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -71,13 +71,11 @@ pub(crate) fn prepare_rename(
 //
 // Renames the item below the cursor and all of its references
 //
-// |===
-// | Editor  | Shortcut
+// | Editor  | Shortcut |
+// |---------|----------|
+// | VS Code | <kbd>F2</kbd> |
 //
-// | VS Code | kbd:[F2]
-// |===
-//
-// image::https://user-images.githubusercontent.com/48062697/113065582-055aae80-91b1-11eb-8ade-2b58e6d81883.gif[]
+// ![Rename](https://user-images.githubusercontent.com/48062697/113065582-055aae80-91b1-11eb-8ade-2b58e6d81883.gif)
 pub(crate) fn rename(
     db: &RootDatabase,
     position: FilePosition,
@@ -2003,13 +2001,11 @@ impl Foo {
             "foo",
             r#"
 fn f($0self) -> i32 {
-    use self as _;
     self.i
 }
 "#,
             r#"
 fn f(foo: _) -> i32 {
-    use self as _;
     foo.i
 }
 "#,
@@ -2017,6 +2013,26 @@ fn f(foo: _) -> i32 {
     }
 
     #[test]
+    fn no_type_value_ns_confuse() {
+        // Test that we don't rename items from different namespaces.
+        check(
+            "bar",
+            r#"
+struct foo {}
+fn f(foo$0: i32) -> i32 {
+    use foo as _;
+}
+"#,
+            r#"
+struct foo {}
+fn f(bar: i32) -> i32 {
+    use foo as _;
+}
+"#,
+        );
+    }
+
+    #[test]
     fn test_self_in_path_to_parameter() {
         check(
             "foo",
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
index 32edacee51c..78c9f2309a0 100644
--- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -119,12 +119,11 @@ impl Runnable {
 // location**. Super useful for repeatedly running just a single test. Do bind this
 // to a shortcut!
 //
-// |===
-// | Editor  | Action Name
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Run** |
 //
-// | VS Code | **rust-analyzer: Run**
-// |===
-// image::https://user-images.githubusercontent.com/48062697/113065583-055aae80-91b1-11eb-958f-d67efcaf6a2f.gif[]
+// ![Run](https://user-images.githubusercontent.com/48062697/113065583-055aae80-91b1-11eb-958f-d67efcaf6a2f.gif)
 pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
     let sema = Semantics::new(db);
 
@@ -207,11 +206,9 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
 // The simplest way to use this feature is via the context menu. Right-click on
 // the selected item. The context menu opens. Select **Peek Related Tests**.
 //
-// |===
-// | Editor  | Action Name
-//
-// | VS Code | **rust-analyzer: Peek Related Tests**
-// |===
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Peek Related Tests** |
 pub(crate) fn related_tests(
     db: &RootDatabase,
     position: FilePosition,
diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
index f8c60418eb0..f9972116004 100644
--- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
@@ -321,7 +321,9 @@ fn signature_help_for_generics(
             format_to!(res.signature, "type {}", it.name(db).display(db, edition));
         }
         // These don't have generic args that can be specified
-        hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) => return None,
+        hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) | hir::GenericDef::Static(_) => {
+            return None
+        }
     }
 
     let params = generics_def.params(sema.db);
diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
index 8050a38b3ca..07553a87d28 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -154,6 +154,7 @@ impl StaticIndex<'_> {
                     implicit_drop_hints: false,
                     hide_named_constructor_hints: false,
                     hide_closure_initialization_hints: false,
+                    hide_closure_parameter_hints: false,
                     closure_style: hir::ClosureStyle::ImplFn,
                     param_names_for_lifetime_elision_hints: false,
                     binding_mode_hints: false,
@@ -169,10 +170,10 @@ impl StaticIndex<'_> {
             .unwrap();
         // hovers
         let sema = hir::Semantics::new(self.db);
-        let tokens_or_nodes = sema.parse_guess_edition(file_id).syntax().clone();
+        let root = sema.parse_guess_edition(file_id).syntax().clone();
         let edition =
             sema.attach_first_edition(file_id).map(|it| it.edition()).unwrap_or(Edition::CURRENT);
-        let tokens = tokens_or_nodes.descendants_with_tokens().filter_map(|it| match it {
+        let tokens = root.descendants_with_tokens().filter_map(|it| match it {
             syntax::NodeOrToken::Node(_) => None,
             syntax::NodeOrToken::Token(it) => Some(it),
         });
@@ -194,24 +195,19 @@ impl StaticIndex<'_> {
             )
         });
         let mut result = StaticIndexedFile { file_id, inlay_hints, folds, tokens: vec![] };
-        for token in tokens {
-            let range = token.text_range();
-            let node = token.parent().unwrap();
-            let def = match get_definition(&sema, token.clone()) {
-                Some(it) => it,
-                None => continue,
-            };
+
+        let mut add_token = |def: Definition, range: TextRange, scope_node: &SyntaxNode| {
             let id = if let Some(it) = self.def_map.get(&def) {
                 *it
             } else {
                 let it = self.tokens.insert(TokenStaticData {
-                    documentation: documentation_for_definition(&sema, def, &node),
+                    documentation: documentation_for_definition(&sema, def, scope_node),
                     hover: Some(hover_for_definition(
                         &sema,
                         file_id,
                         def,
                         None,
-                        &node,
+                        scope_node,
                         None,
                         false,
                         &hover_config,
@@ -240,6 +236,22 @@ impl StaticIndex<'_> {
                 },
             });
             result.tokens.push((range, id));
+        };
+
+        if let Some(module) = sema.file_to_module_def(file_id) {
+            let def = Definition::Module(module);
+            let range = root.text_range();
+            add_token(def, range, &root);
+        }
+
+        for token in tokens {
+            let range = token.text_range();
+            let node = token.parent().unwrap();
+            let def = match get_definition(&sema, token.clone()) {
+                Some(it) => it,
+                None => continue,
+            };
+            add_token(def, range, &node);
         }
         self.files.push(result);
     }
@@ -300,6 +312,10 @@ mod tests {
         let mut range_set: FxHashSet<_> = ranges.iter().map(|it| it.0).collect();
         for f in s.files {
             for (range, _) in f.tokens {
+                if range.start() == TextSize::from(0) {
+                    // ignore whole file range corresponding to module definition
+                    continue;
+                }
                 let it = FileRange { file_id: f.file_id, range };
                 if !range_set.contains(&it) {
                     panic!("additional range {it:?}");
diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs
index 9e823daa2be..b0022cfac76 100644
--- a/src/tools/rust-analyzer/crates/ide/src/status.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/status.rs
@@ -29,12 +29,11 @@ use triomphe::Arc;
 //
 // Shows internal statistic about memory usage of rust-analyzer.
 //
-// |===
-// | Editor  | Action Name
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Status** |
 //
-// | VS Code | **rust-analyzer: Status**
-// |===
-// image::https://user-images.githubusercontent.com/48062697/113065584-05f34500-91b1-11eb-98cc-5c196f76be7f.gif[]
+// ![Status](https://user-images.githubusercontent.com/48062697/113065584-05f34500-91b1-11eb-98cc-5c196f76be7f.gif)
 pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
     let mut buf = String::new();
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
index f53f0aec098..1853e3a3407 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
@@ -76,113 +76,118 @@ pub struct HighlightConfig {
 // We also give special modifier for `mut` and `&mut` local variables.
 //
 //
-// .Token Tags
+// #### Token Tags
 //
 // Rust-analyzer currently emits the following token tags:
 //
 // - For items:
-// +
-// [horizontal]
-// attribute:: Emitted for attribute macros.
-// enum:: Emitted for enums.
-// function:: Emitted for free-standing functions.
-// derive:: Emitted for derive macros.
-// macro:: Emitted for function-like macros.
-// method:: Emitted for associated functions, also knowns as methods.
-// namespace:: Emitted for modules.
-// struct:: Emitted for structs.
-// trait:: Emitted for traits.
-// typeAlias:: Emitted for type aliases and `Self` in `impl`s.
-// union:: Emitted for unions.
+//
+// |           |                                |
+// |-----------|--------------------------------|
+// | attribute |  Emitted for attribute macros. |
+// |enum| Emitted for enums. |
+// |function| Emitted for free-standing functions. |
+// |derive| Emitted for derive macros. |
+// |macro| Emitted for function-like macros. |
+// |method| Emitted for associated functions, also knowns as methods. |
+// |namespace| Emitted for modules. |
+// |struct| Emitted for structs.|
+// |trait| Emitted for traits.|
+// |typeAlias| Emitted for type aliases and `Self` in `impl`s.|
+// |union| Emitted for unions.|
 //
 // - For literals:
-// +
-// [horizontal]
-// boolean:: Emitted for the boolean literals `true` and `false`.
-// character:: Emitted for character literals.
-// number:: Emitted for numeric literals.
-// string:: Emitted for string literals.
-// escapeSequence:: Emitted for escaped sequences inside strings like `\n`.
-// formatSpecifier:: Emitted for format specifiers `{:?}` in `format!`-like macros.
+//
+// |           |                                |
+// |-----------|--------------------------------|
+// | boolean|  Emitted for the boolean literals `true` and `false`.|
+// | character| Emitted for character literals.|
+// | number| Emitted for numeric literals.|
+// | string| Emitted for string literals.|
+// | escapeSequence| Emitted for escaped sequences inside strings like `\n`.|
+// | formatSpecifier| Emitted for format specifiers `{:?}` in `format!`-like macros.|
 //
 // - For operators:
-// +
-// [horizontal]
-// operator:: Emitted for general operators.
-// arithmetic:: Emitted for the arithmetic operators `+`, `-`, `*`, `/`, `+=`, `-=`, `*=`, `/=`.
-// bitwise:: Emitted for the bitwise operators `|`, `&`, `!`, `^`, `|=`, `&=`, `^=`.
-// comparison:: Emitted for the comparison operators `>`, `<`, `==`, `>=`, `<=`, `!=`.
-// logical:: Emitted for the logical operators `||`, `&&`, `!`.
+//
+// |           |                                |
+// |-----------|--------------------------------|
+// |operator| Emitted for general operators.|
+// |arithmetic| Emitted for the arithmetic operators `+`, `-`, `*`, `/`, `+=`, `-=`, `*=`, `/=`.|
+// |bitwise| Emitted for the bitwise operators `|`, `&`, `!`, `^`, `|=`, `&=`, `^=`.|
+// |comparison| Emitted for the comparison oerators `>`, `<`, `==`, `>=`, `<=`, `!=`.|
+// |logical| Emitted for the logical operatos `||`, `&&`, `!`.|
 //
 // - For punctuation:
-// +
-// [horizontal]
-// punctuation:: Emitted for general punctuation.
-// attributeBracket:: Emitted for attribute invocation brackets, that is the `#[` and `]` tokens.
-// angle:: Emitted for `<>` angle brackets.
-// brace:: Emitted for `{}` braces.
-// bracket:: Emitted for `[]` brackets.
-// parenthesis:: Emitted for `()` parentheses.
-// colon:: Emitted for the `:` token.
-// comma:: Emitted for the `,` token.
-// dot:: Emitted for the `.` token.
-// semi:: Emitted for the `;` token.
-// macroBang:: Emitted for the `!` token in macro calls.
 //
-// //-
+// |           |                                |
+// |-----------|--------------------------------|
+// |punctuation| Emitted for general punctuation.|
+// |attributeBracket| Emitted for attribute invocation brackets, that is the `#[` and `]` tokens.|
+// |angle| Emitted for `<>` angle brackets.|
+// |brace| Emitted for `{}` braces.|
+// |bracket| Emitted for `[]` brackets.|
+// |parenthesis| Emitted for `()` parentheses.|
+// |colon| Emitted for the `:` token.|
+// |comma| Emitted for the `,` token.|
+// |dot| Emitted for the `.` token.|
+// |semi| Emitted for the `;` token.|
+// |macroBang| Emitted for the `!` token in macro calls.|
 //
-// [horizontal]
-// builtinAttribute:: Emitted for names to builtin attributes in attribute path, the `repr` in `#[repr(u8)]` for example.
-// builtinType:: Emitted for builtin types like `u32`, `str` and `f32`.
-// comment:: Emitted for comments.
-// constParameter:: Emitted for const parameters.
-// deriveHelper:: Emitted for derive helper attributes.
-// enumMember:: Emitted for enum variants.
-// generic:: Emitted for generic tokens that have no mapping.
-// keyword:: Emitted for keywords.
-// label:: Emitted for labels.
-// lifetime:: Emitted for lifetimes.
-// parameter:: Emitted for non-self function parameters.
-// property:: Emitted for struct and union fields.
-// selfKeyword:: Emitted for the self function parameter and self path-specifier.
-// selfTypeKeyword:: Emitted for the Self type parameter.
-// toolModule:: Emitted for tool modules.
-// typeParameter:: Emitted for type parameters.
-// unresolvedReference:: Emitted for unresolved references, names that rust-analyzer can't find the definition of.
-// variable:: Emitted for locals, constants and statics.
+//-
 //
+// |           |                                |
+// |-----------|--------------------------------|
+// |builtinAttribute| Emitted for names to builtin attributes in attribute path, the `repr` in `#[repr(u8)]` for example.|
+// |builtinType| Emitted for builtin types like `u32`, `str` and `f32`.|
+// |comment| Emitted for comments.|
+// |constParameter| Emitted for const parameters.|
+// |deriveHelper| Emitted for derive helper attributes.|
+// |enumMember| Emitted for enum variants.|
+// |generic| Emitted for generic tokens that have no mapping.|
+// |keyword| Emitted for keywords.|
+// |label| Emitted for labels.|
+// |lifetime| Emitted for lifetimes.|
+// |parameter| Emitted for non-self function parameters.|
+// |property| Emitted for struct and union fields.|
+// |selfKeyword| Emitted for the self function parameter and self path-specifier.|
+// |selfTypeKeyword| Emitted for the Self type parameter.|
+// |toolModule| Emitted for tool modules.|
+// |typeParameter| Emitted for type parameters.|
+// |unresolvedReference| Emitted for unresolved references, names that rust-analyzer can't find the definition of.|
+// |variable| Emitted for locals, constants and statics.|
 //
-// .Token Modifiers
+//
+// #### Token Modifiers
 //
 // Token modifiers allow to style some elements in the source code more precisely.
 //
 // Rust-analyzer currently emits the following token modifiers:
 //
-// [horizontal]
-// async:: Emitted for async functions and the `async` and `await` keywords.
-// attribute:: Emitted for tokens inside attributes.
-// callable:: Emitted for locals whose types implements one of the `Fn*` traits.
-// constant:: Emitted for consts.
-// consuming:: Emitted for locals that are being consumed when use in a function call.
-// controlFlow:: Emitted for control-flow related tokens, this includes the `?` operator.
-// crateRoot:: Emitted for crate names, like `serde` and `crate`.
-// declaration:: Emitted for names of definitions, like `foo` in `fn foo() {}`.
-// defaultLibrary:: Emitted for items from built-in crates (std, core, alloc, test and proc_macro).
-// documentation:: Emitted for documentation comments.
-// injected:: Emitted for doc-string injected highlighting like rust source blocks in documentation.
-// intraDocLink:: Emitted for intra doc links in doc-strings.
-// library:: Emitted for items that are defined outside of the current crate.
-// macro::  Emitted for tokens inside macro calls.
-// mutable:: Emitted for mutable locals and statics as well as functions taking `&mut self`.
-// public:: Emitted for items that are from the current crate and are `pub`.
-// reference:: Emitted for locals behind a reference and functions taking `self` by reference.
-// static:: Emitted for "static" functions, also known as functions that do not take a `self` param, as well as statics and consts.
-// trait:: Emitted for associated trait items.
-// unsafe:: Emitted for unsafe operations, like unsafe function calls, as well as the `unsafe` token.
-//
+// |           |                                |
+// |-----------|--------------------------------|
+// |async| Emitted for async functions and the `async` and `await` keywords.|
+// |attribute| Emitted for tokens inside attributes.|
+// |callable| Emitted for locals whose types implements one of the `Fn*` traits.|
+// |constant| Emitted for const.|
+// |consuming| Emitted for locals that are being consumed when use in a function call.|
+// |controlFlow| Emitted for control-flow related tokens, this includes th `?` operator.|
+// |crateRoot| Emitted for crate names, like `serde` and `crate.|
+// |declaration| Emitted for names of definitions, like `foo` in `fn foo(){}`.|
+// |defaultLibrary| Emitted for items from built-in crates (std, core, allc, test and proc_macro).|
+// |documentation| Emitted for documentation comment.|
+// |injected| Emitted for doc-string injected highlighting like rust source blocks in documentation.|
+// |intraDocLink| Emitted for intra doc links in doc-string.|
+// |library| Emitted for items that are defined outside of the current crae.|
+// |macro|  Emitted for tokens inside macro call.|
+// |mutable| Emitted for mutable locals and statics as well as functions taking `&mut self`.|
+// |public| Emitted for items that are from the current crate and are `pub.|
+// |reference| Emitted for locals behind a reference and functions taking self` by reference.|
+// |static| Emitted for "static" functions, also known as functions that d not take a `self` param, as well as statics and consts.|
+// |trait| Emitted for associated trait item.|
+// |unsafe| Emitted for unsafe operations, like unsafe function calls, as ell as the `unsafe` token.|
 //
-// image::https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png[]
-// image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[]
+// ![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png)
+// ![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png)
 pub(crate) fn highlight(
     db: &RootDatabase,
     config: HighlightConfig,
@@ -478,7 +483,15 @@ fn traverse(
                     {
                         continue;
                     }
-                    highlight_format_string(hl, sema, krate, &string, &expanded_string, range);
+                    highlight_format_string(
+                        hl,
+                        sema,
+                        krate,
+                        &string,
+                        &expanded_string,
+                        range,
+                        file_id.edition(),
+                    );
 
                     if !string.is_raw() {
                         highlight_escape_string(hl, &string, range.start());
@@ -526,6 +539,7 @@ fn traverse(
                 &mut bindings_shadow_count,
                 config.syntactic_name_ref_highlighting,
                 name_like,
+                file_id.edition(),
             ),
             NodeOrToken::Token(token) => {
                 highlight::token(sema, token, file_id.edition()).zip(Some(None))
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
index 7234108701a..43a6bdad7e9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
@@ -4,6 +4,7 @@ use ide_db::{
     syntax_helpers::format_string::{is_format_string, lex_format_specifiers, FormatSpecifier},
     SymbolKind,
 };
+use span::Edition;
 use syntax::{ast, TextRange};
 
 use crate::{
@@ -18,6 +19,7 @@ pub(super) fn highlight_format_string(
     string: &ast::String,
     expanded_string: &ast::String,
     range: TextRange,
+    edition: Edition,
 ) {
     if is_format_string(expanded_string) {
         // FIXME: Replace this with the HIR info we have now.
@@ -39,7 +41,7 @@ pub(super) fn highlight_format_string(
             if let Some(res) = res {
                 stack.add(HlRange {
                     range,
-                    highlight: highlight_def(sema, krate, Definition::from(res)),
+                    highlight: highlight_def(sema, krate, Definition::from(res), edition),
                     binding_hash: None,
                 })
             }
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
index 22a2fe4e9eb..479c0b381a4 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
@@ -58,6 +58,7 @@ pub(super) fn name_like(
     bindings_shadow_count: &mut FxHashMap<hir::Name, u32>,
     syntactic_name_ref_highlighting: bool,
     name_like: ast::NameLike,
+    edition: Edition,
 ) -> Option<(Highlight, Option<u64>)> {
     let mut binding_hash = None;
     let highlight = match name_like {
@@ -68,16 +69,17 @@ pub(super) fn name_like(
             &mut binding_hash,
             syntactic_name_ref_highlighting,
             name_ref,
+            edition,
         ),
         ast::NameLike::Name(name) => {
-            highlight_name(sema, bindings_shadow_count, &mut binding_hash, krate, name)
+            highlight_name(sema, bindings_shadow_count, &mut binding_hash, krate, name, edition)
         }
         ast::NameLike::Lifetime(lifetime) => match IdentClass::classify_lifetime(sema, &lifetime) {
             Some(IdentClass::NameClass(NameClass::Definition(def))) => {
-                highlight_def(sema, krate, def) | HlMod::Definition
+                highlight_def(sema, krate, def, edition) | HlMod::Definition
             }
             Some(IdentClass::NameRefClass(NameRefClass::Definition(def, _))) => {
-                highlight_def(sema, krate, def)
+                highlight_def(sema, krate, def, edition)
             }
             // FIXME: Fallback for 'static and '_, as we do not resolve these yet
             _ => SymbolKind::LifetimeParam.into(),
@@ -234,16 +236,17 @@ fn highlight_name_ref(
     binding_hash: &mut Option<u64>,
     syntactic_name_ref_highlighting: bool,
     name_ref: ast::NameRef,
+    edition: Edition,
 ) -> Highlight {
     let db = sema.db;
-    if let Some(res) = highlight_method_call_by_name_ref(sema, krate, &name_ref) {
+    if let Some(res) = highlight_method_call_by_name_ref(sema, krate, &name_ref, edition) {
         return res;
     }
 
     let name_class = match NameRefClass::classify(sema, &name_ref) {
         Some(name_kind) => name_kind,
         None if syntactic_name_ref_highlighting => {
-            return highlight_name_ref_by_syntax(name_ref, sema, krate)
+            return highlight_name_ref_by_syntax(name_ref, sema, krate, edition)
         }
         // FIXME: This is required for helper attributes used by proc-macros, as those do not map down
         // to anything when used.
@@ -267,7 +270,7 @@ fn highlight_name_ref(
                 *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
             };
 
-            let mut h = highlight_def(sema, krate, def);
+            let mut h = highlight_def(sema, krate, def, edition);
 
             match def {
                 Definition::Local(local) if is_consumed_lvalue(name_ref.syntax(), &local, db) => {
@@ -305,7 +308,7 @@ fn highlight_name_ref(
             h
         }
         NameRefClass::FieldShorthand { field_ref, .. } => {
-            highlight_def(sema, krate, field_ref.into())
+            highlight_def(sema, krate, field_ref.into(), edition)
         }
         NameRefClass::ExternCrateShorthand { decl, krate: resolved_krate } => {
             let mut h = HlTag::Symbol(SymbolKind::Module).into();
@@ -341,6 +344,7 @@ fn highlight_name(
     binding_hash: &mut Option<u64>,
     krate: hir::Crate,
     name: ast::Name,
+    edition: Edition,
 ) -> Highlight {
     let name_kind = NameClass::classify(sema, &name);
     if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind {
@@ -351,7 +355,7 @@ fn highlight_name(
     };
     match name_kind {
         Some(NameClass::Definition(def)) => {
-            let mut h = highlight_def(sema, krate, def) | HlMod::Definition;
+            let mut h = highlight_def(sema, krate, def, edition) | HlMod::Definition;
             if let Definition::Trait(trait_) = &def {
                 if trait_.is_unsafe(sema.db) {
                     h |= HlMod::Unsafe;
@@ -359,7 +363,7 @@ fn highlight_name(
             }
             h
         }
-        Some(NameClass::ConstReference(def)) => highlight_def(sema, krate, def),
+        Some(NameClass::ConstReference(def)) => highlight_def(sema, krate, def, edition),
         Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
             let mut h = HlTag::Symbol(SymbolKind::Field).into();
             if let hir::VariantDef::Union(_) = field_ref.parent_def(sema.db) {
@@ -379,6 +383,7 @@ pub(super) fn highlight_def(
     sema: &Semantics<'_, RootDatabase>,
     krate: hir::Crate,
     def: Definition,
+    edition: Edition,
 ) -> Highlight {
     let db = sema.db;
     let mut h = match def {
@@ -427,7 +432,12 @@ pub(super) fn highlight_def(
                 }
             }
 
-            if func.is_unsafe_to_call(db) {
+            // FIXME: Passing `None` here means not-unsafe functions with `#[target_feature]` will be
+            // highlighted as unsafe, even when the current target features set is a superset (RFC 2396).
+            // We probably should consider checking the current function, but I found no easy way to do
+            // that (also I'm worried about perf). There's also an instance below.
+            // FIXME: This should be the edition of the call.
+            if func.is_unsafe_to_call(db, None, edition) {
                 h |= HlMod::Unsafe;
             }
             if func.is_async(db) {
@@ -575,21 +585,23 @@ fn highlight_method_call_by_name_ref(
     sema: &Semantics<'_, RootDatabase>,
     krate: hir::Crate,
     name_ref: &ast::NameRef,
+    edition: Edition,
 ) -> Option<Highlight> {
     let mc = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?;
-    highlight_method_call(sema, krate, &mc)
+    highlight_method_call(sema, krate, &mc, edition)
 }
 
 fn highlight_method_call(
     sema: &Semantics<'_, RootDatabase>,
     krate: hir::Crate,
     method_call: &ast::MethodCallExpr,
+    edition: Edition,
 ) -> Option<Highlight> {
     let func = sema.resolve_method_call(method_call)?;
 
     let mut h = SymbolKind::Method.into();
 
-    if func.is_unsafe_to_call(sema.db) || sema.is_unsafe_method_call(method_call) {
+    if func.is_unsafe_to_call(sema.db, None, edition) || sema.is_unsafe_method_call(method_call) {
         h |= HlMod::Unsafe;
     }
     if func.is_async(sema.db) {
@@ -665,6 +677,12 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
         STATIC => SymbolKind::Static,
         IDENT_PAT => SymbolKind::Local,
         FORMAT_ARGS_ARG => SymbolKind::Local,
+        RENAME => SymbolKind::Local,
+        MACRO_RULES => SymbolKind::Macro,
+        CONST_PARAM => SymbolKind::ConstParam,
+        SELF_PARAM => SymbolKind::SelfParam,
+        TRAIT_ALIAS => SymbolKind::TraitAlias,
+        ASM_OPERAND_NAMED => SymbolKind::Local,
         _ => return default.into(),
     };
 
@@ -675,6 +693,7 @@ fn highlight_name_ref_by_syntax(
     name: ast::NameRef,
     sema: &Semantics<'_, RootDatabase>,
     krate: hir::Crate,
+    edition: Edition,
 ) -> Highlight {
     let default = HlTag::UnresolvedReference;
 
@@ -685,7 +704,7 @@ fn highlight_name_ref_by_syntax(
 
     match parent.kind() {
         METHOD_CALL_EXPR => ast::MethodCallExpr::cast(parent)
-            .and_then(|it| highlight_method_call(sema, krate, &it))
+            .and_then(|it| highlight_method_call(sema, krate, &it, edition))
             .unwrap_or_else(|| SymbolKind::Method.into()),
         FIELD_EXPR => {
             let h = HlTag::Symbol(SymbolKind::Field);
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index 0a7e273950d..1794d7dbfe2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -82,6 +82,10 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="parenthesis">(</span><span class="punctuation">$</span>literal<span class="colon">:</span>literal<span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span><span class="brace">{</span>stringify<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span>literal<span class="parenthesis">)</span><span class="semicolon">;</span> format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span>literal<span class="parenthesis">)</span><span class="brace">}</span><span class="brace">}</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
+<span class="keyword">use</span> <span class="unresolved_reference">foo</span><span class="operator">::</span><span class="unresolved_reference">bar</span> <span class="keyword">as</span> <span class="variable declaration">baz</span><span class="semicolon">;</span>
+<span class="keyword">trait</span> <span class="trait_alias declaration">Bar</span> <span class="operator">=</span> <span class="unresolved_reference">Baz</span><span class="semicolon">;</span>
+<span class="keyword">trait</span> <span class="trait_alias declaration">Foo</span> <span class="operator">=</span> <span class="trait_alias">Bar</span><span class="semicolon">;</span>
+
 <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
     <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'</span><span class="escape_sequence">\n</span><span class="char_literal">'</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'</span><span class="escape_sequence">\t</span><span class="char_literal">'</span><span class="semicolon">;</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
index af52b33de64..b9520ae2bba 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
@@ -466,6 +466,10 @@ macro_rules! reuse_twice {
     ($literal:literal) => {{stringify!($literal); format_args!($literal)}};
 }
 
+use foo::bar as baz;
+trait Bar = Baz;
+trait Foo = Bar;
+
 fn main() {
     let a = '\n';
     let a = '\t';
diff --git a/src/tools/rust-analyzer/crates/ide/src/typing.rs b/src/tools/rust-analyzer/crates/ide/src/typing.rs
index 47d75f1c957..8c9dd051452 100644
--- a/src/tools/rust-analyzer/crates/ide/src/typing.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/typing.rs
@@ -51,16 +51,15 @@ struct ExtendedTextEdit {
 // - typing `{` in a use item adds a closing `}` in the right place
 // - typing `>` to complete a return type `->` will insert a whitespace after it
 //
-// VS Code::
+// #### VS Code
 //
 // Add the following to `settings.json`:
-// [source,json]
-// ----
+// ```json
 // "editor.formatOnType": true,
-// ----
+// ```
 //
-// image::https://user-images.githubusercontent.com/48062697/113166163-69758500-923a-11eb-81ee-eb33ec380399.gif[]
-// image::https://user-images.githubusercontent.com/48062697/113171066-105c2000-923f-11eb-87ab-f4a263346567.gif[]
+// ![On Typing Assists](https://user-images.githubusercontent.com/48062697/113166163-69758500-923a-11eb-81ee-eb33ec380399.gif)
+// ![On Typing Assists](https://user-images.githubusercontent.com/48062697/113171066-105c2000-923f-11eb-87ab-f4a263346567.gif)
 pub(crate) fn on_char_typed(
     db: &RootDatabase,
     position: FilePosition,
diff --git a/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs b/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs
index e249c38c73d..c6d1c283f4e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs
@@ -16,12 +16,12 @@ use ide_db::text_edit::TextEdit;
 
 // Feature: On Enter
 //
-// rust-analyzer can override kbd:[Enter] key to make it smarter:
+// rust-analyzer can override <kbd>Enter</kbd> key to make it smarter:
 //
-// - kbd:[Enter] inside triple-slash comments automatically inserts `///`
-// - kbd:[Enter] in the middle or after a trailing space in `//` inserts `//`
-// - kbd:[Enter] inside `//!` doc comments automatically inserts `//!`
-// - kbd:[Enter] after `{` indents contents and closing `}` of single-line block
+// - <kbd>Enter</kbd> inside triple-slash comments automatically inserts `///`
+// - <kbd>Enter</kbd> in the middle or after a trailing space in `//` inserts `//`
+// - <kbd>Enter</kbd> inside `//!` doc comments automatically inserts `//!`
+// - <kbd>Enter</kbd> after `{` indents contents and closing `}` of single-line block
 //
 // This action needs to be assigned to shortcut explicitly.
 //
@@ -29,29 +29,27 @@ use ide_db::text_edit::TextEdit;
 // Similarly, if rust-analyzer crashes or stops responding, `Enter` might not work.
 // In that case, you can still press `Shift-Enter` to insert a newline.
 //
-// VS Code::
+// #### VS Code
 //
 // Add the following to `keybindings.json`:
-// [source,json]
-// ----
+// ```json
 // {
 //   "key": "Enter",
 //   "command": "rust-analyzer.onEnter",
 //   "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust"
 // }
-// ----
+// ````
 //
 // When using the Vim plugin:
-// [source,json]
-// ----
+// ```json
 // {
 //   "key": "Enter",
 //   "command": "rust-analyzer.onEnter",
 //   "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust && vim.mode == 'Insert'"
 // }
-// ----
+// ````
 //
-// image::https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif[]
+// ![On Enter](https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif)
 pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<TextEdit> {
     let parse = db.parse(EditionedFileId::current_edition(position.file_id));
     let file = parse.tree();
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
index 9ff099f479e..eb6eb7da1e9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
@@ -12,11 +12,9 @@ use triomphe::Arc;
 //
 // Only workspace crates are included, no crates.io dependencies or sysroot crates.
 //
-// |===
-// | Editor  | Action Name
-//
-// | VS Code | **rust-analyzer: View Crate Graph**
-// |===
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: View Crate Graph** |
 pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result<String, String> {
     let crate_graph = db.crate_graph();
     let crates_to_render = crate_graph
@@ -86,7 +84,8 @@ impl<'a> dot::Labeller<'a, CrateId, Edge<'a>> for DotCrateGraph {
     }
 
     fn node_label(&'a self, n: &CrateId) -> LabelText<'a> {
-        let name = self.graph[*n].display_name.as_ref().map_or("(unnamed crate)", |name| name);
+        let name =
+            self.graph[*n].display_name.as_ref().map_or("(unnamed crate)", |name| name.as_str());
         LabelText::LabelStr(name.into())
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
index fe532f4cc55..bfdf9d0f337 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
@@ -4,12 +4,11 @@ use syntax::{algo::ancestors_at_offset, ast, AstNode};
 
 // Feature: View Hir
 //
-// |===
-// | Editor  | Action Name
-//
+// | Editor  | Action Name |
+// |---------|--------------|
 // | VS Code | **rust-analyzer: View Hir**
-// |===
-// image::https://user-images.githubusercontent.com/48062697/113065588-068bdb80-91b1-11eb-9a78-0b4ef1e972fb.gif[]
+//
+// ![View Hir](https://user-images.githubusercontent.com/48062697/113065588-068bdb80-91b1-11eb-9a78-0b4ef1e972fb.gif)
 pub(crate) fn view_hir(db: &RootDatabase, position: FilePosition) -> String {
     body_hir(db, position).unwrap_or_else(|| "Not inside a function body".to_owned())
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
index a6352b99d4f..67c241cbb91 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
@@ -6,11 +6,9 @@ use span::EditionedFileId;
 //
 // Displays the ItemTree of the currently open file, for debugging.
 //
-// |===
-// | Editor  | Action Name
-//
-// | VS Code | **rust-analyzer: Debug ItemTree**
-// |===
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: Debug ItemTree** |
 pub(crate) fn view_item_tree(db: &RootDatabase, file_id: FileId) -> String {
     let sema = Semantics::new(db);
     let file_id = sema
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs
index ff74e05e943..edb83bc4eac 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs
@@ -75,11 +75,9 @@ impl FieldOrTupleIdx {
 //
 // Displays the recursive memory layout of a datatype.
 //
-// |===
-// | Editor  | Action Name
-//
-// | VS Code | **rust-analyzer: View Memory Layout**
-// |===
+// | Editor  | Action Name |
+// |---------|-------------|
+// | VS Code | **rust-analyzer: View Memory Layout** |
 pub(crate) fn view_memory_layout(
     db: &RootDatabase,
     position: FilePosition,
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_mir.rs b/src/tools/rust-analyzer/crates/ide/src/view_mir.rs
index 7a228375d5e..aa4ff64a819 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_mir.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_mir.rs
@@ -4,11 +4,9 @@ use syntax::{algo::ancestors_at_offset, ast, AstNode};
 
 // Feature: View Mir
 //
-// |===
-// | Editor  | Action Name
-//
+// | Editor  | Action Name |
+// |---------|-------------|
 // | VS Code | **rust-analyzer: View Mir**
-// |===
 pub(crate) fn view_mir(db: &RootDatabase, position: FilePosition) -> String {
     body_mir(db, position).unwrap_or_else(|| "Not inside a function body".to_owned())
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs b/src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs
index 218ee15a7dd..407720864bf 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_syntax_tree.rs
@@ -1,41 +1,50 @@
 use hir::Semantics;
-use ide_db::{FileId, RootDatabase};
-use span::TextRange;
+use ide_db::{
+    line_index::{LineCol, LineIndex},
+    FileId, LineIndexDatabase, RootDatabase,
+};
+use span::{TextRange, TextSize};
 use stdx::format_to;
 use syntax::{
     ast::{self, IsString},
     AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, WalkEvent,
 };
+use triomphe::Arc;
 
 // Feature: Show Syntax Tree
 //
 // Shows a tree view with the syntax tree of the current file
 //
-// |===
-// | Editor  | Panel Name
-//
-// | VS Code | **Rust Syntax Tree**
-// |===
+// | Editor  | Panel Name |
+// |---------|-------------|
+// | VS Code | **Rust Syntax Tree** |
 pub(crate) fn view_syntax_tree(db: &RootDatabase, file_id: FileId) -> String {
     let sema = Semantics::new(db);
+    let line_index = db.line_index(file_id);
     let parse = sema.parse_guess_edition(file_id);
-    syntax_node_to_json(parse.syntax(), None)
+
+    let ctx = SyntaxTreeCtx { line_index, in_string: None };
+
+    syntax_node_to_json(parse.syntax(), &ctx)
 }
 
-fn syntax_node_to_json(node: &SyntaxNode, ctx: Option<InStringCtx>) -> String {
+fn syntax_node_to_json(node: &SyntaxNode, ctx: &SyntaxTreeCtx) -> String {
     let mut result = String::new();
     for event in node.preorder_with_tokens() {
         match event {
             WalkEvent::Enter(it) => {
                 let kind = it.kind();
-                let (text_range, inner_range_str) = match &ctx {
-                    Some(ctx) => {
+                let (text_range, inner_range_str) = match &ctx.in_string {
+                    Some(in_string) => {
+                        let start_pos = TextPosition::new(&ctx.line_index, it.text_range().start());
+                        let end_pos = TextPosition::new(&ctx.line_index, it.text_range().end());
+
                         let inner_start: u32 = it.text_range().start().into();
-                        let inner_end: u32 = it.text_range().end().into();
+                        let inner_end: u32 = it.text_range().start().into();
 
-                        let mut true_start = inner_start + ctx.offset;
-                        let mut true_end = inner_end + ctx.offset;
-                        for pos in &ctx.marker_positions {
+                        let mut true_start = inner_start + in_string.offset;
+                        let mut true_end = inner_end + in_string.offset;
+                        for pos in &in_string.marker_positions {
                             if *pos >= inner_end {
                                 break;
                             }
@@ -48,39 +57,33 @@ fn syntax_node_to_json(node: &SyntaxNode, ctx: Option<InStringCtx>) -> String {
 
                         let true_range = TextRange::new(true_start.into(), true_end.into());
 
-                        (
-                            true_range,
-                            format!(
-                                r#","istart":{:?},"iend":{:?}"#,
-                                it.text_range().start(),
-                                it.text_range().end()
-                            ),
-                        )
+                        (true_range, format!(r#","istart":{start_pos},"iend":{end_pos}"#,))
                     }
                     None => (it.text_range(), "".to_owned()),
                 };
-                let start = text_range.start();
-                let end = text_range.end();
+
+                let start = TextPosition::new(&ctx.line_index, text_range.start());
+                let end = TextPosition::new(&ctx.line_index, text_range.end());
 
                 match it {
                     NodeOrToken::Node(_) => {
                         format_to!(
                             result,
-                            r#"{{"type":"Node","kind":"{kind:?}","start":{start:?},"end":{end:?}{inner_range_str},"children":["#
+                            r#"{{"type":"Node","kind":"{kind:?}","start":{start},"end":{end}{inner_range_str},"children":["#
                         );
                     }
                     NodeOrToken::Token(token) => {
                         let comma = if token.next_sibling_or_token().is_some() { "," } else { "" };
-                        match parse_rust_string(token) {
+                        match parse_rust_string(token, ctx) {
                             Some(parsed) => {
                                 format_to!(
                                     result,
-                                    r#"{{"type":"Node","kind":"{kind:?}","start":{start:?},"end":{end:?}{inner_range_str},"children":[{parsed}]}}{comma}"#
+                                    r#"{{"type":"Node","kind":"{kind:?}","start":{start},"end":{end}{inner_range_str},"children":[{parsed}]}}{comma}"#
                                 );
                             }
                             None => format_to!(
                                 result,
-                                r#"{{"type":"Token","kind":"{kind:?}","start":{start:?},"end":{end:?}{inner_range_str}}}{comma}"#
+                                r#"{{"type":"Token","kind":"{kind:?}","start":{start},"end":{end}{inner_range_str}}}{comma}"#
                             ),
                         }
                     }
@@ -99,7 +102,26 @@ fn syntax_node_to_json(node: &SyntaxNode, ctx: Option<InStringCtx>) -> String {
     result
 }
 
-fn parse_rust_string(token: SyntaxToken) -> Option<String> {
+struct TextPosition {
+    offset: TextSize,
+    line: u32,
+    col: u32,
+}
+
+impl std::fmt::Display for TextPosition {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "[{:?},{},{}]", self.offset, self.line, self.col)
+    }
+}
+
+impl TextPosition {
+    pub(crate) fn new(line_index: &LineIndex, offset: TextSize) -> Self {
+        let LineCol { line, col } = line_index.line_col(offset);
+        Self { offset, line, col }
+    }
+}
+
+fn parse_rust_string(token: SyntaxToken, ctx: &SyntaxTreeCtx) -> Option<String> {
     let string_node = ast::String::cast(token)?;
     let text = string_node.value().ok()?;
 
@@ -128,13 +150,20 @@ fn parse_rust_string(token: SyntaxToken) -> Option<String> {
         return None;
     }
 
-    Some(syntax_node_to_json(
-        node,
-        Some(InStringCtx {
+    let ctx = SyntaxTreeCtx {
+        line_index: ctx.line_index.clone(),
+        in_string: Some(InStringCtx {
             offset: string_node.text_range_between_quotes()?.start().into(),
             marker_positions,
         }),
-    ))
+    };
+
+    Some(syntax_node_to_json(node, &ctx))
+}
+
+struct SyntaxTreeCtx {
+    line_index: Arc<LineIndex>,
+    in_string: Option<InStringCtx>,
 }
 
 struct InStringCtx {
@@ -160,7 +189,7 @@ mod tests {
         check(
             r#"fn foo() {}"#,
             expect![[
-                r#"{"type":"Node","kind":"SOURCE_FILE","start":0,"end":11,"children":[{"type":"Node","kind":"FN","start":0,"end":11,"children":[{"type":"Token","kind":"FN_KW","start":0,"end":2},{"type":"Token","kind":"WHITESPACE","start":2,"end":3},{"type":"Node","kind":"NAME","start":3,"end":6,"children":[{"type":"Token","kind":"IDENT","start":3,"end":6}]},{"type":"Node","kind":"PARAM_LIST","start":6,"end":8,"children":[{"type":"Token","kind":"L_PAREN","start":6,"end":7},{"type":"Token","kind":"R_PAREN","start":7,"end":8}]},{"type":"Token","kind":"WHITESPACE","start":8,"end":9},{"type":"Node","kind":"BLOCK_EXPR","start":9,"end":11,"children":[{"type":"Node","kind":"STMT_LIST","start":9,"end":11,"children":[{"type":"Token","kind":"L_CURLY","start":9,"end":10},{"type":"Token","kind":"R_CURLY","start":10,"end":11}]}]}]}]}"#
+                r#"{"type":"Node","kind":"SOURCE_FILE","start":[0,0,0],"end":[11,0,11],"children":[{"type":"Node","kind":"FN","start":[0,0,0],"end":[11,0,11],"children":[{"type":"Token","kind":"FN_KW","start":[0,0,0],"end":[2,0,2]},{"type":"Token","kind":"WHITESPACE","start":[2,0,2],"end":[3,0,3]},{"type":"Node","kind":"NAME","start":[3,0,3],"end":[6,0,6],"children":[{"type":"Token","kind":"IDENT","start":[3,0,3],"end":[6,0,6]}]},{"type":"Node","kind":"PARAM_LIST","start":[6,0,6],"end":[8,0,8],"children":[{"type":"Token","kind":"L_PAREN","start":[6,0,6],"end":[7,0,7]},{"type":"Token","kind":"R_PAREN","start":[7,0,7],"end":[8,0,8]}]},{"type":"Token","kind":"WHITESPACE","start":[8,0,8],"end":[9,0,9]},{"type":"Node","kind":"BLOCK_EXPR","start":[9,0,9],"end":[11,0,11],"children":[{"type":"Node","kind":"STMT_LIST","start":[9,0,9],"end":[11,0,11],"children":[{"type":"Token","kind":"L_CURLY","start":[9,0,9],"end":[10,0,10]},{"type":"Token","kind":"R_CURLY","start":[10,0,10],"end":[11,0,11]}]}]}]}]}"#
             ]],
         );
 
@@ -173,7 +202,7 @@ fn test() {
     ", "");
 }"#,
             expect![[
-                r#"{"type":"Node","kind":"SOURCE_FILE","start":0,"end":60,"children":[{"type":"Node","kind":"FN","start":0,"end":60,"children":[{"type":"Token","kind":"FN_KW","start":0,"end":2},{"type":"Token","kind":"WHITESPACE","start":2,"end":3},{"type":"Node","kind":"NAME","start":3,"end":7,"children":[{"type":"Token","kind":"IDENT","start":3,"end":7}]},{"type":"Node","kind":"PARAM_LIST","start":7,"end":9,"children":[{"type":"Token","kind":"L_PAREN","start":7,"end":8},{"type":"Token","kind":"R_PAREN","start":8,"end":9}]},{"type":"Token","kind":"WHITESPACE","start":9,"end":10},{"type":"Node","kind":"BLOCK_EXPR","start":10,"end":60,"children":[{"type":"Node","kind":"STMT_LIST","start":10,"end":60,"children":[{"type":"Token","kind":"L_CURLY","start":10,"end":11},{"type":"Token","kind":"WHITESPACE","start":11,"end":16},{"type":"Node","kind":"EXPR_STMT","start":16,"end":58,"children":[{"type":"Node","kind":"MACRO_EXPR","start":16,"end":57,"children":[{"type":"Node","kind":"MACRO_CALL","start":16,"end":57,"children":[{"type":"Node","kind":"PATH","start":16,"end":22,"children":[{"type":"Node","kind":"PATH_SEGMENT","start":16,"end":22,"children":[{"type":"Node","kind":"NAME_REF","start":16,"end":22,"children":[{"type":"Token","kind":"IDENT","start":16,"end":22}]}]}]},{"type":"Token","kind":"BANG","start":22,"end":23},{"type":"Node","kind":"TOKEN_TREE","start":23,"end":57,"children":[{"type":"Token","kind":"L_PAREN","start":23,"end":24},{"type":"Node","kind":"STRING","start":24,"end":52,"children":[{"type":"Node","kind":"SOURCE_FILE","start":25,"end":51,"istart":0,"iend":26,"children":[{"type":"Token","kind":"WHITESPACE","start":25,"end":30,"istart":0,"iend":5},{"type":"Node","kind":"FN","start":30,"end":46,"istart":5,"iend":21,"children":[{"type":"Token","kind":"FN_KW","start":30,"end":32,"istart":5,"iend":7},{"type":"Token","kind":"WHITESPACE","start":32,"end":33,"istart":7,"iend":8},{"type":"Node","kind":"NAME","start":33,"end":36,"istart":8,"iend":11,"children":[{"type":"Token","kind":"IDENT","start":33,"end":36,"istart":8,"iend":11}]},{"type":"Node","kind":"PARAM_LIST","start":36,"end":38,"istart":11,"iend":13,"children":[{"type":"Token","kind":"L_PAREN","start":36,"end":37,"istart":11,"iend":12},{"type":"Token","kind":"R_PAREN","start":37,"end":38,"istart":12,"iend":13}]},{"type":"Token","kind":"WHITESPACE","start":38,"end":39,"istart":13,"iend":14},{"type":"Node","kind":"BLOCK_EXPR","start":39,"end":46,"istart":14,"iend":21,"children":[{"type":"Node","kind":"STMT_LIST","start":39,"end":46,"istart":14,"iend":21,"children":[{"type":"Token","kind":"L_CURLY","start":39,"end":40,"istart":14,"iend":15},{"type":"Token","kind":"WHITESPACE","start":40,"end":45,"istart":15,"iend":20},{"type":"Token","kind":"R_CURLY","start":45,"end":46,"istart":20,"iend":21}]}]}]},{"type":"Token","kind":"WHITESPACE","start":46,"end":51,"istart":21,"iend":26}]}]},{"type":"Token","kind":"COMMA","start":52,"end":53},{"type":"Token","kind":"WHITESPACE","start":53,"end":54},{"type":"Token","kind":"STRING","start":54,"end":56},{"type":"Token","kind":"R_PAREN","start":56,"end":57}]}]}]},{"type":"Token","kind":"SEMICOLON","start":57,"end":58}]},{"type":"Token","kind":"WHITESPACE","start":58,"end":59},{"type":"Token","kind":"R_CURLY","start":59,"end":60}]}]}]}]}"#
+                r#"{"type":"Node","kind":"SOURCE_FILE","start":[0,0,0],"end":[60,5,1],"children":[{"type":"Node","kind":"FN","start":[0,0,0],"end":[60,5,1],"children":[{"type":"Token","kind":"FN_KW","start":[0,0,0],"end":[2,0,2]},{"type":"Token","kind":"WHITESPACE","start":[2,0,2],"end":[3,0,3]},{"type":"Node","kind":"NAME","start":[3,0,3],"end":[7,0,7],"children":[{"type":"Token","kind":"IDENT","start":[3,0,3],"end":[7,0,7]}]},{"type":"Node","kind":"PARAM_LIST","start":[7,0,7],"end":[9,0,9],"children":[{"type":"Token","kind":"L_PAREN","start":[7,0,7],"end":[8,0,8]},{"type":"Token","kind":"R_PAREN","start":[8,0,8],"end":[9,0,9]}]},{"type":"Token","kind":"WHITESPACE","start":[9,0,9],"end":[10,0,10]},{"type":"Node","kind":"BLOCK_EXPR","start":[10,0,10],"end":[60,5,1],"children":[{"type":"Node","kind":"STMT_LIST","start":[10,0,10],"end":[60,5,1],"children":[{"type":"Token","kind":"L_CURLY","start":[10,0,10],"end":[11,0,11]},{"type":"Token","kind":"WHITESPACE","start":[11,0,11],"end":[16,1,4]},{"type":"Node","kind":"EXPR_STMT","start":[16,1,4],"end":[58,4,11],"children":[{"type":"Node","kind":"MACRO_EXPR","start":[16,1,4],"end":[57,4,10],"children":[{"type":"Node","kind":"MACRO_CALL","start":[16,1,4],"end":[57,4,10],"children":[{"type":"Node","kind":"PATH","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Node","kind":"PATH_SEGMENT","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Node","kind":"NAME_REF","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Token","kind":"IDENT","start":[16,1,4],"end":[22,1,10]}]}]}]},{"type":"Token","kind":"BANG","start":[22,1,10],"end":[23,1,11]},{"type":"Node","kind":"TOKEN_TREE","start":[23,1,11],"end":[57,4,10],"children":[{"type":"Token","kind":"L_PAREN","start":[23,1,11],"end":[24,1,12]},{"type":"Node","kind":"STRING","start":[24,1,12],"end":[52,4,5],"children":[{"type":"Node","kind":"SOURCE_FILE","start":[25,1,13],"end":[25,1,13],"istart":[0,0,0],"iend":[26,2,0],"children":[{"type":"Token","kind":"WHITESPACE","start":[25,1,13],"end":[25,1,13],"istart":[0,0,0],"iend":[5,0,5]},{"type":"Node","kind":"FN","start":[30,2,4],"end":[30,2,4],"istart":[5,0,5],"iend":[21,1,9],"children":[{"type":"Token","kind":"FN_KW","start":[30,2,4],"end":[30,2,4],"istart":[5,0,5],"iend":[7,0,7]},{"type":"Token","kind":"WHITESPACE","start":[32,2,6],"end":[32,2,6],"istart":[7,0,7],"iend":[8,0,8]},{"type":"Node","kind":"NAME","start":[33,2,7],"end":[33,2,7],"istart":[8,0,8],"iend":[11,0,11],"children":[{"type":"Token","kind":"IDENT","start":[33,2,7],"end":[33,2,7],"istart":[8,0,8],"iend":[11,0,11]}]},{"type":"Node","kind":"PARAM_LIST","start":[36,2,10],"end":[36,2,10],"istart":[11,0,11],"iend":[13,1,1],"children":[{"type":"Token","kind":"L_PAREN","start":[36,2,10],"end":[36,2,10],"istart":[11,0,11],"iend":[12,1,0]},{"type":"Token","kind":"R_PAREN","start":[37,2,11],"end":[37,2,11],"istart":[12,1,0],"iend":[13,1,1]}]},{"type":"Token","kind":"WHITESPACE","start":[38,2,12],"end":[38,2,12],"istart":[13,1,1],"iend":[14,1,2]},{"type":"Node","kind":"BLOCK_EXPR","start":[39,2,13],"end":[39,2,13],"istart":[14,1,2],"iend":[21,1,9],"children":[{"type":"Node","kind":"STMT_LIST","start":[39,2,13],"end":[39,2,13],"istart":[14,1,2],"iend":[21,1,9],"children":[{"type":"Token","kind":"L_CURLY","start":[39,2,13],"end":[39,2,13],"istart":[14,1,2],"iend":[15,1,3]},{"type":"Token","kind":"WHITESPACE","start":[40,2,14],"end":[40,2,14],"istart":[15,1,3],"iend":[20,1,8]},{"type":"Token","kind":"R_CURLY","start":[45,3,4],"end":[45,3,4],"istart":[20,1,8],"iend":[21,1,9]}]}]}]},{"type":"Token","kind":"WHITESPACE","start":[46,3,5],"end":[46,3,5],"istart":[21,1,9],"iend":[26,2,0]}]}]},{"type":"Token","kind":"COMMA","start":[52,4,5],"end":[53,4,6]},{"type":"Token","kind":"WHITESPACE","start":[53,4,6],"end":[54,4,7]},{"type":"Token","kind":"STRING","start":[54,4,7],"end":[56,4,9]},{"type":"Token","kind":"R_PAREN","start":[56,4,9],"end":[57,4,10]}]}]}]},{"type":"Token","kind":"SEMICOLON","start":[57,4,10],"end":[58,4,11]}]},{"type":"Token","kind":"WHITESPACE","start":[58,4,11],"end":[59,5,0]},{"type":"Token","kind":"R_CURLY","start":[59,5,0],"end":[60,5,1]}]}]}]}]}"#
             ]],
         )
     }
@@ -190,7 +219,7 @@ fn bar() {
     ", "");
 }"#,
             expect![[
-                r#"{"type":"Node","kind":"SOURCE_FILE","start":0,"end":65,"children":[{"type":"Node","kind":"FN","start":0,"end":65,"children":[{"type":"Token","kind":"FN_KW","start":0,"end":2},{"type":"Token","kind":"WHITESPACE","start":2,"end":3},{"type":"Node","kind":"NAME","start":3,"end":7,"children":[{"type":"Token","kind":"IDENT","start":3,"end":7}]},{"type":"Node","kind":"PARAM_LIST","start":7,"end":9,"children":[{"type":"Token","kind":"L_PAREN","start":7,"end":8},{"type":"Token","kind":"R_PAREN","start":8,"end":9}]},{"type":"Token","kind":"WHITESPACE","start":9,"end":10},{"type":"Node","kind":"BLOCK_EXPR","start":10,"end":65,"children":[{"type":"Node","kind":"STMT_LIST","start":10,"end":65,"children":[{"type":"Token","kind":"L_CURLY","start":10,"end":11},{"type":"Token","kind":"WHITESPACE","start":11,"end":16},{"type":"Node","kind":"EXPR_STMT","start":16,"end":63,"children":[{"type":"Node","kind":"MACRO_EXPR","start":16,"end":62,"children":[{"type":"Node","kind":"MACRO_CALL","start":16,"end":62,"children":[{"type":"Node","kind":"PATH","start":16,"end":22,"children":[{"type":"Node","kind":"PATH_SEGMENT","start":16,"end":22,"children":[{"type":"Node","kind":"NAME_REF","start":16,"end":22,"children":[{"type":"Token","kind":"IDENT","start":16,"end":22}]}]}]},{"type":"Token","kind":"BANG","start":22,"end":23},{"type":"Node","kind":"TOKEN_TREE","start":23,"end":62,"children":[{"type":"Token","kind":"L_PAREN","start":23,"end":24},{"type":"Node","kind":"STRING","start":24,"end":57,"children":[{"type":"Node","kind":"SOURCE_FILE","start":25,"end":56,"istart":0,"iend":31,"children":[{"type":"Token","kind":"WHITESPACE","start":25,"end":26,"istart":0,"iend":1},{"type":"Node","kind":"FN","start":26,"end":38,"istart":1,"iend":13,"children":[{"type":"Token","kind":"FN_KW","start":26,"end":28,"istart":1,"iend":3},{"type":"Token","kind":"WHITESPACE","start":28,"end":29,"istart":3,"iend":4},{"type":"Node","kind":"NAME","start":29,"end":32,"istart":4,"iend":7,"children":[{"type":"Token","kind":"IDENT","start":29,"end":32,"istart":4,"iend":7}]},{"type":"Node","kind":"PARAM_LIST","start":32,"end":34,"istart":7,"iend":9,"children":[{"type":"Token","kind":"L_PAREN","start":32,"end":33,"istart":7,"iend":8},{"type":"Token","kind":"R_PAREN","start":33,"end":34,"istart":8,"iend":9}]},{"type":"Token","kind":"WHITESPACE","start":34,"end":35,"istart":9,"iend":10},{"type":"Node","kind":"BLOCK_EXPR","start":35,"end":38,"istart":10,"iend":13,"children":[{"type":"Node","kind":"STMT_LIST","start":35,"end":38,"istart":10,"iend":13,"children":[{"type":"Token","kind":"L_CURLY","start":35,"end":36,"istart":10,"iend":11},{"type":"Token","kind":"WHITESPACE","start":36,"end":37,"istart":11,"iend":12},{"type":"Token","kind":"R_CURLY","start":37,"end":38,"istart":12,"iend":13}]}]}]},{"type":"Token","kind":"WHITESPACE","start":38,"end":39,"istart":13,"iend":14},{"type":"Node","kind":"FN","start":39,"end":51,"istart":14,"iend":26,"children":[{"type":"Token","kind":"FN_KW","start":39,"end":41,"istart":14,"iend":16},{"type":"Token","kind":"WHITESPACE","start":41,"end":42,"istart":16,"iend":17},{"type":"Node","kind":"NAME","start":42,"end":45,"istart":17,"iend":20,"children":[{"type":"Token","kind":"IDENT","start":42,"end":45,"istart":17,"iend":20}]},{"type":"Node","kind":"PARAM_LIST","start":45,"end":47,"istart":20,"iend":22,"children":[{"type":"Token","kind":"L_PAREN","start":45,"end":46,"istart":20,"iend":21},{"type":"Token","kind":"R_PAREN","start":46,"end":47,"istart":21,"iend":22}]},{"type":"Token","kind":"WHITESPACE","start":47,"end":48,"istart":22,"iend":23},{"type":"Node","kind":"BLOCK_EXPR","start":48,"end":51,"istart":23,"iend":26,"children":[{"type":"Node","kind":"STMT_LIST","start":48,"end":51,"istart":23,"iend":26,"children":[{"type":"Token","kind":"L_CURLY","start":48,"end":49,"istart":23,"iend":24},{"type":"Token","kind":"WHITESPACE","start":49,"end":50,"istart":24,"iend":25},{"type":"Token","kind":"R_CURLY","start":50,"end":51,"istart":25,"iend":26}]}]}]},{"type":"Token","kind":"WHITESPACE","start":51,"end":56,"istart":26,"iend":31}]}]},{"type":"Token","kind":"COMMA","start":57,"end":58},{"type":"Token","kind":"WHITESPACE","start":58,"end":59},{"type":"Token","kind":"STRING","start":59,"end":61},{"type":"Token","kind":"R_PAREN","start":61,"end":62}]}]}]},{"type":"Token","kind":"SEMICOLON","start":62,"end":63}]},{"type":"Token","kind":"WHITESPACE","start":63,"end":64},{"type":"Token","kind":"R_CURLY","start":64,"end":65}]}]}]}]}"#
+                r#"{"type":"Node","kind":"SOURCE_FILE","start":[0,0,0],"end":[65,7,1],"children":[{"type":"Node","kind":"FN","start":[0,0,0],"end":[65,7,1],"children":[{"type":"Token","kind":"FN_KW","start":[0,0,0],"end":[2,0,2]},{"type":"Token","kind":"WHITESPACE","start":[2,0,2],"end":[3,0,3]},{"type":"Node","kind":"NAME","start":[3,0,3],"end":[7,0,7],"children":[{"type":"Token","kind":"IDENT","start":[3,0,3],"end":[7,0,7]}]},{"type":"Node","kind":"PARAM_LIST","start":[7,0,7],"end":[9,0,9],"children":[{"type":"Token","kind":"L_PAREN","start":[7,0,7],"end":[8,0,8]},{"type":"Token","kind":"R_PAREN","start":[8,0,8],"end":[9,0,9]}]},{"type":"Token","kind":"WHITESPACE","start":[9,0,9],"end":[10,0,10]},{"type":"Node","kind":"BLOCK_EXPR","start":[10,0,10],"end":[65,7,1],"children":[{"type":"Node","kind":"STMT_LIST","start":[10,0,10],"end":[65,7,1],"children":[{"type":"Token","kind":"L_CURLY","start":[10,0,10],"end":[11,0,11]},{"type":"Token","kind":"WHITESPACE","start":[11,0,11],"end":[16,1,4]},{"type":"Node","kind":"EXPR_STMT","start":[16,1,4],"end":[63,6,11],"children":[{"type":"Node","kind":"MACRO_EXPR","start":[16,1,4],"end":[62,6,10],"children":[{"type":"Node","kind":"MACRO_CALL","start":[16,1,4],"end":[62,6,10],"children":[{"type":"Node","kind":"PATH","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Node","kind":"PATH_SEGMENT","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Node","kind":"NAME_REF","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Token","kind":"IDENT","start":[16,1,4],"end":[22,1,10]}]}]}]},{"type":"Token","kind":"BANG","start":[22,1,10],"end":[23,1,11]},{"type":"Node","kind":"TOKEN_TREE","start":[23,1,11],"end":[62,6,10],"children":[{"type":"Token","kind":"L_PAREN","start":[23,1,11],"end":[24,1,12]},{"type":"Node","kind":"STRING","start":[24,1,12],"end":[57,6,5],"children":[{"type":"Node","kind":"SOURCE_FILE","start":[25,1,13],"end":[25,1,13],"istart":[0,0,0],"iend":[31,2,5],"children":[{"type":"Token","kind":"WHITESPACE","start":[25,1,13],"end":[25,1,13],"istart":[0,0,0],"iend":[1,0,1]},{"type":"Node","kind":"FN","start":[26,2,0],"end":[26,2,0],"istart":[1,0,1],"iend":[13,1,1],"children":[{"type":"Token","kind":"FN_KW","start":[26,2,0],"end":[26,2,0],"istart":[1,0,1],"iend":[3,0,3]},{"type":"Token","kind":"WHITESPACE","start":[28,2,2],"end":[28,2,2],"istart":[3,0,3],"iend":[4,0,4]},{"type":"Node","kind":"NAME","start":[29,2,3],"end":[29,2,3],"istart":[4,0,4],"iend":[7,0,7],"children":[{"type":"Token","kind":"IDENT","start":[29,2,3],"end":[29,2,3],"istart":[4,0,4],"iend":[7,0,7]}]},{"type":"Node","kind":"PARAM_LIST","start":[32,2,6],"end":[32,2,6],"istart":[7,0,7],"iend":[9,0,9],"children":[{"type":"Token","kind":"L_PAREN","start":[32,2,6],"end":[32,2,6],"istart":[7,0,7],"iend":[8,0,8]},{"type":"Token","kind":"R_PAREN","start":[33,2,7],"end":[33,2,7],"istart":[8,0,8],"iend":[9,0,9]}]},{"type":"Token","kind":"WHITESPACE","start":[34,2,8],"end":[34,2,8],"istart":[9,0,9],"iend":[10,0,10]},{"type":"Node","kind":"BLOCK_EXPR","start":[35,2,9],"end":[35,2,9],"istart":[10,0,10],"iend":[13,1,1],"children":[{"type":"Node","kind":"STMT_LIST","start":[35,2,9],"end":[35,2,9],"istart":[10,0,10],"iend":[13,1,1],"children":[{"type":"Token","kind":"L_CURLY","start":[35,2,9],"end":[35,2,9],"istart":[10,0,10],"iend":[11,0,11]},{"type":"Token","kind":"WHITESPACE","start":[36,2,10],"end":[36,2,10],"istart":[11,0,11],"iend":[12,1,0]},{"type":"Token","kind":"R_CURLY","start":[37,3,0],"end":[37,3,0],"istart":[12,1,0],"iend":[13,1,1]}]}]}]},{"type":"Token","kind":"WHITESPACE","start":[38,3,1],"end":[38,3,1],"istart":[13,1,1],"iend":[14,1,2]},{"type":"Node","kind":"FN","start":[39,4,0],"end":[39,4,0],"istart":[14,1,2],"iend":[26,2,0],"children":[{"type":"Token","kind":"FN_KW","start":[39,4,0],"end":[39,4,0],"istart":[14,1,2],"iend":[16,1,4]},{"type":"Token","kind":"WHITESPACE","start":[41,4,2],"end":[41,4,2],"istart":[16,1,4],"iend":[17,1,5]},{"type":"Node","kind":"NAME","start":[42,4,3],"end":[42,4,3],"istart":[17,1,5],"iend":[20,1,8],"children":[{"type":"Token","kind":"IDENT","start":[42,4,3],"end":[42,4,3],"istart":[17,1,5],"iend":[20,1,8]}]},{"type":"Node","kind":"PARAM_LIST","start":[45,4,6],"end":[45,4,6],"istart":[20,1,8],"iend":[22,1,10],"children":[{"type":"Token","kind":"L_PAREN","start":[45,4,6],"end":[45,4,6],"istart":[20,1,8],"iend":[21,1,9]},{"type":"Token","kind":"R_PAREN","start":[46,4,7],"end":[46,4,7],"istart":[21,1,9],"iend":[22,1,10]}]},{"type":"Token","kind":"WHITESPACE","start":[47,4,8],"end":[47,4,8],"istart":[22,1,10],"iend":[23,1,11]},{"type":"Node","kind":"BLOCK_EXPR","start":[48,4,9],"end":[48,4,9],"istart":[23,1,11],"iend":[26,2,0],"children":[{"type":"Node","kind":"STMT_LIST","start":[48,4,9],"end":[48,4,9],"istart":[23,1,11],"iend":[26,2,0],"children":[{"type":"Token","kind":"L_CURLY","start":[48,4,9],"end":[48,4,9],"istart":[23,1,11],"iend":[24,1,12]},{"type":"Token","kind":"WHITESPACE","start":[49,4,10],"end":[49,4,10],"istart":[24,1,12],"iend":[25,1,13]},{"type":"Token","kind":"R_CURLY","start":[50,5,0],"end":[50,5,0],"istart":[25,1,13],"iend":[26,2,0]}]}]}]},{"type":"Token","kind":"WHITESPACE","start":[51,5,1],"end":[51,5,1],"istart":[26,2,0],"iend":[31,2,5]}]}]},{"type":"Token","kind":"COMMA","start":[57,6,5],"end":[58,6,6]},{"type":"Token","kind":"WHITESPACE","start":[58,6,6],"end":[59,6,7]},{"type":"Token","kind":"STRING","start":[59,6,7],"end":[61,6,9]},{"type":"Token","kind":"R_PAREN","start":[61,6,9],"end":[62,6,10]}]}]}]},{"type":"Token","kind":"SEMICOLON","start":[62,6,10],"end":[63,6,11]}]},{"type":"Token","kind":"WHITESPACE","start":[63,6,11],"end":[64,7,0]},{"type":"Token","kind":"R_CURLY","start":[64,7,0],"end":[65,7,1]}]}]}]}]}"#
             ]],
         );
 
@@ -205,7 +234,7 @@ fn bar() {
     "#, "");
 }"###,
             expect![[
-                r#"{"type":"Node","kind":"SOURCE_FILE","start":0,"end":68,"children":[{"type":"Node","kind":"FN","start":0,"end":68,"children":[{"type":"Token","kind":"FN_KW","start":0,"end":2},{"type":"Token","kind":"WHITESPACE","start":2,"end":3},{"type":"Node","kind":"NAME","start":3,"end":7,"children":[{"type":"Token","kind":"IDENT","start":3,"end":7}]},{"type":"Node","kind":"PARAM_LIST","start":7,"end":9,"children":[{"type":"Token","kind":"L_PAREN","start":7,"end":8},{"type":"Token","kind":"R_PAREN","start":8,"end":9}]},{"type":"Token","kind":"WHITESPACE","start":9,"end":10},{"type":"Node","kind":"BLOCK_EXPR","start":10,"end":68,"children":[{"type":"Node","kind":"STMT_LIST","start":10,"end":68,"children":[{"type":"Token","kind":"L_CURLY","start":10,"end":11},{"type":"Token","kind":"WHITESPACE","start":11,"end":16},{"type":"Node","kind":"EXPR_STMT","start":16,"end":66,"children":[{"type":"Node","kind":"MACRO_EXPR","start":16,"end":65,"children":[{"type":"Node","kind":"MACRO_CALL","start":16,"end":65,"children":[{"type":"Node","kind":"PATH","start":16,"end":22,"children":[{"type":"Node","kind":"PATH_SEGMENT","start":16,"end":22,"children":[{"type":"Node","kind":"NAME_REF","start":16,"end":22,"children":[{"type":"Token","kind":"IDENT","start":16,"end":22}]}]}]},{"type":"Token","kind":"BANG","start":22,"end":23},{"type":"Node","kind":"TOKEN_TREE","start":23,"end":65,"children":[{"type":"Token","kind":"L_PAREN","start":23,"end":24},{"type":"Node","kind":"STRING","start":24,"end":60,"children":[{"type":"Node","kind":"SOURCE_FILE","start":27,"end":58,"istart":0,"iend":31,"children":[{"type":"Token","kind":"WHITESPACE","start":27,"end":28,"istart":0,"iend":1},{"type":"Node","kind":"FN","start":28,"end":40,"istart":1,"iend":13,"children":[{"type":"Token","kind":"FN_KW","start":28,"end":30,"istart":1,"iend":3},{"type":"Token","kind":"WHITESPACE","start":30,"end":31,"istart":3,"iend":4},{"type":"Node","kind":"NAME","start":31,"end":34,"istart":4,"iend":7,"children":[{"type":"Token","kind":"IDENT","start":31,"end":34,"istart":4,"iend":7}]},{"type":"Node","kind":"PARAM_LIST","start":34,"end":36,"istart":7,"iend":9,"children":[{"type":"Token","kind":"L_PAREN","start":34,"end":35,"istart":7,"iend":8},{"type":"Token","kind":"R_PAREN","start":35,"end":36,"istart":8,"iend":9}]},{"type":"Token","kind":"WHITESPACE","start":36,"end":37,"istart":9,"iend":10},{"type":"Node","kind":"BLOCK_EXPR","start":37,"end":40,"istart":10,"iend":13,"children":[{"type":"Node","kind":"STMT_LIST","start":37,"end":40,"istart":10,"iend":13,"children":[{"type":"Token","kind":"L_CURLY","start":37,"end":38,"istart":10,"iend":11},{"type":"Token","kind":"WHITESPACE","start":38,"end":39,"istart":11,"iend":12},{"type":"Token","kind":"R_CURLY","start":39,"end":40,"istart":12,"iend":13}]}]}]},{"type":"Token","kind":"WHITESPACE","start":40,"end":41,"istart":13,"iend":14},{"type":"Node","kind":"FN","start":41,"end":53,"istart":14,"iend":26,"children":[{"type":"Token","kind":"FN_KW","start":41,"end":43,"istart":14,"iend":16},{"type":"Token","kind":"WHITESPACE","start":43,"end":44,"istart":16,"iend":17},{"type":"Node","kind":"NAME","start":44,"end":47,"istart":17,"iend":20,"children":[{"type":"Token","kind":"IDENT","start":44,"end":47,"istart":17,"iend":20}]},{"type":"Node","kind":"PARAM_LIST","start":47,"end":49,"istart":20,"iend":22,"children":[{"type":"Token","kind":"L_PAREN","start":47,"end":48,"istart":20,"iend":21},{"type":"Token","kind":"R_PAREN","start":48,"end":49,"istart":21,"iend":22}]},{"type":"Token","kind":"WHITESPACE","start":49,"end":50,"istart":22,"iend":23},{"type":"Node","kind":"BLOCK_EXPR","start":50,"end":53,"istart":23,"iend":26,"children":[{"type":"Node","kind":"STMT_LIST","start":50,"end":53,"istart":23,"iend":26,"children":[{"type":"Token","kind":"L_CURLY","start":50,"end":51,"istart":23,"iend":24},{"type":"Token","kind":"WHITESPACE","start":51,"end":52,"istart":24,"iend":25},{"type":"Token","kind":"R_CURLY","start":52,"end":53,"istart":25,"iend":26}]}]}]},{"type":"Token","kind":"WHITESPACE","start":53,"end":58,"istart":26,"iend":31}]}]},{"type":"Token","kind":"COMMA","start":60,"end":61},{"type":"Token","kind":"WHITESPACE","start":61,"end":62},{"type":"Token","kind":"STRING","start":62,"end":64},{"type":"Token","kind":"R_PAREN","start":64,"end":65}]}]}]},{"type":"Token","kind":"SEMICOLON","start":65,"end":66}]},{"type":"Token","kind":"WHITESPACE","start":66,"end":67},{"type":"Token","kind":"R_CURLY","start":67,"end":68}]}]}]}]}"#
+                r#"{"type":"Node","kind":"SOURCE_FILE","start":[0,0,0],"end":[68,7,1],"children":[{"type":"Node","kind":"FN","start":[0,0,0],"end":[68,7,1],"children":[{"type":"Token","kind":"FN_KW","start":[0,0,0],"end":[2,0,2]},{"type":"Token","kind":"WHITESPACE","start":[2,0,2],"end":[3,0,3]},{"type":"Node","kind":"NAME","start":[3,0,3],"end":[7,0,7],"children":[{"type":"Token","kind":"IDENT","start":[3,0,3],"end":[7,0,7]}]},{"type":"Node","kind":"PARAM_LIST","start":[7,0,7],"end":[9,0,9],"children":[{"type":"Token","kind":"L_PAREN","start":[7,0,7],"end":[8,0,8]},{"type":"Token","kind":"R_PAREN","start":[8,0,8],"end":[9,0,9]}]},{"type":"Token","kind":"WHITESPACE","start":[9,0,9],"end":[10,0,10]},{"type":"Node","kind":"BLOCK_EXPR","start":[10,0,10],"end":[68,7,1],"children":[{"type":"Node","kind":"STMT_LIST","start":[10,0,10],"end":[68,7,1],"children":[{"type":"Token","kind":"L_CURLY","start":[10,0,10],"end":[11,0,11]},{"type":"Token","kind":"WHITESPACE","start":[11,0,11],"end":[16,1,4]},{"type":"Node","kind":"EXPR_STMT","start":[16,1,4],"end":[66,6,12],"children":[{"type":"Node","kind":"MACRO_EXPR","start":[16,1,4],"end":[65,6,11],"children":[{"type":"Node","kind":"MACRO_CALL","start":[16,1,4],"end":[65,6,11],"children":[{"type":"Node","kind":"PATH","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Node","kind":"PATH_SEGMENT","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Node","kind":"NAME_REF","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Token","kind":"IDENT","start":[16,1,4],"end":[22,1,10]}]}]}]},{"type":"Token","kind":"BANG","start":[22,1,10],"end":[23,1,11]},{"type":"Node","kind":"TOKEN_TREE","start":[23,1,11],"end":[65,6,11],"children":[{"type":"Token","kind":"L_PAREN","start":[23,1,11],"end":[24,1,12]},{"type":"Node","kind":"STRING","start":[24,1,12],"end":[60,6,6],"children":[{"type":"Node","kind":"SOURCE_FILE","start":[27,1,15],"end":[27,1,15],"istart":[0,0,0],"iend":[31,2,3],"children":[{"type":"Token","kind":"WHITESPACE","start":[27,1,15],"end":[27,1,15],"istart":[0,0,0],"iend":[1,0,1]},{"type":"Node","kind":"FN","start":[28,2,0],"end":[28,2,0],"istart":[1,0,1],"iend":[13,1,1],"children":[{"type":"Token","kind":"FN_KW","start":[28,2,0],"end":[28,2,0],"istart":[1,0,1],"iend":[3,0,3]},{"type":"Token","kind":"WHITESPACE","start":[30,2,2],"end":[30,2,2],"istart":[3,0,3],"iend":[4,0,4]},{"type":"Node","kind":"NAME","start":[31,2,3],"end":[31,2,3],"istart":[4,0,4],"iend":[7,0,7],"children":[{"type":"Token","kind":"IDENT","start":[31,2,3],"end":[31,2,3],"istart":[4,0,4],"iend":[7,0,7]}]},{"type":"Node","kind":"PARAM_LIST","start":[34,2,6],"end":[34,2,6],"istart":[7,0,7],"iend":[9,0,9],"children":[{"type":"Token","kind":"L_PAREN","start":[34,2,6],"end":[34,2,6],"istart":[7,0,7],"iend":[8,0,8]},{"type":"Token","kind":"R_PAREN","start":[35,2,7],"end":[35,2,7],"istart":[8,0,8],"iend":[9,0,9]}]},{"type":"Token","kind":"WHITESPACE","start":[36,2,8],"end":[36,2,8],"istart":[9,0,9],"iend":[10,0,10]},{"type":"Node","kind":"BLOCK_EXPR","start":[37,2,9],"end":[37,2,9],"istart":[10,0,10],"iend":[13,1,1],"children":[{"type":"Node","kind":"STMT_LIST","start":[37,2,9],"end":[37,2,9],"istart":[10,0,10],"iend":[13,1,1],"children":[{"type":"Token","kind":"L_CURLY","start":[37,2,9],"end":[37,2,9],"istart":[10,0,10],"iend":[11,0,11]},{"type":"Token","kind":"WHITESPACE","start":[38,2,10],"end":[38,2,10],"istart":[11,0,11],"iend":[12,1,0]},{"type":"Token","kind":"R_CURLY","start":[39,3,0],"end":[39,3,0],"istart":[12,1,0],"iend":[13,1,1]}]}]}]},{"type":"Token","kind":"WHITESPACE","start":[40,3,1],"end":[40,3,1],"istart":[13,1,1],"iend":[14,1,2]},{"type":"Node","kind":"FN","start":[41,4,0],"end":[41,4,0],"istart":[14,1,2],"iend":[26,1,14],"children":[{"type":"Token","kind":"FN_KW","start":[41,4,0],"end":[41,4,0],"istart":[14,1,2],"iend":[16,1,4]},{"type":"Token","kind":"WHITESPACE","start":[43,4,2],"end":[43,4,2],"istart":[16,1,4],"iend":[17,1,5]},{"type":"Node","kind":"NAME","start":[44,4,3],"end":[44,4,3],"istart":[17,1,5],"iend":[20,1,8],"children":[{"type":"Token","kind":"IDENT","start":[44,4,3],"end":[44,4,3],"istart":[17,1,5],"iend":[20,1,8]}]},{"type":"Node","kind":"PARAM_LIST","start":[47,4,6],"end":[47,4,6],"istart":[20,1,8],"iend":[22,1,10],"children":[{"type":"Token","kind":"L_PAREN","start":[47,4,6],"end":[47,4,6],"istart":[20,1,8],"iend":[21,1,9]},{"type":"Token","kind":"R_PAREN","start":[48,4,7],"end":[48,4,7],"istart":[21,1,9],"iend":[22,1,10]}]},{"type":"Token","kind":"WHITESPACE","start":[49,4,8],"end":[49,4,8],"istart":[22,1,10],"iend":[23,1,11]},{"type":"Node","kind":"BLOCK_EXPR","start":[50,4,9],"end":[50,4,9],"istart":[23,1,11],"iend":[26,1,14],"children":[{"type":"Node","kind":"STMT_LIST","start":[50,4,9],"end":[50,4,9],"istart":[23,1,11],"iend":[26,1,14],"children":[{"type":"Token","kind":"L_CURLY","start":[50,4,9],"end":[50,4,9],"istart":[23,1,11],"iend":[24,1,12]},{"type":"Token","kind":"WHITESPACE","start":[51,4,10],"end":[51,4,10],"istart":[24,1,12],"iend":[25,1,13]},{"type":"Token","kind":"R_CURLY","start":[52,5,0],"end":[52,5,0],"istart":[25,1,13],"iend":[26,1,14]}]}]}]},{"type":"Token","kind":"WHITESPACE","start":[53,5,1],"end":[53,5,1],"istart":[26,1,14],"iend":[31,2,3]}]}]},{"type":"Token","kind":"COMMA","start":[60,6,6],"end":[61,6,7]},{"type":"Token","kind":"WHITESPACE","start":[61,6,7],"end":[62,6,8]},{"type":"Token","kind":"STRING","start":[62,6,8],"end":[64,6,10]},{"type":"Token","kind":"R_PAREN","start":[64,6,10],"end":[65,6,11]}]}]}]},{"type":"Token","kind":"SEMICOLON","start":[65,6,11],"end":[66,6,12]}]},{"type":"Token","kind":"WHITESPACE","start":[66,6,12],"end":[67,7,0]},{"type":"Token","kind":"R_CURLY","start":[67,7,0],"end":[68,7,1]}]}]}]}]}"#
             ]],
         );
 
@@ -219,7 +248,7 @@ fn bar() {
 }"$0#, "");
 }"###,
             expect![[
-                r#"{"type":"Node","kind":"SOURCE_FILE","start":0,"end":63,"children":[{"type":"Node","kind":"FN","start":0,"end":63,"children":[{"type":"Token","kind":"FN_KW","start":0,"end":2},{"type":"Token","kind":"WHITESPACE","start":2,"end":3},{"type":"Node","kind":"NAME","start":3,"end":7,"children":[{"type":"Token","kind":"IDENT","start":3,"end":7}]},{"type":"Node","kind":"PARAM_LIST","start":7,"end":9,"children":[{"type":"Token","kind":"L_PAREN","start":7,"end":8},{"type":"Token","kind":"R_PAREN","start":8,"end":9}]},{"type":"Token","kind":"WHITESPACE","start":9,"end":10},{"type":"Node","kind":"BLOCK_EXPR","start":10,"end":63,"children":[{"type":"Node","kind":"STMT_LIST","start":10,"end":63,"children":[{"type":"Token","kind":"L_CURLY","start":10,"end":11},{"type":"Token","kind":"WHITESPACE","start":11,"end":16},{"type":"Node","kind":"EXPR_STMT","start":16,"end":61,"children":[{"type":"Node","kind":"MACRO_EXPR","start":16,"end":60,"children":[{"type":"Node","kind":"MACRO_CALL","start":16,"end":60,"children":[{"type":"Node","kind":"PATH","start":16,"end":22,"children":[{"type":"Node","kind":"PATH_SEGMENT","start":16,"end":22,"children":[{"type":"Node","kind":"NAME_REF","start":16,"end":22,"children":[{"type":"Token","kind":"IDENT","start":16,"end":22}]}]}]},{"type":"Token","kind":"BANG","start":22,"end":23},{"type":"Node","kind":"TOKEN_TREE","start":23,"end":60,"children":[{"type":"Token","kind":"L_PAREN","start":23,"end":24},{"type":"Node","kind":"STRING","start":24,"end":55,"children":[{"type":"Node","kind":"SOURCE_FILE","start":27,"end":53,"istart":0,"iend":26,"children":[{"type":"Token","kind":"WHITESPACE","start":27,"end":28,"istart":0,"iend":1},{"type":"Node","kind":"FN","start":28,"end":40,"istart":1,"iend":13,"children":[{"type":"Token","kind":"FN_KW","start":28,"end":30,"istart":1,"iend":3},{"type":"Token","kind":"WHITESPACE","start":30,"end":31,"istart":3,"iend":4},{"type":"Node","kind":"NAME","start":31,"end":34,"istart":4,"iend":7,"children":[{"type":"Token","kind":"IDENT","start":31,"end":34,"istart":4,"iend":7}]},{"type":"Node","kind":"PARAM_LIST","start":34,"end":36,"istart":7,"iend":9,"children":[{"type":"Token","kind":"L_PAREN","start":34,"end":35,"istart":7,"iend":8},{"type":"Token","kind":"R_PAREN","start":35,"end":36,"istart":8,"iend":9}]},{"type":"Token","kind":"WHITESPACE","start":36,"end":37,"istart":9,"iend":10},{"type":"Node","kind":"BLOCK_EXPR","start":37,"end":40,"istart":10,"iend":13,"children":[{"type":"Node","kind":"STMT_LIST","start":37,"end":40,"istart":10,"iend":13,"children":[{"type":"Token","kind":"L_CURLY","start":37,"end":38,"istart":10,"iend":11},{"type":"Token","kind":"WHITESPACE","start":38,"end":39,"istart":11,"iend":12},{"type":"Token","kind":"R_CURLY","start":39,"end":40,"istart":12,"iend":13}]}]}]},{"type":"Token","kind":"WHITESPACE","start":40,"end":41,"istart":13,"iend":14},{"type":"Node","kind":"FN","start":41,"end":53,"istart":14,"iend":26,"children":[{"type":"Token","kind":"FN_KW","start":41,"end":43,"istart":14,"iend":16},{"type":"Token","kind":"WHITESPACE","start":43,"end":44,"istart":16,"iend":17},{"type":"Node","kind":"NAME","start":44,"end":47,"istart":17,"iend":20,"children":[{"type":"Token","kind":"IDENT","start":44,"end":47,"istart":17,"iend":20}]},{"type":"Node","kind":"PARAM_LIST","start":47,"end":49,"istart":20,"iend":22,"children":[{"type":"Token","kind":"L_PAREN","start":47,"end":48,"istart":20,"iend":21},{"type":"Token","kind":"R_PAREN","start":48,"end":49,"istart":21,"iend":22}]},{"type":"Token","kind":"WHITESPACE","start":49,"end":50,"istart":22,"iend":23},{"type":"Node","kind":"BLOCK_EXPR","start":50,"end":53,"istart":23,"iend":26,"children":[{"type":"Node","kind":"STMT_LIST","start":50,"end":53,"istart":23,"iend":26,"children":[{"type":"Token","kind":"L_CURLY","start":50,"end":51,"istart":23,"iend":24},{"type":"Token","kind":"WHITESPACE","start":51,"end":52,"istart":24,"iend":25},{"type":"Token","kind":"R_CURLY","start":52,"end":53,"istart":25,"iend":26}]}]}]}]}]},{"type":"Token","kind":"COMMA","start":55,"end":56},{"type":"Token","kind":"WHITESPACE","start":56,"end":57},{"type":"Token","kind":"STRING","start":57,"end":59},{"type":"Token","kind":"R_PAREN","start":59,"end":60}]}]}]},{"type":"Token","kind":"SEMICOLON","start":60,"end":61}]},{"type":"Token","kind":"WHITESPACE","start":61,"end":62},{"type":"Token","kind":"R_CURLY","start":62,"end":63}]}]}]}]}"#
+                r#"{"type":"Node","kind":"SOURCE_FILE","start":[0,0,0],"end":[63,6,1],"children":[{"type":"Node","kind":"FN","start":[0,0,0],"end":[63,6,1],"children":[{"type":"Token","kind":"FN_KW","start":[0,0,0],"end":[2,0,2]},{"type":"Token","kind":"WHITESPACE","start":[2,0,2],"end":[3,0,3]},{"type":"Node","kind":"NAME","start":[3,0,3],"end":[7,0,7],"children":[{"type":"Token","kind":"IDENT","start":[3,0,3],"end":[7,0,7]}]},{"type":"Node","kind":"PARAM_LIST","start":[7,0,7],"end":[9,0,9],"children":[{"type":"Token","kind":"L_PAREN","start":[7,0,7],"end":[8,0,8]},{"type":"Token","kind":"R_PAREN","start":[8,0,8],"end":[9,0,9]}]},{"type":"Token","kind":"WHITESPACE","start":[9,0,9],"end":[10,0,10]},{"type":"Node","kind":"BLOCK_EXPR","start":[10,0,10],"end":[63,6,1],"children":[{"type":"Node","kind":"STMT_LIST","start":[10,0,10],"end":[63,6,1],"children":[{"type":"Token","kind":"L_CURLY","start":[10,0,10],"end":[11,0,11]},{"type":"Token","kind":"WHITESPACE","start":[11,0,11],"end":[16,1,4]},{"type":"Node","kind":"EXPR_STMT","start":[16,1,4],"end":[61,5,9],"children":[{"type":"Node","kind":"MACRO_EXPR","start":[16,1,4],"end":[60,5,8],"children":[{"type":"Node","kind":"MACRO_CALL","start":[16,1,4],"end":[60,5,8],"children":[{"type":"Node","kind":"PATH","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Node","kind":"PATH_SEGMENT","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Node","kind":"NAME_REF","start":[16,1,4],"end":[22,1,10],"children":[{"type":"Token","kind":"IDENT","start":[16,1,4],"end":[22,1,10]}]}]}]},{"type":"Token","kind":"BANG","start":[22,1,10],"end":[23,1,11]},{"type":"Node","kind":"TOKEN_TREE","start":[23,1,11],"end":[60,5,8],"children":[{"type":"Token","kind":"L_PAREN","start":[23,1,11],"end":[24,1,12]},{"type":"Node","kind":"STRING","start":[24,1,12],"end":[55,5,3],"children":[{"type":"Node","kind":"SOURCE_FILE","start":[27,1,15],"end":[27,1,15],"istart":[0,0,0],"iend":[26,1,14],"children":[{"type":"Token","kind":"WHITESPACE","start":[27,1,15],"end":[27,1,15],"istart":[0,0,0],"iend":[1,0,1]},{"type":"Node","kind":"FN","start":[28,2,0],"end":[28,2,0],"istart":[1,0,1],"iend":[13,1,1],"children":[{"type":"Token","kind":"FN_KW","start":[28,2,0],"end":[28,2,0],"istart":[1,0,1],"iend":[3,0,3]},{"type":"Token","kind":"WHITESPACE","start":[30,2,2],"end":[30,2,2],"istart":[3,0,3],"iend":[4,0,4]},{"type":"Node","kind":"NAME","start":[31,2,3],"end":[31,2,3],"istart":[4,0,4],"iend":[7,0,7],"children":[{"type":"Token","kind":"IDENT","start":[31,2,3],"end":[31,2,3],"istart":[4,0,4],"iend":[7,0,7]}]},{"type":"Node","kind":"PARAM_LIST","start":[34,2,6],"end":[34,2,6],"istart":[7,0,7],"iend":[9,0,9],"children":[{"type":"Token","kind":"L_PAREN","start":[34,2,6],"end":[34,2,6],"istart":[7,0,7],"iend":[8,0,8]},{"type":"Token","kind":"R_PAREN","start":[35,2,7],"end":[35,2,7],"istart":[8,0,8],"iend":[9,0,9]}]},{"type":"Token","kind":"WHITESPACE","start":[36,2,8],"end":[36,2,8],"istart":[9,0,9],"iend":[10,0,10]},{"type":"Node","kind":"BLOCK_EXPR","start":[37,2,9],"end":[37,2,9],"istart":[10,0,10],"iend":[13,1,1],"children":[{"type":"Node","kind":"STMT_LIST","start":[37,2,9],"end":[37,2,9],"istart":[10,0,10],"iend":[13,1,1],"children":[{"type":"Token","kind":"L_CURLY","start":[37,2,9],"end":[37,2,9],"istart":[10,0,10],"iend":[11,0,11]},{"type":"Token","kind":"WHITESPACE","start":[38,2,10],"end":[38,2,10],"istart":[11,0,11],"iend":[12,1,0]},{"type":"Token","kind":"R_CURLY","start":[39,3,0],"end":[39,3,0],"istart":[12,1,0],"iend":[13,1,1]}]}]}]},{"type":"Token","kind":"WHITESPACE","start":[40,3,1],"end":[40,3,1],"istart":[13,1,1],"iend":[14,1,2]},{"type":"Node","kind":"FN","start":[41,4,0],"end":[41,4,0],"istart":[14,1,2],"iend":[26,1,14],"children":[{"type":"Token","kind":"FN_KW","start":[41,4,0],"end":[41,4,0],"istart":[14,1,2],"iend":[16,1,4]},{"type":"Token","kind":"WHITESPACE","start":[43,4,2],"end":[43,4,2],"istart":[16,1,4],"iend":[17,1,5]},{"type":"Node","kind":"NAME","start":[44,4,3],"end":[44,4,3],"istart":[17,1,5],"iend":[20,1,8],"children":[{"type":"Token","kind":"IDENT","start":[44,4,3],"end":[44,4,3],"istart":[17,1,5],"iend":[20,1,8]}]},{"type":"Node","kind":"PARAM_LIST","start":[47,4,6],"end":[47,4,6],"istart":[20,1,8],"iend":[22,1,10],"children":[{"type":"Token","kind":"L_PAREN","start":[47,4,6],"end":[47,4,6],"istart":[20,1,8],"iend":[21,1,9]},{"type":"Token","kind":"R_PAREN","start":[48,4,7],"end":[48,4,7],"istart":[21,1,9],"iend":[22,1,10]}]},{"type":"Token","kind":"WHITESPACE","start":[49,4,8],"end":[49,4,8],"istart":[22,1,10],"iend":[23,1,11]},{"type":"Node","kind":"BLOCK_EXPR","start":[50,4,9],"end":[50,4,9],"istart":[23,1,11],"iend":[26,1,14],"children":[{"type":"Node","kind":"STMT_LIST","start":[50,4,9],"end":[50,4,9],"istart":[23,1,11],"iend":[26,1,14],"children":[{"type":"Token","kind":"L_CURLY","start":[50,4,9],"end":[50,4,9],"istart":[23,1,11],"iend":[24,1,12]},{"type":"Token","kind":"WHITESPACE","start":[51,4,10],"end":[51,4,10],"istart":[24,1,12],"iend":[25,1,13]},{"type":"Token","kind":"R_CURLY","start":[52,5,0],"end":[52,5,0],"istart":[25,1,13],"iend":[26,1,14]}]}]}]}]}]},{"type":"Token","kind":"COMMA","start":[55,5,3],"end":[56,5,4]},{"type":"Token","kind":"WHITESPACE","start":[56,5,4],"end":[57,5,5]},{"type":"Token","kind":"STRING","start":[57,5,5],"end":[59,5,7]},{"type":"Token","kind":"R_PAREN","start":[59,5,7],"end":[60,5,8]}]}]}]},{"type":"Token","kind":"SEMICOLON","start":[60,5,8],"end":[61,5,9]}]},{"type":"Token","kind":"WHITESPACE","start":[61,5,9],"end":[62,6,0]},{"type":"Token","kind":"R_CURLY","start":[62,6,0],"end":[63,6,1]}]}]}]}]}"#
             ]],
         );
     }
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
index ae1c6efe0cb..66553a2661a 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
@@ -347,6 +347,7 @@ define_symbols! {
     option,
     Option,
     Ord,
+    Ordering,
     Output,
     CallRefFuture,
     CallOnceFuture,
@@ -458,6 +459,8 @@ define_symbols! {
     system,
     sysv64,
     Target,
+    target_feature,
+    enable,
     termination,
     test_case,
     test,
@@ -479,6 +482,7 @@ define_symbols! {
     u64,
     u8,
     unadjusted,
+    unknown,
     Unknown,
     unpin,
     unreachable_2015,
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
index 389c01933c9..fe1316c9bfd 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
@@ -678,6 +678,8 @@ fn path_expr(p: &mut Parser<'_>, r: Restrictions) -> (CompletedMarker, BlockLike
 //     S { x };
 //     S { x, y: 32, };
 //     S { x, y: 32, ..Default::default() };
+//     S { x, y: 32, .. };
+//     S { .. };
 //     S { x: ::default() };
 //     TupleStruct { 0: 1 };
 // }
@@ -709,6 +711,8 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
                 // fn main() {
                 //     S { field ..S::default() }
                 //     S { 0 ..S::default() }
+                //     S { field .. }
+                //     S { 0 .. }
                 // }
                 name_ref_or_index(p);
                 p.error("expected `:`");
@@ -739,7 +743,13 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
                 //     S { .. } = S {};
                 // }
 
-                // We permit `.. }` on the left-hand side of a destructuring assignment.
+                // test struct_initializer_with_defaults
+                // fn foo() {
+                //     let _s = S { .. };
+                // }
+
+                // We permit `.. }` on the left-hand side of a destructuring assignment
+                // or defaults values.
                 if !p.at(T!['}']) {
                     expr(p);
 
@@ -750,6 +760,12 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
                         //     S { ..x, a: 0 }
                         // }
 
+                        // test_err comma_after_default_values_syntax
+                        // fn foo() {
+                        //     S { .., };
+                        //     S { .., a: 0 }
+                        // }
+
                         // Do not bump, so we can support additional fields after this comma.
                         p.error("cannot use a comma after the base struct");
                     }
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs
index 21078175c0e..9a16c9db6da 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs
@@ -135,6 +135,11 @@ pub(crate) fn record_field_list(p: &mut Parser<'_>) {
             name(p);
             p.expect(T![:]);
             types::type_(p);
+            // test record_field_default_values
+            // struct S { f: f32 = 0.0 }
+            if p.eat(T![=]) {
+                expressions::expr(p);
+            }
             m.complete(p, RECORD_FIELD);
         } else {
             m.abandon(p);
diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
index 318f71a2d4d..79900425a17 100644
--- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
@@ -1,4 +1,4 @@
-//! Generated by `cargo codegen grammar`, do not edit by hand.
+//! Generated by `cargo xtask codegen grammar`, do not edit by hand.
 
 #![allow(bad_style, missing_docs, unreachable_pub)]
 use crate::Edition;
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
index b9f87b6af24..c8ea8c547a9 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
@@ -482,6 +482,10 @@ mod ok {
         run_and_expect_no_errors("test_data/parser/inline/ok/record_field_attrs.rs");
     }
     #[test]
+    fn record_field_default_values() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/record_field_default_values.rs");
+    }
+    #[test]
     fn record_field_list() {
         run_and_expect_no_errors("test_data/parser/inline/ok/record_field_list.rs");
     }
@@ -544,6 +548,10 @@ mod ok {
         run_and_expect_no_errors("test_data/parser/inline/ok/stmt_postfix_expr_ambiguity.rs");
     }
     #[test]
+    fn struct_initializer_with_defaults() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/struct_initializer_with_defaults.rs");
+    }
+    #[test]
     fn struct_item() { run_and_expect_no_errors("test_data/parser/inline/ok/struct_item.rs"); }
     #[test]
     fn trait_alias() { run_and_expect_no_errors("test_data/parser/inline/ok/trait_alias.rs"); }
@@ -719,6 +727,10 @@ mod err {
         );
     }
     #[test]
+    fn comma_after_default_values_syntax() {
+        run_and_expect_errors("test_data/parser/inline/err/comma_after_default_values_syntax.rs");
+    }
+    #[test]
     fn crate_visibility_empty_recover() {
         run_and_expect_errors("test_data/parser/inline/err/crate_visibility_empty_recover.rs");
     }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast
new file mode 100644
index 00000000000..feb617e1aa2
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast
@@ -0,0 +1,59 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              DOT2 ".."
+              ERROR
+                COMMA ","
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        RECORD_EXPR
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "S"
+          WHITESPACE " "
+          RECORD_EXPR_FIELD_LIST
+            L_CURLY "{"
+            WHITESPACE " "
+            DOT2 ".."
+            ERROR
+              COMMA ","
+            WHITESPACE " "
+            RECORD_EXPR_FIELD
+              NAME_REF
+                IDENT "a"
+              COLON ":"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "0"
+            WHITESPACE " "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 21: expected expression
+error 36: expected expression
+error 37: expected COMMA
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rs
new file mode 100644
index 00000000000..f1ecdf89fab
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rs
@@ -0,0 +1,4 @@
+fn foo() {
+    S { .., };
+    S { .., a: 0 }
+}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
index 08ae906421c..12b4e233e30 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
@@ -44,6 +44,56 @@ SOURCE_FILE
               WHITESPACE " "
               R_CURLY "}"
         WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                NAME_REF
+                  INT_NUMBER "0"
+              WHITESPACE " "
+              DOT2 ".."
+              CALL_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "S"
+                    COLON2 "::"
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "default"
+                ARG_LIST
+                  L_PAREN "("
+                  R_PAREN ")"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                NAME_REF
+                  IDENT "field"
+              WHITESPACE " "
+              DOT2 ".."
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
         RECORD_EXPR
           PATH
             PATH_SEGMENT
@@ -58,20 +108,6 @@ SOURCE_FILE
                 INT_NUMBER "0"
             WHITESPACE " "
             DOT2 ".."
-            CALL_EXPR
-              PATH_EXPR
-                PATH
-                  PATH
-                    PATH_SEGMENT
-                      NAME_REF
-                        IDENT "S"
-                  COLON2 "::"
-                  PATH_SEGMENT
-                    NAME_REF
-                      IDENT "default"
-              ARG_LIST
-                L_PAREN "("
-                R_PAREN ")"
             WHITESPACE " "
             R_CURLY "}"
         WHITESPACE "\n"
@@ -82,3 +118,9 @@ error 25: expected COMMA
 error 42: expected SEMICOLON
 error 52: expected `:`
 error 52: expected COMMA
+error 69: expected SEMICOLON
+error 83: expected `:`
+error 83: expected COMMA
+error 88: expected SEMICOLON
+error 98: expected `:`
+error 98: expected COMMA
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
index 65398ccb88e..416cd763fdb 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
@@ -1,4 +1,6 @@
 fn main() {
     S { field ..S::default() }
     S { 0 ..S::default() }
+    S { field .. }
+    S { 0 .. }
 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rast
new file mode 100644
index 00000000000..33088f2cabf
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rast
@@ -0,0 +1,28 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE " "
+      RECORD_FIELD
+        NAME
+          IDENT "f"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "f32"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        LITERAL
+          FLOAT_NUMBER "0.0"
+      WHITESPACE " "
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rs
new file mode 100644
index 00000000000..d7b38944a8a
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rs
@@ -0,0 +1 @@
+struct S { f: f32 = 0.0 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rast
index 00948c322f4..b868da55bce 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rast
@@ -131,6 +131,53 @@ SOURCE_FILE
               L_CURLY "{"
               WHITESPACE " "
               RECORD_EXPR_FIELD
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "x"
+              COMMA ","
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                NAME_REF
+                  IDENT "y"
+                COLON ":"
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "32"
+              COMMA ","
+              WHITESPACE " "
+              DOT2 ".."
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              DOT2 ".."
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
                 NAME_REF
                   IDENT "x"
                 COLON ":"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rs
index 86411fbb7dc..42895f759b2 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rs
@@ -3,6 +3,8 @@ fn foo() {
     S { x };
     S { x, y: 32, };
     S { x, y: 32, ..Default::default() };
+    S { x, y: 32, .. };
+    S { .. };
     S { x: ::default() };
     TupleStruct { 0: 1 };
 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_initializer_with_defaults.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_initializer_with_defaults.rast
new file mode 100644
index 00000000000..987e219ae82
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_initializer_with_defaults.rast
@@ -0,0 +1,39 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_s"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              DOT2 ".."
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_initializer_with_defaults.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_initializer_with_defaults.rs
new file mode 100644
index 00000000000..e08204f94c4
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_initializer_with_defaults.rs
@@ -0,0 +1,3 @@
+fn foo() {
+    let _s = S { .. };
+}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs
index ba1fcd8e336..569070766f1 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs
@@ -21,18 +21,16 @@ pub(crate) fn run() -> io::Result<()> {
         }
     }
 
-    let read_request =
-        |buf: &mut String| msg::Request::read(read_json, &mut io::stdin().lock(), buf);
-
+    let mut buf = String::new();
+    let mut read_request = || msg::Request::read(read_json, &mut io::stdin().lock(), &mut buf);
     let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
 
     let env = EnvSnapshot::default();
-    let mut srv = proc_macro_srv::ProcMacroSrv::new(&env);
-    let mut buf = String::new();
+    let srv = proc_macro_srv::ProcMacroSrv::new(&env);
 
     let mut span_mode = SpanMode::Id;
 
-    while let Some(req) = read_request(&mut buf)? {
+    while let Some(req) = read_request()? {
         let res = match req {
             msg::Request::ListMacros { dylib_path } => {
                 msg::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| {
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
index 7ae75713ebf..f28821b4afc 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
@@ -35,6 +35,7 @@ use std::{
     ffi::OsString,
     fs,
     path::{Path, PathBuf},
+    sync::{Arc, Mutex, PoisonError},
     thread,
 };
 
@@ -53,7 +54,7 @@ pub enum ProcMacroKind {
 pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION");
 
 pub struct ProcMacroSrv<'env> {
-    expanders: HashMap<Utf8PathBuf, dylib::Expander>,
+    expanders: Mutex<HashMap<Utf8PathBuf, Arc<dylib::Expander>>>,
     env: &'env EnvSnapshot,
 }
 
@@ -67,7 +68,7 @@ const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024;
 
 impl ProcMacroSrv<'_> {
     pub fn expand<S: ProcMacroSrvSpan>(
-        &mut self,
+        &self,
         lib: impl AsRef<Utf8Path>,
         env: Vec<(String, String)>,
         current_dir: Option<impl AsRef<Path>>,
@@ -118,29 +119,37 @@ impl ProcMacroSrv<'_> {
     }
 
     pub fn list_macros(
-        &mut self,
+        &self,
         dylib_path: &Utf8Path,
     ) -> Result<Vec<(String, ProcMacroKind)>, String> {
         let expander = self.expander(dylib_path)?;
         Ok(expander.list_macros())
     }
 
-    fn expander(&mut self, path: &Utf8Path) -> Result<&dylib::Expander, String> {
+    fn expander(&self, path: &Utf8Path) -> Result<Arc<dylib::Expander>, String> {
         let expander = || {
-            dylib::Expander::new(path)
-                .map_err(|err| format!("Cannot create expander for {path}: {err}",))
+            let expander = dylib::Expander::new(path)
+                .map_err(|err| format!("Cannot create expander for {path}: {err}",));
+            expander.map(Arc::new)
         };
 
-        Ok(match self.expanders.entry(path.to_path_buf()) {
-            Entry::Vacant(v) => v.insert(expander()?),
-            Entry::Occupied(mut e) => {
-                let time = fs::metadata(path).and_then(|it| it.modified()).ok();
-                if Some(e.get().modified_time()) != time {
-                    e.insert(expander()?);
+        Ok(
+            match self
+                .expanders
+                .lock()
+                .unwrap_or_else(PoisonError::into_inner)
+                .entry(path.to_path_buf())
+            {
+                Entry::Vacant(v) => v.insert(expander()?).clone(),
+                Entry::Occupied(mut e) => {
+                    let time = fs::metadata(path).and_then(|it| it.modified()).ok();
+                    if Some(e.get().modified_time()) != time {
+                        e.insert(expander()?);
+                    }
+                    e.get().clone()
                 }
-                e.into_mut()
-            }
-        })
+            },
+        )
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
index 4ce4544243a..1b085520d56 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
@@ -107,7 +107,7 @@ fn assert_expand_impl(
 pub(crate) fn list() -> Vec<String> {
     let dylib_path = proc_macro_test_dylib_path();
     let env = EnvSnapshot::default();
-    let mut srv = ProcMacroSrv::new(&env);
+    let srv = ProcMacroSrv::new(&env);
     let res = srv.list_macros(&dylib_path).unwrap();
     res.into_iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect()
 }
diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
index a3963967610..feee40a1fc9 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
@@ -508,5 +508,5 @@ fn serialize_crate_name<S>(name: &CrateName, se: S) -> Result<S::Ok, S::Error>
 where
     S: serde::Serializer,
 {
-    se.serialize_str(name)
+    se.serialize_str(name.as_str())
 }
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
index f1113831125..28560865436 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -230,7 +230,7 @@ fn rust_project_is_proc_macro_has_proc_macro_dep() {
     let crate_data = &crate_graph[crate_id];
     // Assert that the project crate with `is_proc_macro` has a dependency
     // on the proc_macro sysroot crate.
-    crate_data.dependencies.iter().find(|&dep| dep.name.deref() == "proc_macro").unwrap();
+    crate_data.dependencies.iter().find(|&dep| *dep.name.deref() == sym::proc_macro).unwrap();
 }
 
 #[test]
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
index c24cbb4a311..b8ce2b7430b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -37,7 +37,7 @@ rustc-hash.workspace = true
 serde_json = { workspace = true, features = ["preserve_order"] }
 serde.workspace = true
 serde_derive.workspace = true
-tenthash = "0.4.0"
+tenthash = "1.0.0"
 num_cpus = "1.15.0"
 mimalloc = { version = "0.1.30", default-features = false, optional = true }
 lsp-server.workspace = true
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
index 18c27c84496..4fc6180920f 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -13,7 +13,7 @@ use hir::{
     ModuleDef, Name,
 };
 use hir_def::{
-    body::BodySourceMap,
+    expr_store::BodySourceMap,
     hir::{ExprId, PatId},
     SyntheticSyntax,
 };
@@ -1072,6 +1072,7 @@ impl flags::AnalysisStats {
                     param_names_for_lifetime_elision_hints: true,
                     hide_named_constructor_hints: false,
                     hide_closure_initialization_hints: false,
+                    hide_closure_parameter_hints: false,
                     closure_style: hir::ClosureStyle::ImplFn,
                     max_length: Some(25),
                     closing_brace_hints_min_lines: Some(20),
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
index 28f25975d64..6a3ceb640b9 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -4,7 +4,7 @@
 use project_model::{CargoConfig, RustLibSource};
 use rustc_hash::FxHashSet;
 
-use hir::{db::HirDatabase, Crate, HirFileIdExt, Module};
+use hir::{db::HirDatabase, sym, Crate, HirFileIdExt, Module};
 use ide::{AnalysisHost, AssistResolveStrategy, Diagnostic, DiagnosticsConfig, Severity};
 use ide_db::{base_db::SourceRootDatabase, LineIndexDatabase};
 use load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice};
@@ -60,7 +60,7 @@ impl flags::Diagnostics {
             let file_id = module.definition_source_file_id(db).original_file(db);
             if !visited_files.contains(&file_id) {
                 let crate_name =
-                    module.krate().display_name(db).as_deref().unwrap_or("unknown").to_owned();
+                    module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned();
                 println!(
                     "processing crate: {crate_name}, module: {}",
                     _vfs.file_path(file_id.into())
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
index dc0f722aae6..fe75872105a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -139,45 +139,42 @@ impl flags::Scip {
             let mut occurrences = Vec::new();
             let mut symbols = Vec::new();
 
-            tokens.into_iter().for_each(|(text_range, id)| {
+            for (text_range, id) in tokens.into_iter() {
                 let token = si.tokens.get(id).unwrap();
 
-                let (symbol, enclosing_symbol, is_inherent_impl) =
-                    if let Some(TokenSymbols { symbol, enclosing_symbol, is_inherent_impl }) =
-                        symbol_generator.token_symbols(id, token)
-                    {
-                        (symbol, enclosing_symbol, is_inherent_impl)
-                    } else {
-                        ("".to_owned(), None, false)
-                    };
+                let Some(TokenSymbols { symbol, enclosing_symbol, is_inherent_impl }) =
+                    symbol_generator.token_symbols(id, token)
+                else {
+                    // token did not have a moniker, so there is no reasonable occurrence to emit
+                    // see ide::moniker::def_to_moniker
+                    continue;
+                };
 
-                if !symbol.is_empty() {
-                    let is_defined_in_this_document = match token.definition {
-                        Some(def) => def.file_id == file_id,
-                        _ => false,
-                    };
-                    if is_defined_in_this_document {
-                        if token_ids_emitted.insert(id) {
-                            // token_ids_emitted does deduplication. This checks that this results
-                            // in unique emitted symbols, as otherwise references are ambiguous.
-                            let should_emit = record_error_if_symbol_already_used(
+                let is_defined_in_this_document = match token.definition {
+                    Some(def) => def.file_id == file_id,
+                    _ => false,
+                };
+                if is_defined_in_this_document {
+                    if token_ids_emitted.insert(id) {
+                        // token_ids_emitted does deduplication. This checks that this results
+                        // in unique emitted symbols, as otherwise references are ambiguous.
+                        let should_emit = record_error_if_symbol_already_used(
+                            symbol.clone(),
+                            is_inherent_impl,
+                            relative_path.as_str(),
+                            &line_index,
+                            text_range,
+                        );
+                        if should_emit {
+                            symbols.push(compute_symbol_info(
                                 symbol.clone(),
-                                is_inherent_impl,
-                                relative_path.as_str(),
-                                &line_index,
-                                text_range,
-                            );
-                            if should_emit {
-                                symbols.push(compute_symbol_info(
-                                    symbol.clone(),
-                                    enclosing_symbol,
-                                    token,
-                                ));
-                            }
+                                enclosing_symbol,
+                                token,
+                            ));
                         }
-                    } else {
-                        token_ids_referenced.insert(id);
                     }
+                } else {
+                    token_ids_referenced.insert(id);
                 }
 
                 // If the range of the def and the range of the token are the same, this must be the definition.
@@ -202,7 +199,7 @@ impl flags::Scip {
                     special_fields: Default::default(),
                     enclosing_range: Vec::new(),
                 });
-            });
+            }
 
             if occurrences.is_empty() {
                 continue;
@@ -444,14 +441,14 @@ impl SymbolGenerator {
                     MonikerResult::Moniker(moniker) => TokenSymbols {
                         symbol: scip::symbol::format_symbol(moniker_to_symbol(moniker)),
                         enclosing_symbol: None,
-                        is_inherent_impl: moniker
-                            .identifier
-                            .description
-                            .get(moniker.identifier.description.len() - 2)
-                            .is_some_and(|descriptor| {
+                        is_inherent_impl: match &moniker.identifier.description[..] {
+                            // inherent impls are represented as impl#[SelfType]
+                            [.., descriptor, _] => {
                                 descriptor.desc == MonikerDescriptorKind::Type
                                     && descriptor.name == "impl"
-                            }),
+                            }
+                            _ => false,
+                        },
                     },
                     MonikerResult::Local { enclosing_moniker } => {
                         let local_symbol = scip::types::Symbol::new_local(local_count);
@@ -549,7 +546,9 @@ mod test {
                 continue;
             }
             for &(range, id) in &file.tokens {
-                if range.contains(offset - TextSize::from(1)) {
+                // check if cursor is within token, ignoring token for the module defined by the file (whose range is the whole file)
+                if range.start() != TextSize::from(0) && range.contains(offset - TextSize::from(1))
+                {
                     let token = si.tokens.get(id).unwrap();
                     found_symbol = match token.moniker.as_ref() {
                         None => None,
@@ -885,7 +884,7 @@ pub mod example_mod {
         );
 
         let file = si.files.first().unwrap();
-        let (_, token_id) = file.tokens.first().unwrap();
+        let (_, token_id) = file.tokens.get(1).unwrap(); // first token is file module, second is `bar`
         let token = si.tokens.get(*token_id).unwrap();
 
         assert_eq!(token.documentation.as_ref().map(|d| d.as_str()), Some("foo"));
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs
index 986bd018b42..021b1bff393 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs
@@ -1,5 +1,5 @@
 //! Reports references in code that the IDE layer cannot resolve.
-use hir::{db::HirDatabase, AnyDiagnostic, Crate, HirFileIdExt as _, Module, Semantics};
+use hir::{db::HirDatabase, sym, AnyDiagnostic, Crate, HirFileIdExt as _, Module, Semantics};
 use ide::{AnalysisHost, RootDatabase, TextRange};
 use ide_db::{
     base_db::{SourceDatabase, SourceRootDatabase},
@@ -66,7 +66,7 @@ impl flags::UnresolvedReferences {
             let file_id = module.definition_source_file_id(db).original_file(db);
             if !visited_files.contains(&file_id) {
                 let crate_name =
-                    module.krate().display_name(db).as_deref().unwrap_or("unknown").to_owned();
+                    module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned();
                 let file_path = vfs.file_path(file_id.into());
                 eprintln!("processing crate: {crate_name}, module: {file_path}",);
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 44325fa1a29..e915e55722b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -208,6 +208,8 @@ config_data! {
         /// Whether to hide inlay type hints for `let` statements that initialize to a closure.
         /// Only applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`.
         inlayHints_typeHints_hideClosureInitialization: bool       = false,
+        /// Whether to hide inlay parameter type hints for closures.
+        inlayHints_typeHints_hideClosureParameter:bool             = false,
         /// Whether to hide inlay type hints for constructors.
         inlayHints_typeHints_hideNamedConstructor: bool            = false,
 
@@ -528,7 +530,7 @@ config_data! {
         imports_granularity_enforce: bool              = false,
         /// How imports should be grouped into use statements.
         imports_granularity_group: ImportGranularityDef  = ImportGranularityDef::Crate,
-        /// Group inserted imports by the https://rust-analyzer.github.io/manual.html#auto-import[following order]. Groups are separated by newlines.
+        /// Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
         imports_group_enable: bool                           = true,
         /// Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
         imports_merge_glob: bool           = true,
@@ -1666,6 +1668,9 @@ impl Config {
             hide_closure_initialization_hints: self
                 .inlayHints_typeHints_hideClosureInitialization()
                 .to_owned(),
+            hide_closure_parameter_hints: self
+                .inlayHints_typeHints_hideClosureParameter()
+                .to_owned(),
             closure_style: match self.inlayHints_closureStyle() {
                 ClosureStyle::ImplFn => hir::ClosureStyle::ImplFn,
                 ClosureStyle::RustAnalyzer => hir::ClosureStyle::RANotation,
@@ -3624,21 +3629,9 @@ fn manual(fields: &[SchemaField]) -> String {
         let name = format!("rust-analyzer.{}", field.replace('_', "."));
         let doc = doc_comment_to_string(doc);
         if default.contains('\n') {
-            format_to_acc!(
-                acc,
-                r#"[[{name}]]{name}::
-+
---
-Default:
-----
-{default}
-----
-{doc}
---
-"#
-            )
+            format_to_acc!(acc, " **{name}**\n\nDefault:\n\n```{default}\n\n```\n\n {doc}\n\n ")
         } else {
-            format_to_acc!(acc, "[[{name}]]{name} (default: `{default}`)::\n+\n--\n{doc}--\n")
+            format_to_acc!(acc, "**{name}** (default: {default})\n\n {doc}\n\n")
         }
     })
 }
@@ -3716,7 +3709,7 @@ mod tests {
 
     #[test]
     fn generate_config_documentation() {
-        let docs_path = project_root().join("docs/user/generated_config.adoc");
+        let docs_path = project_root().join("docs/book/src/configuration_generated.md");
         let expected = FullConfigInput::manual();
         ensure_file_contents(docs_path.as_std_path(), &expected);
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index 0f2d7823b7e..b52f64aaace 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -396,6 +396,7 @@ impl GlobalState {
             || !self.config.same_source_root_parent_map(&self.local_roots_parent_map)
         {
             let config_change = {
+                let _p = span!(Level::INFO, "GlobalState::process_changes/config_change").entered();
                 let user_config_path = (|| {
                     let mut p = Config::user_config_dir_path()?;
                     p.push("rust-analyzer.toml");
@@ -569,12 +570,12 @@ impl GlobalState {
         if let Some((method, start)) = self.req_queue.incoming.complete(&response.id) {
             if let Some(err) = &response.error {
                 if err.message.starts_with("server panicked") {
-                    self.poke_rust_analyzer_developer(format!("{}, check the log", err.message))
+                    self.poke_rust_analyzer_developer(format!("{}, check the log", err.message));
                 }
             }
 
             let duration = start.elapsed();
-            tracing::debug!("handled {} - ({}) in {:0.2?}", method, response.id, duration);
+            tracing::debug!(name: "message response", method, %response.id, duration = format_args!("{:0.2?}", duration));
             self.send(response.into());
         }
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
index ff50f7533a6..4683877db69 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
@@ -118,7 +118,7 @@ impl RequestDispatcher<'_> {
             }
             return self;
         }
-        self.on_with_thread_intent::<true, ALLOW_RETRYING, R>(
+        self.on_with_thread_intent::<false, ALLOW_RETRYING, R>(
             ThreadIntent::Worker,
             f,
             Self::content_modified_error,
@@ -147,7 +147,7 @@ impl RequestDispatcher<'_> {
             }
             return self;
         }
-        self.on_with_thread_intent::<true, false, R>(ThreadIntent::Worker, f, on_cancelled)
+        self.on_with_thread_intent::<false, false, R>(ThreadIntent::Worker, f, on_cancelled)
     }
 
     /// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not
@@ -166,7 +166,7 @@ impl RequestDispatcher<'_> {
             }
             return self;
         }
-        self.on_with_thread_intent::<true, ALLOW_RETRYING, R>(
+        self.on_with_thread_intent::<false, ALLOW_RETRYING, R>(
             ThreadIntent::Worker,
             f,
             Self::content_modified_error,
@@ -193,7 +193,7 @@ impl RequestDispatcher<'_> {
             }
             return self;
         }
-        self.on_with_thread_intent::<true, ALLOW_RETRYING, R>(
+        self.on_with_thread_intent::<false, ALLOW_RETRYING, R>(
             ThreadIntent::LatencySensitive,
             f,
             Self::content_modified_error,
@@ -212,7 +212,7 @@ impl RequestDispatcher<'_> {
         R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
         R::Result: Serialize,
     {
-        self.on_with_thread_intent::<false, false, R>(
+        self.on_with_thread_intent::<true, false, R>(
             ThreadIntent::LatencySensitive,
             f,
             Self::content_modified_error,
@@ -231,7 +231,7 @@ impl RequestDispatcher<'_> {
         }
     }
 
-    fn on_with_thread_intent<const MAIN_POOL: bool, const ALLOW_RETRYING: bool, R>(
+    fn on_with_thread_intent<const RUSTFMT: bool, const ALLOW_RETRYING: bool, R>(
         &mut self,
         intent: ThreadIntent,
         f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>,
@@ -251,10 +251,10 @@ impl RequestDispatcher<'_> {
         tracing::debug!(?params);
 
         let world = self.global_state.snapshot();
-        if MAIN_POOL {
-            &mut self.global_state.task_pool.handle
-        } else {
+        if RUSTFMT {
             &mut self.global_state.fmt_pool.handle
+        } else {
+            &mut self.global_state.task_pool.handle
         }
         .spawn(intent, move || {
             let result = panic::catch_unwind(move || {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
index 84ba89d9f31..48856d19e15 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
@@ -74,7 +74,8 @@ pub(crate) fn handle_did_open_text_document(
             tracing::error!("duplicate DidOpenTextDocument: {}", path);
         }
 
-        state.vfs.write().0.set_file_contents(path, Some(params.text_document.text.into_bytes()));
+        let contents = params.text_document.text.into_bytes();
+        state.vfs.write().0.set_file_contents(path, Some(contents));
         if state.config.discover_workspace_config().is_some() {
             tracing::debug!("queuing task");
             let _ = state
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
index 39cbf53eaa2..ed028f1d37b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
@@ -2318,18 +2318,21 @@ fn run_rustfmt(
         }
     };
 
-    tracing::debug!(?command, "created format command");
+    let output = {
+        let _p = tracing::info_span!("rustfmt", ?command).entered();
 
-    let mut rustfmt = command
-        .stdin(Stdio::piped())
-        .stdout(Stdio::piped())
-        .stderr(Stdio::piped())
-        .spawn()
-        .context(format!("Failed to spawn {command:?}"))?;
+        let mut rustfmt = command
+            .stdin(Stdio::piped())
+            .stdout(Stdio::piped())
+            .stderr(Stdio::piped())
+            .spawn()
+            .context(format!("Failed to spawn {command:?}"))?;
 
-    rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?;
+        rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?;
+
+        rustfmt.wait_with_output()?
+    };
 
-    let output = rustfmt.wait_with_output()?;
     let captured_stdout = String::from_utf8(output.stdout)?;
     let captured_stderr = String::from_utf8(output.stderr).unwrap_or_default();
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
index ccffa7a671e..1221f7c7012 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
@@ -50,7 +50,7 @@ mod integrated_benchmarks;
 use hir::Mutability;
 use ide::{CompletionItem, CompletionItemRefMode, CompletionRelevance};
 use serde::de::DeserializeOwned;
-use tenthash::TentHasher;
+use tenthash::TentHash;
 
 pub use crate::{
     lsp::capabilities::server_capabilities, main_loop::main_loop, reload::ws_to_crate_graph,
@@ -66,7 +66,7 @@ pub fn from_json<T: DeserializeOwned>(
 }
 
 fn completion_item_hash(item: &CompletionItem, is_ref_completion: bool) -> [u8; 20] {
-    fn hash_completion_relevance(hasher: &mut TentHasher, relevance: &CompletionRelevance) {
+    fn hash_completion_relevance(hasher: &mut TentHash, relevance: &CompletionRelevance) {
         use ide_completion::{
             CompletionRelevancePostfixMatch, CompletionRelevanceReturnType,
             CompletionRelevanceTypeMatch,
@@ -79,71 +79,97 @@ fn completion_item_hash(item: &CompletionItem, is_ref_completion: bool) -> [u8;
             u8::from(relevance.requires_import),
             u8::from(relevance.is_private_editable),
         ]);
-        if let Some(type_match) = &relevance.type_match {
-            let label = match type_match {
-                CompletionRelevanceTypeMatch::CouldUnify => "could_unify",
-                CompletionRelevanceTypeMatch::Exact => "exact",
-            };
-            hasher.update(label);
+
+        match relevance.type_match {
+            None => hasher.update([0u8]),
+            Some(CompletionRelevanceTypeMatch::CouldUnify) => hasher.update([1u8]),
+            Some(CompletionRelevanceTypeMatch::Exact) => hasher.update([2u8]),
         }
+
+        hasher.update([u8::from(relevance.trait_.is_some())]);
         if let Some(trait_) = &relevance.trait_ {
             hasher.update([u8::from(trait_.is_op_method), u8::from(trait_.notable_trait)]);
         }
-        if let Some(postfix_match) = &relevance.postfix_match {
-            let label = match postfix_match {
-                CompletionRelevancePostfixMatch::NonExact => "non_exact",
-                CompletionRelevancePostfixMatch::Exact => "exact",
-            };
-            hasher.update(label);
+
+        match relevance.postfix_match {
+            None => hasher.update([0u8]),
+            Some(CompletionRelevancePostfixMatch::NonExact) => hasher.update([1u8]),
+            Some(CompletionRelevancePostfixMatch::Exact) => hasher.update([2u8]),
         }
+
+        hasher.update([u8::from(relevance.function.is_some())]);
         if let Some(function) = &relevance.function {
             hasher.update([u8::from(function.has_params), u8::from(function.has_self_param)]);
-            let label = match function.return_type {
-                CompletionRelevanceReturnType::Other => "other",
-                CompletionRelevanceReturnType::DirectConstructor => "direct_constructor",
-                CompletionRelevanceReturnType::Constructor => "constructor",
-                CompletionRelevanceReturnType::Builder => "builder",
+            let discriminant: u8 = match function.return_type {
+                CompletionRelevanceReturnType::Other => 0,
+                CompletionRelevanceReturnType::DirectConstructor => 1,
+                CompletionRelevanceReturnType::Constructor => 2,
+                CompletionRelevanceReturnType::Builder => 3,
             };
-            hasher.update(label);
+            hasher.update([discriminant]);
         }
     }
 
-    let mut hasher = TentHasher::new();
+    let mut hasher = TentHash::new();
     hasher.update([
         u8::from(is_ref_completion),
         u8::from(item.is_snippet),
         u8::from(item.deprecated),
         u8::from(item.trigger_call_info),
     ]);
+
+    hasher.update(item.label.primary.len().to_ne_bytes());
     hasher.update(&item.label.primary);
+
+    hasher.update([u8::from(item.label.detail_left.is_some())]);
     if let Some(label_detail) = &item.label.detail_left {
+        hasher.update(label_detail.len().to_ne_bytes());
         hasher.update(label_detail);
     }
+
+    hasher.update([u8::from(item.label.detail_right.is_some())]);
     if let Some(label_detail) = &item.label.detail_right {
+        hasher.update(label_detail.len().to_ne_bytes());
         hasher.update(label_detail);
     }
+
     // NB: do not hash edits or source range, as those may change between the time the client sends the resolve request
     // and the time it receives it: some editors do allow changing the buffer between that, leading to ranges being different.
     //
     // Documentation hashing is skipped too, as it's a large blob to process,
     // while not really making completion properties more unique as they are already.
-    hasher.update(item.kind.tag());
+
+    let kind_tag = item.kind.tag();
+    hasher.update(kind_tag.len().to_ne_bytes());
+    hasher.update(kind_tag);
+
+    hasher.update(item.lookup.len().to_ne_bytes());
     hasher.update(&item.lookup);
+
+    hasher.update([u8::from(item.detail.is_some())]);
     if let Some(detail) = &item.detail {
+        hasher.update(detail.len().to_ne_bytes());
         hasher.update(detail);
     }
+
     hash_completion_relevance(&mut hasher, &item.relevance);
+
+    hasher.update([u8::from(item.ref_match.is_some())]);
     if let Some((ref_mode, text_size)) = &item.ref_match {
-        let prefix = match ref_mode {
-            CompletionItemRefMode::Reference(Mutability::Shared) => "&",
-            CompletionItemRefMode::Reference(Mutability::Mut) => "&mut ",
-            CompletionItemRefMode::Dereference => "*",
+        let discriminant = match ref_mode {
+            CompletionItemRefMode::Reference(Mutability::Shared) => 0u8,
+            CompletionItemRefMode::Reference(Mutability::Mut) => 1u8,
+            CompletionItemRefMode::Dereference => 2u8,
         };
-        hasher.update(prefix);
-        hasher.update(u32::from(*text_size).to_le_bytes());
+        hasher.update([discriminant]);
+        hasher.update(u32::from(*text_size).to_ne_bytes());
     }
+
+    hasher.update(item.import_to_add.len().to_ne_bytes());
     for import_path in &item.import_to_add {
+        hasher.update(import_path.len().to_ne_bytes());
         hasher.update(import_path);
     }
+
     hasher.finalize()
 }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs
index 991c10743f7..3c21e199252 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs
@@ -24,7 +24,7 @@ macro_rules! define_semantic_token_types {
         }
 
         pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[
-            $(SemanticTokenType::$standard,)*
+            $(self::types::$standard,)*
             $(self::types::$custom),*
         ];
 
@@ -32,7 +32,7 @@ macro_rules! define_semantic_token_types {
             use self::types::*;
             $(
                 if token == $custom {
-                    None $(.or(Some(SemanticTokenType::$fallback)))?
+                    None $(.or(Some(self::types::$fallback)))?
                 } else
             )*
             { Some(token )}
@@ -60,6 +60,7 @@ define_semantic_token_types![
         STRUCT,
         TYPE_PARAMETER,
         VARIABLE,
+        TYPE,
     }
 
     custom {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index d6dc8b521fd..ebc65373b52 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -253,6 +253,11 @@ impl GlobalState {
         &self,
         inbox: &Receiver<lsp_server::Message>,
     ) -> Result<Option<Event>, crossbeam_channel::RecvError> {
+        // Make sure we reply to formatting requests ASAP so the editor doesn't block
+        if let Ok(task) = self.fmt_pool.receiver.try_recv() {
+            return Ok(Some(Event::Task(task)));
+        }
+
         select! {
             recv(inbox) -> msg =>
                 return Ok(msg.ok().map(Event::Lsp)),
@@ -320,26 +325,30 @@ impl GlobalState {
                 }
 
                 for progress in prime_caches_progress {
-                    let (state, message, fraction);
+                    let (state, message, fraction, title);
                     match progress {
                         PrimeCachesProgress::Begin => {
                             state = Progress::Begin;
                             message = None;
                             fraction = 0.0;
+                            title = "Indexing";
                         }
                         PrimeCachesProgress::Report(report) => {
                             state = Progress::Report;
+                            title = report.work_type;
 
-                            message = match &report.crates_currently_indexing[..] {
+                            message = match &*report.crates_currently_indexing {
                                 [crate_name] => Some(format!(
-                                    "{}/{} ({crate_name})",
-                                    report.crates_done, report.crates_total
+                                    "{}/{} ({})",
+                                    report.crates_done,
+                                    report.crates_total,
+                                    crate_name.as_str(),
                                 )),
                                 [crate_name, rest @ ..] => Some(format!(
                                     "{}/{} ({} + {} more)",
                                     report.crates_done,
                                     report.crates_total,
-                                    crate_name,
+                                    crate_name.as_str(),
                                     rest.len()
                                 )),
                                 _ => None,
@@ -351,6 +360,7 @@ impl GlobalState {
                             state = Progress::End;
                             message = None;
                             fraction = 1.0;
+                            title = "Indexing";
 
                             self.prime_caches_queue.op_completed(());
                             if cancelled {
@@ -360,7 +370,13 @@ impl GlobalState {
                         }
                     };
 
-                    self.report_progress("Indexing", state, message, Some(fraction), None);
+                    self.report_progress(
+                        title,
+                        state,
+                        message,
+                        Some(fraction),
+                        Some("rustAnalyzer/cachePriming".to_owned()),
+                    );
                 }
             }
             Event::Vfs(message) => {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
index 0add2cdf5a7..d18e5770477 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -701,8 +701,7 @@ impl GlobalState {
 
         let (crate_graph, proc_macro_paths, ws_data) = {
             // Create crate graph from all the workspaces
-            let vfs = &mut self.vfs.write().0;
-
+            let vfs = &self.vfs.read().0;
             let load = |path: &AbsPath| {
                 let vfs_path = vfs::VfsPath::from(path.to_path_buf());
                 self.crate_graph_file_dependencies.insert(vfs_path.clone());
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs
index 2bcd8505e81..c5de69bb9fc 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs
@@ -1,6 +1,8 @@
 //! A thin wrapper around [`stdx::thread::Pool`] which threads a sender through spawned jobs.
 //! It is used in [`crate::global_state::GlobalState`] throughout the main loop.
 
+use std::panic::UnwindSafe;
+
 use crossbeam_channel::Sender;
 use stdx::thread::{Pool, ThreadIntent};
 
@@ -18,7 +20,7 @@ impl<T> TaskPool<T> {
 
     pub(crate) fn spawn<F>(&mut self, intent: ThreadIntent, task: F)
     where
-        F: FnOnce() -> T + Send + 'static,
+        F: FnOnce() -> T + Send + UnwindSafe + 'static,
         T: Send + 'static,
     {
         self.pool.spawn(intent, {
@@ -29,7 +31,7 @@ impl<T> TaskPool<T> {
 
     pub(crate) fn spawn_with_sender<F>(&mut self, intent: ThreadIntent, task: F)
     where
-        F: FnOnce(Sender<T>) + Send + 'static,
+        F: FnOnce(Sender<T>) + Send + UnwindSafe + 'static,
         T: Send + 'static,
     {
         self.pool.spawn(intent, {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/cli.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/cli.rs
index fba54666912..4ef930e9854 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/cli.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/cli.rs
@@ -43,89 +43,93 @@ mod tests {
     expect![[r#"
         {"id":2,"type":"vertex","label":"foldingRangeResult","result":[{"startLine":2,"startCharacter":43,"endLine":6,"endCharacter":1},{"startLine":3,"startCharacter":19,"endLine":5,"endCharacter":5},{"startLine":9,"startCharacter":10,"endLine":12,"endCharacter":1}]}
         {"id":3,"type":"edge","label":"textDocument/foldingRange","inV":2,"outV":1}
-        {"id":4,"type":"vertex","label":"range","start":{"line":0,"character":3},"end":{"line":0,"character":8}}
+        {"id":4,"type":"vertex","label":"range","start":{"line":0,"character":0},"end":{"line":13,"character":0}}
         {"id":5,"type":"vertex","label":"resultSet"}
         {"id":6,"type":"edge","label":"next","inV":5,"outV":4}
-        {"id":7,"type":"vertex","label":"range","start":{"line":2,"character":13},"end":{"line":2,"character":43}}
+        {"id":7,"type":"vertex","label":"range","start":{"line":0,"character":3},"end":{"line":0,"character":8}}
         {"id":8,"type":"vertex","label":"resultSet"}
         {"id":9,"type":"edge","label":"next","inV":8,"outV":7}
-        {"id":10,"type":"vertex","label":"range","start":{"line":8,"character":0},"end":{"line":8,"character":30}}
-        {"id":11,"type":"edge","label":"next","inV":8,"outV":10}
-        {"id":12,"type":"vertex","label":"range","start":{"line":8,"character":32},"end":{"line":8,"character":39}}
-        {"id":13,"type":"vertex","label":"resultSet"}
-        {"id":14,"type":"edge","label":"next","inV":13,"outV":12}
-        {"id":15,"type":"vertex","label":"range","start":{"line":9,"character":4},"end":{"line":9,"character":9}}
+        {"id":10,"type":"vertex","label":"range","start":{"line":2,"character":13},"end":{"line":2,"character":43}}
+        {"id":11,"type":"vertex","label":"resultSet"}
+        {"id":12,"type":"edge","label":"next","inV":11,"outV":10}
+        {"id":13,"type":"vertex","label":"range","start":{"line":8,"character":0},"end":{"line":8,"character":30}}
+        {"id":14,"type":"edge","label":"next","inV":11,"outV":13}
+        {"id":15,"type":"vertex","label":"range","start":{"line":8,"character":32},"end":{"line":8,"character":39}}
         {"id":16,"type":"vertex","label":"resultSet"}
         {"id":17,"type":"edge","label":"next","inV":16,"outV":15}
-        {"id":18,"type":"vertex","label":"range","start":{"line":10,"character":8},"end":{"line":10,"character":13}}
+        {"id":18,"type":"vertex","label":"range","start":{"line":9,"character":4},"end":{"line":9,"character":9}}
         {"id":19,"type":"vertex","label":"resultSet"}
         {"id":20,"type":"edge","label":"next","inV":19,"outV":18}
-        {"id":21,"type":"vertex","label":"range","start":{"line":11,"character":4},"end":{"line":11,"character":34}}
-        {"id":22,"type":"edge","label":"next","inV":8,"outV":21}
-        {"id":23,"type":"vertex","label":"range","start":{"line":11,"character":36},"end":{"line":11,"character":43}}
-        {"id":24,"type":"vertex","label":"resultSet"}
-        {"id":25,"type":"edge","label":"next","inV":24,"outV":23}
-        {"id":26,"type":"edge","label":"contains","inVs":[4,7,10,12,15,18,21,23],"outV":1}
-        {"id":27,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\n#[allow]\n```\n\n---\n\nValid forms are:\n\n* \\#\\[allow(lint1, lint2, ..., /\\*opt\\*/ reason = \"...\")\\]"}}}
-        {"id":28,"type":"edge","label":"textDocument/hover","inV":27,"outV":5}
-        {"id":29,"type":"vertex","label":"referenceResult"}
-        {"id":30,"type":"edge","label":"textDocument/references","inV":29,"outV":5}
-        {"id":31,"type":"edge","label":"item","document":1,"property":"references","inVs":[4],"outV":29}
-        {"id":32,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmacro_rules! generate_const_from_identifier\n```"}}}
-        {"id":33,"type":"edge","label":"textDocument/hover","inV":32,"outV":8}
-        {"id":34,"type":"vertex","label":"packageInformation","name":"foo","manager":"cargo","version":"0.0.0"}
-        {"id":35,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::generate_const_from_identifier","unique":"scheme","kind":"export"}
-        {"id":36,"type":"edge","label":"packageInformation","inV":34,"outV":35}
-        {"id":37,"type":"edge","label":"moniker","inV":35,"outV":8}
-        {"id":38,"type":"vertex","label":"definitionResult"}
-        {"id":39,"type":"edge","label":"item","document":1,"inVs":[7],"outV":38}
-        {"id":40,"type":"edge","label":"textDocument/definition","inV":38,"outV":8}
-        {"id":41,"type":"vertex","label":"referenceResult"}
-        {"id":42,"type":"edge","label":"textDocument/references","inV":41,"outV":8}
-        {"id":43,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[7],"outV":41}
-        {"id":44,"type":"edge","label":"item","document":1,"property":"references","inVs":[10,21],"outV":41}
-        {"id":45,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nconst REQ_001: &str = \"encoded_data\"\n```"}}}
-        {"id":46,"type":"edge","label":"textDocument/hover","inV":45,"outV":13}
-        {"id":47,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::REQ_001","unique":"scheme","kind":"export"}
-        {"id":48,"type":"edge","label":"packageInformation","inV":34,"outV":47}
-        {"id":49,"type":"edge","label":"moniker","inV":47,"outV":13}
-        {"id":50,"type":"vertex","label":"definitionResult"}
-        {"id":51,"type":"edge","label":"item","document":1,"inVs":[12],"outV":50}
-        {"id":52,"type":"edge","label":"textDocument/definition","inV":50,"outV":13}
-        {"id":53,"type":"vertex","label":"referenceResult"}
-        {"id":54,"type":"edge","label":"textDocument/references","inV":53,"outV":13}
-        {"id":55,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[12],"outV":53}
-        {"id":56,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmod tests\n```"}}}
-        {"id":57,"type":"edge","label":"textDocument/hover","inV":56,"outV":16}
-        {"id":58,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests","unique":"scheme","kind":"export"}
-        {"id":59,"type":"edge","label":"packageInformation","inV":34,"outV":58}
-        {"id":60,"type":"edge","label":"moniker","inV":58,"outV":16}
-        {"id":61,"type":"vertex","label":"definitionResult"}
-        {"id":62,"type":"edge","label":"item","document":1,"inVs":[15],"outV":61}
-        {"id":63,"type":"edge","label":"textDocument/definition","inV":61,"outV":16}
-        {"id":64,"type":"vertex","label":"referenceResult"}
-        {"id":65,"type":"edge","label":"textDocument/references","inV":64,"outV":16}
-        {"id":66,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[15],"outV":64}
-        {"id":67,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nextern crate foo\n```"}}}
-        {"id":68,"type":"edge","label":"textDocument/hover","inV":67,"outV":19}
-        {"id":69,"type":"vertex","label":"definitionResult"}
-        {"id":70,"type":"vertex","label":"range","start":{"line":0,"character":0},"end":{"line":13,"character":0}}
-        {"id":71,"type":"edge","label":"contains","inVs":[70],"outV":1}
-        {"id":72,"type":"edge","label":"item","document":1,"inVs":[70],"outV":69}
-        {"id":73,"type":"edge","label":"textDocument/definition","inV":69,"outV":19}
-        {"id":74,"type":"vertex","label":"referenceResult"}
-        {"id":75,"type":"edge","label":"textDocument/references","inV":74,"outV":19}
-        {"id":76,"type":"edge","label":"item","document":1,"property":"references","inVs":[18],"outV":74}
-        {"id":77,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo::tests\n```\n\n```rust\nconst REQ_002: &str = \"encoded_data\"\n```"}}}
-        {"id":78,"type":"edge","label":"textDocument/hover","inV":77,"outV":24}
-        {"id":79,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests::REQ_002","unique":"scheme","kind":"export"}
-        {"id":80,"type":"edge","label":"packageInformation","inV":34,"outV":79}
-        {"id":81,"type":"edge","label":"moniker","inV":79,"outV":24}
-        {"id":82,"type":"vertex","label":"definitionResult"}
-        {"id":83,"type":"edge","label":"item","document":1,"inVs":[23],"outV":82}
-        {"id":84,"type":"edge","label":"textDocument/definition","inV":82,"outV":24}
-        {"id":85,"type":"vertex","label":"referenceResult"}
-        {"id":86,"type":"edge","label":"textDocument/references","inV":85,"outV":24}
-        {"id":87,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[23],"outV":85}
+        {"id":21,"type":"vertex","label":"range","start":{"line":10,"character":8},"end":{"line":10,"character":13}}
+        {"id":22,"type":"edge","label":"next","inV":5,"outV":21}
+        {"id":23,"type":"vertex","label":"range","start":{"line":11,"character":4},"end":{"line":11,"character":34}}
+        {"id":24,"type":"edge","label":"next","inV":11,"outV":23}
+        {"id":25,"type":"vertex","label":"range","start":{"line":11,"character":36},"end":{"line":11,"character":43}}
+        {"id":26,"type":"vertex","label":"resultSet"}
+        {"id":27,"type":"edge","label":"next","inV":26,"outV":25}
+        {"id":28,"type":"edge","label":"contains","inVs":[4,7,10,13,15,18,21,23,25],"outV":1}
+        {"id":29,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nextern crate foo\n```"}}}
+        {"id":30,"type":"edge","label":"textDocument/hover","inV":29,"outV":5}
+        {"id":31,"type":"vertex","label":"packageInformation","name":"foo","manager":"cargo","version":"0.0.0"}
+        {"id":32,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::crate","unique":"scheme","kind":"export"}
+        {"id":33,"type":"edge","label":"packageInformation","inV":31,"outV":32}
+        {"id":34,"type":"edge","label":"moniker","inV":32,"outV":5}
+        {"id":35,"type":"vertex","label":"definitionResult"}
+        {"id":36,"type":"edge","label":"item","document":1,"inVs":[4],"outV":35}
+        {"id":37,"type":"edge","label":"textDocument/definition","inV":35,"outV":5}
+        {"id":38,"type":"vertex","label":"referenceResult"}
+        {"id":39,"type":"edge","label":"textDocument/references","inV":38,"outV":5}
+        {"id":40,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[4],"outV":38}
+        {"id":41,"type":"edge","label":"item","document":1,"property":"references","inVs":[21],"outV":38}
+        {"id":42,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\n#[allow]\n```\n\n---\n\nValid forms are:\n\n* \\#\\[allow(lint1, lint2, ..., /\\*opt\\*/ reason = \"...\")\\]"}}}
+        {"id":43,"type":"edge","label":"textDocument/hover","inV":42,"outV":8}
+        {"id":44,"type":"vertex","label":"referenceResult"}
+        {"id":45,"type":"edge","label":"textDocument/references","inV":44,"outV":8}
+        {"id":46,"type":"edge","label":"item","document":1,"property":"references","inVs":[7],"outV":44}
+        {"id":47,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmacro_rules! generate_const_from_identifier\n```"}}}
+        {"id":48,"type":"edge","label":"textDocument/hover","inV":47,"outV":11}
+        {"id":49,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::generate_const_from_identifier","unique":"scheme","kind":"export"}
+        {"id":50,"type":"edge","label":"packageInformation","inV":31,"outV":49}
+        {"id":51,"type":"edge","label":"moniker","inV":49,"outV":11}
+        {"id":52,"type":"vertex","label":"definitionResult"}
+        {"id":53,"type":"edge","label":"item","document":1,"inVs":[10],"outV":52}
+        {"id":54,"type":"edge","label":"textDocument/definition","inV":52,"outV":11}
+        {"id":55,"type":"vertex","label":"referenceResult"}
+        {"id":56,"type":"edge","label":"textDocument/references","inV":55,"outV":11}
+        {"id":57,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[10],"outV":55}
+        {"id":58,"type":"edge","label":"item","document":1,"property":"references","inVs":[13,23],"outV":55}
+        {"id":59,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nconst REQ_001: &str = \"encoded_data\"\n```"}}}
+        {"id":60,"type":"edge","label":"textDocument/hover","inV":59,"outV":16}
+        {"id":61,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::REQ_001","unique":"scheme","kind":"export"}
+        {"id":62,"type":"edge","label":"packageInformation","inV":31,"outV":61}
+        {"id":63,"type":"edge","label":"moniker","inV":61,"outV":16}
+        {"id":64,"type":"vertex","label":"definitionResult"}
+        {"id":65,"type":"edge","label":"item","document":1,"inVs":[15],"outV":64}
+        {"id":66,"type":"edge","label":"textDocument/definition","inV":64,"outV":16}
+        {"id":67,"type":"vertex","label":"referenceResult"}
+        {"id":68,"type":"edge","label":"textDocument/references","inV":67,"outV":16}
+        {"id":69,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[15],"outV":67}
+        {"id":70,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmod tests\n```"}}}
+        {"id":71,"type":"edge","label":"textDocument/hover","inV":70,"outV":19}
+        {"id":72,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests","unique":"scheme","kind":"export"}
+        {"id":73,"type":"edge","label":"packageInformation","inV":31,"outV":72}
+        {"id":74,"type":"edge","label":"moniker","inV":72,"outV":19}
+        {"id":75,"type":"vertex","label":"definitionResult"}
+        {"id":76,"type":"edge","label":"item","document":1,"inVs":[18],"outV":75}
+        {"id":77,"type":"edge","label":"textDocument/definition","inV":75,"outV":19}
+        {"id":78,"type":"vertex","label":"referenceResult"}
+        {"id":79,"type":"edge","label":"textDocument/references","inV":78,"outV":19}
+        {"id":80,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[18],"outV":78}
+        {"id":81,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo::tests\n```\n\n```rust\nconst REQ_002: &str = \"encoded_data\"\n```"}}}
+        {"id":82,"type":"edge","label":"textDocument/hover","inV":81,"outV":26}
+        {"id":83,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests::REQ_002","unique":"scheme","kind":"export"}
+        {"id":84,"type":"edge","label":"packageInformation","inV":31,"outV":83}
+        {"id":85,"type":"edge","label":"moniker","inV":83,"outV":26}
+        {"id":86,"type":"vertex","label":"definitionResult"}
+        {"id":87,"type":"edge","label":"item","document":1,"inVs":[25],"outV":86}
+        {"id":88,"type":"edge","label":"textDocument/definition","inV":86,"outV":26}
+        {"id":89,"type":"vertex","label":"referenceResult"}
+        {"id":90,"type":"edge","label":"textDocument/references","inV":89,"outV":26}
+        {"id":91,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[25],"outV":89}
     "#]].assert_eq(stdout);
 }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/testdir.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/testdir.rs
index d113bd51278..409be2894fe 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/testdir.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/testdir.rs
@@ -43,10 +43,15 @@ impl TestDir {
             }
             fs::create_dir_all(&path).unwrap();
 
-            #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
+            #[cfg(any(
+                target_os = "macos",
+                target_os = "linux",
+                target_os = "windows",
+                target_os = "freebsd"
+            ))]
             if symlink {
                 let symlink_path = base.join(format!("{pid}_{cnt}_symlink"));
-                #[cfg(any(target_os = "macos", target_os = "linux"))]
+                #[cfg(any(target_os = "macos", target_os = "linux", target_os = "freebsd"))]
                 std::os::unix::fs::symlink(path, &symlink_path).unwrap();
 
                 #[cfg(target_os = "windows")]
diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs
index 2ddd7da74c2..9acc1de922a 100644
--- a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs
+++ b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs
@@ -7,9 +7,12 @@
 //! The thread pool is implemented entirely using
 //! the threading utilities in [`crate::thread`].
 
-use std::sync::{
-    atomic::{AtomicUsize, Ordering},
-    Arc,
+use std::{
+    panic::{self, UnwindSafe},
+    sync::{
+        atomic::{AtomicUsize, Ordering},
+        Arc,
+    },
 };
 
 use crossbeam_channel::{Receiver, Sender};
@@ -25,13 +28,13 @@ pub struct Pool {
     // so that the channel is actually closed
     // before we join the worker threads!
     job_sender: Sender<Job>,
-    _handles: Vec<JoinHandle>,
+    _handles: Box<[JoinHandle]>,
     extant_tasks: Arc<AtomicUsize>,
 }
 
 struct Job {
     requested_intent: ThreadIntent,
-    f: Box<dyn FnOnce() + Send + 'static>,
+    f: Box<dyn FnOnce() + Send + UnwindSafe + 'static>,
 }
 
 impl Pool {
@@ -47,6 +50,7 @@ impl Pool {
             let handle = Builder::new(INITIAL_INTENT)
                 .stack_size(STACK_SIZE)
                 .name("Worker".into())
+                .allow_leak(true)
                 .spawn({
                     let extant_tasks = Arc::clone(&extant_tasks);
                     let job_receiver: Receiver<Job> = job_receiver.clone();
@@ -58,7 +62,8 @@ impl Pool {
                                 current_intent = job.requested_intent;
                             }
                             extant_tasks.fetch_add(1, Ordering::SeqCst);
-                            (job.f)();
+                            // discard the panic, we should've logged the backtrace already
+                            _ = panic::catch_unwind(job.f);
                             extant_tasks.fetch_sub(1, Ordering::SeqCst);
                         }
                     }
@@ -68,12 +73,12 @@ impl Pool {
             handles.push(handle);
         }
 
-        Pool { _handles: handles, extant_tasks, job_sender }
+        Pool { _handles: handles.into_boxed_slice(), extant_tasks, job_sender }
     }
 
     pub fn spawn<F>(&self, intent: ThreadIntent, f: F)
     where
-        F: FnOnce() + Send + 'static,
+        F: FnOnce() + Send + UnwindSafe + 'static,
     {
         let f = Box::new(move || {
             if cfg!(debug_assertions) {
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index 4e2a70d6cd9..bbb8413cbc0 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -241,7 +241,7 @@ RecordFieldList =
 
 RecordField =
   Attr* Visibility?
-  Name ':' Type
+  Name ':' Type ('=' Expr)?
 
 TupleFieldList =
   '(' fields:(TupleField (',' TupleField)* ','?)? ')'
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
index 69e2a9f9c1b..58c76a456ab 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -1,4 +1,4 @@
-//! Generated by `cargo codegen grammar`, do not edit by hand.
+//! Generated by `cargo xtask codegen grammar`, do not edit by hand.
 
 #![allow(non_snake_case)]
 use crate::{
@@ -1539,9 +1539,13 @@ impl ast::HasName for RecordField {}
 impl ast::HasVisibility for RecordField {}
 impl RecordField {
     #[inline]
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+    #[inline]
     pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     #[inline]
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
+    #[inline]
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/tokens.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/tokens.rs
index 85d20c2bd8c..df2e9619db1 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/tokens.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/tokens.rs
@@ -1,4 +1,4 @@
-//! Generated by `cargo codegen grammar`, do not edit by hand.
+//! Generated by `cargo xtask codegen grammar`, do not edit by hand.
 
 use crate::{
     ast::AstToken,
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
index 28089ffb377..5d33f132ac1 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
@@ -5,7 +5,122 @@ use crate::{
     match_ast, AstNode, SyntaxNode,
 };
 
+#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
+pub enum ExprPrecedence {
+    // return, break, yield, closures
+    Jump,
+    // = += -= *= /= %= &= |= ^= <<= >>=
+    Assign,
+    // .. ..=
+    Range,
+    // ||
+    LOr,
+    // &&
+    LAnd,
+    // == != < > <= >=
+    Compare,
+    // |
+    BitOr,
+    // ^
+    BitXor,
+    // &
+    BitAnd,
+    // << >>
+    Shift,
+    // + -
+    Sum,
+    // * / %
+    Product,
+    // as
+    Cast,
+    // unary - * ! & &mut
+    Prefix,
+    // paths, loops, function calls, array indexing, field expressions, method calls
+    Unambiguous,
+}
+
+#[derive(PartialEq, Debug)]
+pub enum Fixity {
+    /// The operator is left-associative
+    Left,
+    /// The operator is right-associative
+    Right,
+    /// The operator is not associative
+    None,
+}
+
+pub fn precedence(expr: &ast::Expr) -> ExprPrecedence {
+    match expr {
+        Expr::ClosureExpr(closure) => match closure.ret_type() {
+            None => ExprPrecedence::Jump,
+            Some(_) => ExprPrecedence::Unambiguous,
+        },
+
+        Expr::BreakExpr(_)
+        | Expr::ContinueExpr(_)
+        | Expr::ReturnExpr(_)
+        | Expr::YeetExpr(_)
+        | Expr::YieldExpr(_) => ExprPrecedence::Jump,
+
+        Expr::RangeExpr(..) => ExprPrecedence::Range,
+
+        Expr::BinExpr(bin_expr) => match bin_expr.op_kind() {
+            Some(it) => match it {
+                BinaryOp::LogicOp(logic_op) => match logic_op {
+                    ast::LogicOp::And => ExprPrecedence::LAnd,
+                    ast::LogicOp::Or => ExprPrecedence::LOr,
+                },
+                BinaryOp::ArithOp(arith_op) => match arith_op {
+                    ast::ArithOp::Add | ast::ArithOp::Sub => ExprPrecedence::Sum,
+                    ast::ArithOp::Div | ast::ArithOp::Rem | ast::ArithOp::Mul => {
+                        ExprPrecedence::Product
+                    }
+                    ast::ArithOp::Shl | ast::ArithOp::Shr => ExprPrecedence::Shift,
+                    ast::ArithOp::BitXor => ExprPrecedence::BitXor,
+                    ast::ArithOp::BitOr => ExprPrecedence::BitOr,
+                    ast::ArithOp::BitAnd => ExprPrecedence::BitAnd,
+                },
+                BinaryOp::CmpOp(_) => ExprPrecedence::Compare,
+                BinaryOp::Assignment { .. } => ExprPrecedence::Assign,
+            },
+            None => ExprPrecedence::Unambiguous,
+        },
+        Expr::CastExpr(_) => ExprPrecedence::Cast,
+
+        Expr::LetExpr(_) | Expr::PrefixExpr(_) | Expr::RefExpr(_) => ExprPrecedence::Prefix,
+
+        Expr::ArrayExpr(_)
+        | Expr::AsmExpr(_)
+        | Expr::AwaitExpr(_)
+        | Expr::BecomeExpr(_)
+        | Expr::BlockExpr(_)
+        | Expr::CallExpr(_)
+        | Expr::FieldExpr(_)
+        | Expr::ForExpr(_)
+        | Expr::FormatArgsExpr(_)
+        | Expr::IfExpr(_)
+        | Expr::IndexExpr(_)
+        | Expr::Literal(_)
+        | Expr::LoopExpr(_)
+        | Expr::MacroExpr(_)
+        | Expr::MatchExpr(_)
+        | Expr::MethodCallExpr(_)
+        | Expr::OffsetOfExpr(_)
+        | Expr::ParenExpr(_)
+        | Expr::PathExpr(_)
+        | Expr::RecordExpr(_)
+        | Expr::TryExpr(_)
+        | Expr::TupleExpr(_)
+        | Expr::UnderscoreExpr(_)
+        | Expr::WhileExpr(_) => ExprPrecedence::Unambiguous,
+    }
+}
+
 impl Expr {
+    pub fn precedence(&self) -> ExprPrecedence {
+        precedence(self)
+    }
+
     // Implementation is based on
     // - https://doc.rust-lang.org/reference/expressions.html#expression-precedence
     // - https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html
@@ -261,7 +376,7 @@ impl Expr {
     }
 
     /// Returns true if self is one of `return`, `break`, `continue` or `yield` with **no associated value**.
-    fn is_ret_like_with_no_value(&self) -> bool {
+    pub fn is_ret_like_with_no_value(&self) -> bool {
         use Expr::*;
 
         match self {
diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
index 866379d940e..ca596583590 100644
--- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
@@ -258,15 +258,7 @@ impl ChangeFixture {
                 let to_id = crates[&to];
                 let sysroot = crate_graph[to_id].origin.is_lang();
                 crate_graph
-                    .add_dep(
-                        from_id,
-                        Dependency::with_prelude(
-                            CrateName::new(&to).unwrap(),
-                            to_id,
-                            prelude,
-                            sysroot,
-                        ),
-                    )
+                    .add_dep(from_id, Dependency::with_prelude(to.clone(), to_id, prelude, sysroot))
                     .unwrap();
             }
         }
diff --git a/src/tools/rust-analyzer/docs/book/README.md b/src/tools/rust-analyzer/docs/book/README.md
new file mode 100644
index 00000000000..a9d10df6643
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/README.md
@@ -0,0 +1,29 @@
+# rust-analyzer documentation
+
+The rust analyzer manual uses [mdbook](https://rust-lang.github.io/mdBook/).
+
+## Quick start
+
+To run the documentation site locally:
+
+```shell
+cargo install mdbook
+cd docs/book
+mdbook serve
+# make changes to documentation files in doc/book/src
+# ...
+```
+
+mdbook will rebuild the documentation as changes are made.
+
+## Making updates
+
+While not required, installing the mdbook binary can be helfpul in order to see the changes.
+Start with the mdbook [User Guide](https://rust-lang.github.io/mdBook/guide/installation.html) to familiarize yourself with the tool.
+
+## Generated documentation
+
+Four sections are generated dynamically: assists, configuration, diagnostics and features. Their content is found in the `generated.md` files
+of the respective book section, for example `src/configuration_generated.md`, and are included in the book via mdbook's
+[include](https://rust-lang.github.io/mdBook/format/mdbook.html#including-files) functionality. Generated files can be rebuilt by running the various
+test cases that generate them, or by simply running all of the `rust-analyzer` tests with `cargo test`.
diff --git a/src/tools/rust-analyzer/docs/book/book.toml b/src/tools/rust-analyzer/docs/book/book.toml
new file mode 100644
index 00000000000..ba3c1dede5d
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/book.toml
@@ -0,0 +1,41 @@
+[book]
+authors = ["The rust-analyzer authors"]
+language = "en"
+multilingual = false
+src = "src"
+title = "rust-analyzer"
+
+[rust]
+edition = "2021"
+
+[output.html]
+edit-url-template = "https://github.com/rust-lang/rust-analyzer/edit/master/manual/{path}"
+git-repository-url = "https://github.com/rust-lang/rust-analyzer/tree/master/manual"
+mathjax-support = true
+site-url = "/manual/"
+
+[output.html.playground]
+editable = true
+runnable = false
+line-numbers = true
+
+[output.html.search]
+boost-hierarchy = 2
+boost-paragraph = 1
+boost-title = 2
+expand = true
+heading-split-level = 2
+limit-results = 20
+use-boolean-and = true
+
+[output.html.redirect]
+"/manual.html" = "/index.html"
+
+[output.html.fold]
+enable = true
+level = 3
+
+[preprocessor.toc]
+command = "mdbook-toc"
+renderer = ["html"]
+max-level = 3
diff --git a/src/tools/rust-analyzer/docs/book/src/README.md b/src/tools/rust-analyzer/docs/book/src/README.md
new file mode 100644
index 00000000000..71f34e03466
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/README.md
@@ -0,0 +1,21 @@
+# rust-analyzer
+
+At its core, rust-analyzer is a **library** for semantic analysis of
+Rust code as it changes over time. This manual focuses on a specific
+usage of the library -- running it as part of a server that implements
+the [Language Server
+Protocol](https://microsoft.github.io/language-server-protocol/) (LSP).
+The LSP allows various code editors, like VS Code, Emacs or Vim, to
+implement semantic features like completion or goto definition by
+talking to an external language server process.
+
+To improve this document, send a pull request:
+[https://github.com/rust-lang/rust-analyzer](https://github.com/rust-lang/rust-analyzer/blob/master/docs/book/README.md)
+
+The manual is written in markdown and includes
+some extra files which are generated from the source code. Run
+`cargo test` and `cargo xtask codegen` to create these.
+
+If you have questions about using rust-analyzer, please ask them in the
+["IDEs and Editors"](https://users.rust-lang.org/c/ide/14) topic of Rust
+users forum.
diff --git a/src/tools/rust-analyzer/docs/book/src/SUMMARY.md b/src/tools/rust-analyzer/docs/book/src/SUMMARY.md
new file mode 100644
index 00000000000..b3ed1e6df0a
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/SUMMARY.md
@@ -0,0 +1,13 @@
+# Summary
+
+- [Introduction](README.md)
+- [Installation](installation.md)
+- [Troubleshooting](troubleshooting.md)
+- [Configuration](configuration.md)
+  - [Non-Cargo Based Projects](non_cargo_based_projects.md)
+- [Security](security.md)
+- [Privacy](privacy.md)
+- [Features](features.md)
+  - [Assists (Code Actions)](assists.md)
+  - [Diagnostics](diagnostics.md)
+- [Editor Features](editor_features.md)
diff --git a/src/tools/rust-analyzer/docs/book/src/assists.md b/src/tools/rust-analyzer/docs/book/src/assists.md
new file mode 100644
index 00000000000..9d7c3bc1d5b
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/assists.md
@@ -0,0 +1,8 @@
+# Assists
+
+Assists, or code actions, are small local refactorings, available in a
+particular context. They are usually triggered by a shortcut or by
+clicking a light bulb icon in the editor. Cursor position or selection
+is signified by `┃` character.
+
+{{#include assists_generated.md:2:}}
diff --git a/src/tools/rust-analyzer/docs/book/src/configuration.md b/src/tools/rust-analyzer/docs/book/src/configuration.md
new file mode 100644
index 00000000000..221a571c17c
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/configuration.md
@@ -0,0 +1,51 @@
+# Configuration
+
+**Source:**
+[config.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs)
+
+The [Installation](#_installation) section contains details on
+configuration for some of the editors. In general `rust-analyzer` is
+configured via LSP messages, which means that it’s up to the editor to
+decide on the exact format and location of configuration files.
+
+Some clients, such as [VS Code](#vs-code) or [COC plugin in
+Vim](#coc-rust-analyzer) provide `rust-analyzer` specific configuration
+UIs. Others may require you to know a bit more about the interaction
+with `rust-analyzer`.
+
+For the later category, it might help to know that the initial
+configuration is specified as a value of the `initializationOptions`
+field of the [`InitializeParams` message, in the LSP
+protocol](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#initialize).
+The spec says that the field type is `any?`, but `rust-analyzer` is
+looking for a JSON object that is constructed using settings from the
+list below. Name of the setting, ignoring the `rust-analyzer.` prefix,
+is used as a path, and value of the setting becomes the JSON property
+value.
+
+For example, a very common configuration is to enable proc-macro
+support, can be achieved by sending this JSON:
+
+    {
+      "cargo": {
+        "buildScripts": {
+          "enable": true,
+        },
+      },
+      "procMacro": {
+        "enable": true,
+      }
+    }
+
+Please consult your editor’s documentation to learn more about how to
+configure [LSP
+servers](https://microsoft.github.io/language-server-protocol/).
+
+To verify which configuration is actually used by `rust-analyzer`, set
+`RA_LOG` environment variable to `rust_analyzer=info` and look for
+config-related messages. Logs should show both the JSON that
+`rust-analyzer` sees as well as the updated config.
+
+This is the list of config options `rust-analyzer` supports:
+
+{{#include configuration_generated.md}}
diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
new file mode 100644
index 00000000000..55678926609
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
@@ -0,0 +1,1206 @@
+**rust-analyzer.assist.emitMustUse** (default: false)
+
+ Whether to insert #[must_use] when generating `as_` methods
+for enum variants.
+
+
+**rust-analyzer.assist.expressionFillDefault** (default: "todo")
+
+ Placeholder expression to use for missing expressions in assists.
+
+
+**rust-analyzer.assist.termSearch.borrowcheck** (default: true)
+
+ Enable borrow checking for term search code assists. If set to false, also there will be more suggestions, but some of them may not borrow-check.
+
+
+**rust-analyzer.assist.termSearch.fuel** (default: 1800)
+
+ Term search fuel in "units of work" for assists (Defaults to 1800).
+
+
+**rust-analyzer.cachePriming.enable** (default: true)
+
+ Warm up caches on project load.
+
+
+**rust-analyzer.cachePriming.numThreads** (default: "physical")
+
+ How many worker threads to handle priming caches. The default `0` means to pick automatically.
+
+
+**rust-analyzer.cargo.allTargets** (default: true)
+
+ Pass `--all-targets` to cargo invocation.
+
+
+**rust-analyzer.cargo.autoreload** (default: true)
+
+ Automatically refresh project info via `cargo metadata` on
+`Cargo.toml` or `.cargo/config.toml` changes.
+
+
+**rust-analyzer.cargo.buildScripts.enable** (default: true)
+
+ Run build scripts (`build.rs`) for more precise code analysis.
+
+
+**rust-analyzer.cargo.buildScripts.invocationStrategy** (default: "per_workspace")
+
+ Specifies the invocation strategy to use when running the build scripts command.
+If `per_workspace` is set, the command will be executed for each Rust workspace with the
+workspace as the working directory.
+If `once` is set, the command will be executed once with the opened project as the
+working directory.
+This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+is set.
+
+
+**rust-analyzer.cargo.buildScripts.overrideCommand** (default: null)
+
+ Override the command rust-analyzer uses to run build scripts and
+build procedural macros. The command is required to output json
+and should therefore include `--message-format=json` or a similar
+option.
+
+If there are multiple linked projects/workspaces, this command is invoked for
+each of them, with the working directory being the workspace root
+(i.e., the folder containing the `Cargo.toml`). This can be overwritten
+by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`.
+
+By default, a cargo invocation will be constructed for the configured
+targets and features, with the following base command line:
+
+```bash
+cargo check --quiet --workspace --message-format=json --all-targets --keep-going
+```
+.
+
+
+**rust-analyzer.cargo.buildScripts.rebuildOnSave** (default: true)
+
+ Rerun proc-macros building/build-scripts running when proc-macro
+or build-script sources change and are saved.
+
+
+**rust-analyzer.cargo.buildScripts.useRustcWrapper** (default: true)
+
+ Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
+avoid checking unnecessary things.
+
+
+ **rust-analyzer.cargo.cfgs**
+
+Default:
+
+```[
+  "debug_assertions",
+  "miri"
+]
+
+```
+
+ List of cfg options to enable with the given values.
+
+
+ **rust-analyzer.cargo.extraArgs** (default: [])
+
+ Extra arguments that are passed to every cargo invocation.
+
+
+**rust-analyzer.cargo.extraEnv** (default: {})
+
+ Extra environment variables that will be set when running cargo, rustc
+or other commands within the workspace. Useful for setting RUSTFLAGS.
+
+
+**rust-analyzer.cargo.features** (default: [])
+
+ List of features to activate.
+
+Set this to `"all"` to pass `--all-features` to cargo.
+
+
+**rust-analyzer.cargo.noDefaultFeatures** (default: false)
+
+ Whether to pass `--no-default-features` to cargo.
+
+
+**rust-analyzer.cargo.sysroot** (default: "discover")
+
+ Relative path to the sysroot, or "discover" to try to automatically find it via
+"rustc --print sysroot".
+
+Unsetting this disables sysroot loading.
+
+This option does not take effect until rust-analyzer is restarted.
+
+
+**rust-analyzer.cargo.sysrootSrc** (default: null)
+
+ Relative path to the sysroot library sources. If left unset, this will default to
+`{cargo.sysroot}/lib/rustlib/src/rust/library`.
+
+This option does not take effect until rust-analyzer is restarted.
+
+
+**rust-analyzer.cargo.target** (default: null)
+
+ Compilation target override (target tuple).
+
+
+**rust-analyzer.cargo.targetDir** (default: null)
+
+ Optional path to a rust-analyzer specific target directory.
+This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro
+building from locking the `Cargo.lock` at the expense of duplicating build artifacts.
+
+Set to `true` to use a subdirectory of the existing target directory or
+set to a path relative to the workspace to use that path.
+
+
+**rust-analyzer.cfg.setTest** (default: true)
+
+ Set `cfg(test)` for local crates. Defaults to true.
+
+
+**rust-analyzer.checkOnSave** (default: true)
+
+ Run the check command for diagnostics on save.
+
+
+**rust-analyzer.check.allTargets** (default: null)
+
+ Check all targets and tests (`--all-targets`). Defaults to
+`#rust-analyzer.cargo.allTargets#`.
+
+
+**rust-analyzer.check.command** (default: "check")
+
+ Cargo command to use for `cargo check`.
+
+
+**rust-analyzer.check.extraArgs** (default: [])
+
+ Extra arguments for `cargo check`.
+
+
+**rust-analyzer.check.extraEnv** (default: {})
+
+ Extra environment variables that will be set when running `cargo check`.
+Extends `#rust-analyzer.cargo.extraEnv#`.
+
+
+**rust-analyzer.check.features** (default: null)
+
+ List of features to activate. Defaults to
+`#rust-analyzer.cargo.features#`.
+
+Set to `"all"` to pass `--all-features` to Cargo.
+
+
+**rust-analyzer.check.ignore** (default: [])
+
+ List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.
+
+For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...
+
+
+**rust-analyzer.check.invocationStrategy** (default: "per_workspace")
+
+ Specifies the invocation strategy to use when running the check command.
+If `per_workspace` is set, the command will be executed for each workspace.
+If `once` is set, the command will be executed once.
+This config only has an effect when `#rust-analyzer.check.overrideCommand#`
+is set.
+
+
+**rust-analyzer.check.noDefaultFeatures** (default: null)
+
+ Whether to pass `--no-default-features` to Cargo. Defaults to
+`#rust-analyzer.cargo.noDefaultFeatures#`.
+
+
+**rust-analyzer.check.overrideCommand** (default: null)
+
+ Override the command rust-analyzer uses instead of `cargo check` for
+diagnostics on save. The command is required to output json and
+should therefore include `--message-format=json` or a similar option
+(if your client supports the `colorDiagnosticOutput` experimental
+capability, you can use `--message-format=json-diagnostic-rendered-ansi`).
+
+If you're changing this because you're using some tool wrapping
+Cargo, you might also want to change
+`#rust-analyzer.cargo.buildScripts.overrideCommand#`.
+
+If there are multiple linked projects/workspaces, this command is invoked for
+each of them, with the working directory being the workspace root
+(i.e., the folder containing the `Cargo.toml`). This can be overwritten
+by changing `#rust-analyzer.check.invocationStrategy#`.
+
+If `$saved_file` is part of the command, rust-analyzer will pass
+the absolute path of the saved file to the provided command. This is
+intended to be used with non-Cargo build systems.
+Note that `$saved_file` is experimental and may be removed in the future.
+
+An example command would be:
+
+```bash
+cargo check --workspace --message-format=json --all-targets
+```
+.
+
+
+**rust-analyzer.check.targets** (default: null)
+
+ Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.
+
+Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g.
+`["aarch64-apple-darwin", "x86_64-apple-darwin"]`.
+
+Aliased as `"checkOnSave.targets"`.
+
+
+**rust-analyzer.check.workspace** (default: true)
+
+ Whether `--workspace` should be passed to `cargo check`.
+If false, `-p <package>` will be passed instead if applicable. In case it is not, no
+check will be performed.
+
+
+**rust-analyzer.completion.addSemicolonToUnit** (default: true)
+
+ Whether to automatically add a semicolon when completing unit-returning functions.
+
+In `match` arms it completes a comma instead.
+
+
+**rust-analyzer.completion.autoAwait.enable** (default: true)
+
+ Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.
+
+
+**rust-analyzer.completion.autoIter.enable** (default: true)
+
+ Toggles the additional completions that automatically show method calls with `iter()` or `into_iter()` prefixed to them when completing on a type that has them.
+
+
+**rust-analyzer.completion.autoimport.enable** (default: true)
+
+ Toggles the additional completions that automatically add imports when completed.
+Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
+
+
+ **rust-analyzer.completion.autoimport.exclude**
+
+Default:
+
+```[
+  {
+    "path": "core::borrow::Borrow",
+    "type": "methods"
+  },
+  {
+    "path": "core::borrow::BorrowMut",
+    "type": "methods"
+  }
+]
+
+```
+
+ A list of full paths to items to exclude from auto-importing completions.
+
+Traits in this list won't have their methods suggested in completions unless the trait
+is in scope.
+
+You can either specify a string path which defaults to type "always" or use the more verbose
+form `{ "path": "path::to::item", type: "always" }`.
+
+For traits the type "methods" can be used to only exclude the methods but not the trait itself.
+
+This setting also inherits `#rust-analyzer.completion.excludeTraits#`.
+
+
+ **rust-analyzer.completion.autoself.enable** (default: true)
+
+ Toggles the additional completions that automatically show method calls and field accesses
+with `self` prefixed to them when inside a method.
+
+
+**rust-analyzer.completion.callable.snippets** (default: "fill_arguments")
+
+ Whether to add parenthesis and argument snippets when completing function.
+
+
+**rust-analyzer.completion.excludeTraits** (default: [])
+
+ A list of full paths to traits whose methods to exclude from completion.
+
+Methods from these traits won't be completed, even if the trait is in scope. However, they will still be suggested on expressions whose type is `dyn Trait`, `impl Trait` or `T where T: Trait`.
+
+Note that the trait themselves can still be completed.
+
+
+**rust-analyzer.completion.fullFunctionSignatures.enable** (default: false)
+
+ Whether to show full function/method signatures in completion docs.
+
+
+**rust-analyzer.completion.hideDeprecated** (default: false)
+
+ Whether to omit deprecated items from autocompletion. By default they are marked as deprecated but not hidden.
+
+
+**rust-analyzer.completion.limit** (default: null)
+
+ Maximum number of completions to return. If `None`, the limit is infinite.
+
+
+**rust-analyzer.completion.postfix.enable** (default: true)
+
+ Whether to show postfix snippets like `dbg`, `if`, `not`, etc.
+
+
+**rust-analyzer.completion.privateEditable.enable** (default: false)
+
+ Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position.
+
+
+ **rust-analyzer.completion.snippets.custom**
+
+Default:
+
+```{
+  "Ok": {
+    "postfix": "ok",
+    "body": "Ok(${receiver})",
+    "description": "Wrap the expression in a `Result::Ok`",
+    "scope": "expr"
+  },
+  "Box::pin": {
+    "postfix": "pinbox",
+    "body": "Box::pin(${receiver})",
+    "requires": "std::boxed::Box",
+    "description": "Put the expression into a pinned `Box`",
+    "scope": "expr"
+  },
+  "Arc::new": {
+    "postfix": "arc",
+    "body": "Arc::new(${receiver})",
+    "requires": "std::sync::Arc",
+    "description": "Put the expression into an `Arc`",
+    "scope": "expr"
+  },
+  "Some": {
+    "postfix": "some",
+    "body": "Some(${receiver})",
+    "description": "Wrap the expression in an `Option::Some`",
+    "scope": "expr"
+  },
+  "Err": {
+    "postfix": "err",
+    "body": "Err(${receiver})",
+    "description": "Wrap the expression in a `Result::Err`",
+    "scope": "expr"
+  },
+  "Rc::new": {
+    "postfix": "rc",
+    "body": "Rc::new(${receiver})",
+    "requires": "std::rc::Rc",
+    "description": "Put the expression into an `Rc`",
+    "scope": "expr"
+  }
+}
+
+```
+
+ Custom completion snippets.
+
+
+ **rust-analyzer.completion.termSearch.enable** (default: false)
+
+ Whether to enable term search based snippets like `Some(foo.bar().baz())`.
+
+
+**rust-analyzer.completion.termSearch.fuel** (default: 1000)
+
+ Term search fuel in "units of work" for autocompletion (Defaults to 1000).
+
+
+**rust-analyzer.diagnostics.disabled** (default: [])
+
+ List of rust-analyzer diagnostics to disable.
+
+
+**rust-analyzer.diagnostics.enable** (default: true)
+
+ Whether to show native rust-analyzer diagnostics.
+
+
+**rust-analyzer.diagnostics.experimental.enable** (default: false)
+
+ Whether to show experimental rust-analyzer diagnostics that might
+have more false positives than usual.
+
+
+**rust-analyzer.diagnostics.remapPrefix** (default: {})
+
+ Map of prefixes to be substituted when parsing diagnostic file paths.
+This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`.
+
+
+**rust-analyzer.diagnostics.styleLints.enable** (default: false)
+
+ Whether to run additional style lints.
+
+
+**rust-analyzer.diagnostics.warningsAsHint** (default: [])
+
+ List of warnings that should be displayed with hint severity.
+
+The warnings will be indicated by faded text or three dots in code
+and will not show up in the `Problems Panel`.
+
+
+**rust-analyzer.diagnostics.warningsAsInfo** (default: [])
+
+ List of warnings that should be displayed with info severity.
+
+The warnings will be indicated by a blue squiggly underline in code
+and a blue icon in the `Problems Panel`.
+
+
+**rust-analyzer.files.excludeDirs** (default: [])
+
+ These directories will be ignored by rust-analyzer. They are
+relative to the workspace root, and globs are not supported. You may
+also need to add the folders to Code's `files.watcherExclude`.
+
+
+**rust-analyzer.files.watcher** (default: "client")
+
+ Controls file watching implementation.
+
+
+**rust-analyzer.highlightRelated.breakPoints.enable** (default: true)
+
+ Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords.
+
+
+**rust-analyzer.highlightRelated.closureCaptures.enable** (default: true)
+
+ Enables highlighting of all captures of a closure while the cursor is on the `|` or move keyword of a closure.
+
+
+**rust-analyzer.highlightRelated.exitPoints.enable** (default: true)
+
+ Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`).
+
+
+**rust-analyzer.highlightRelated.references.enable** (default: true)
+
+ Enables highlighting of related references while the cursor is on any identifier.
+
+
+**rust-analyzer.highlightRelated.yieldPoints.enable** (default: true)
+
+ Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords.
+
+
+**rust-analyzer.hover.actions.debug.enable** (default: true)
+
+ Whether to show `Debug` action. Only applies when
+`#rust-analyzer.hover.actions.enable#` is set.
+
+
+**rust-analyzer.hover.actions.enable** (default: true)
+
+ Whether to show HoverActions in Rust files.
+
+
+**rust-analyzer.hover.actions.gotoTypeDef.enable** (default: true)
+
+ Whether to show `Go to Type Definition` action. Only applies when
+`#rust-analyzer.hover.actions.enable#` is set.
+
+
+**rust-analyzer.hover.actions.implementations.enable** (default: true)
+
+ Whether to show `Implementations` action. Only applies when
+`#rust-analyzer.hover.actions.enable#` is set.
+
+
+**rust-analyzer.hover.actions.references.enable** (default: false)
+
+ Whether to show `References` action. Only applies when
+`#rust-analyzer.hover.actions.enable#` is set.
+
+
+**rust-analyzer.hover.actions.run.enable** (default: true)
+
+ Whether to show `Run` action. Only applies when
+`#rust-analyzer.hover.actions.enable#` is set.
+
+
+**rust-analyzer.hover.actions.updateTest.enable** (default: true)
+
+ Whether to show `Update Test` action. Only applies when
+`#rust-analyzer.hover.actions.enable#` and `#rust-analyzer.hover.actions.run.enable#` are set.
+
+
+**rust-analyzer.hover.documentation.enable** (default: true)
+
+ Whether to show documentation on hover.
+
+
+**rust-analyzer.hover.documentation.keywords.enable** (default: true)
+
+ Whether to show keyword hover popups. Only applies when
+`#rust-analyzer.hover.documentation.enable#` is set.
+
+
+**rust-analyzer.hover.links.enable** (default: true)
+
+ Use markdown syntax for links on hover.
+
+
+**rust-analyzer.hover.maxSubstitutionLength** (default: 20)
+
+ Whether to show what types are used as generic arguments in calls etc. on hover, and what is their max length to show such types, beyond it they will be shown with ellipsis.
+
+This can take three values: `null` means "unlimited", the string `"hide"` means to not show generic substitutions at all, and a number means to limit them to X characters.
+
+The default is 20 characters.
+
+
+**rust-analyzer.hover.memoryLayout.alignment** (default: "hexadecimal")
+
+ How to render the align information in a memory layout hover.
+
+
+**rust-analyzer.hover.memoryLayout.enable** (default: true)
+
+ Whether to show memory layout data on hover.
+
+
+**rust-analyzer.hover.memoryLayout.niches** (default: false)
+
+ How to render the niche information in a memory layout hover.
+
+
+**rust-analyzer.hover.memoryLayout.offset** (default: "hexadecimal")
+
+ How to render the offset information in a memory layout hover.
+
+
+**rust-analyzer.hover.memoryLayout.size** (default: "both")
+
+ How to render the size information in a memory layout hover.
+
+
+**rust-analyzer.hover.show.enumVariants** (default: 5)
+
+ How many variants of an enum to display when hovering on. Show none if empty.
+
+
+**rust-analyzer.hover.show.fields** (default: 5)
+
+ How many fields of a struct, variant or union to display when hovering on. Show none if empty.
+
+
+**rust-analyzer.hover.show.traitAssocItems** (default: null)
+
+ How many associated items of a trait to display when hovering a trait.
+
+
+**rust-analyzer.imports.granularity.enforce** (default: false)
+
+ Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file.
+
+
+**rust-analyzer.imports.granularity.group** (default: "crate")
+
+ How imports should be grouped into use statements.
+
+
+**rust-analyzer.imports.group.enable** (default: true)
+
+ Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
+
+
+**rust-analyzer.imports.merge.glob** (default: true)
+
+ Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
+
+
+**rust-analyzer.imports.preferNoStd** (default: false)
+
+ Prefer to unconditionally use imports of the core and alloc crate, over the std crate.
+
+
+**rust-analyzer.imports.preferPrelude** (default: false)
+
+ Whether to prefer import paths containing a `prelude` module.
+
+
+**rust-analyzer.imports.prefix** (default: "plain")
+
+ The path structure for newly inserted paths to use.
+
+
+**rust-analyzer.imports.prefixExternPrelude** (default: false)
+
+ Whether to prefix external (including std, core) crate imports with `::`. e.g. "use ::std::io::Read;".
+
+
+**rust-analyzer.inlayHints.bindingModeHints.enable** (default: false)
+
+ Whether to show inlay type hints for binding modes.
+
+
+**rust-analyzer.inlayHints.chainingHints.enable** (default: true)
+
+ Whether to show inlay type hints for method chains.
+
+
+**rust-analyzer.inlayHints.closingBraceHints.enable** (default: true)
+
+ Whether to show inlay hints after a closing `}` to indicate what item it belongs to.
+
+
+**rust-analyzer.inlayHints.closingBraceHints.minLines** (default: 25)
+
+ Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1
+to always show them).
+
+
+**rust-analyzer.inlayHints.closureCaptureHints.enable** (default: false)
+
+ Whether to show inlay hints for closure captures.
+
+
+**rust-analyzer.inlayHints.closureReturnTypeHints.enable** (default: "never")
+
+ Whether to show inlay type hints for return types of closures.
+
+
+**rust-analyzer.inlayHints.closureStyle** (default: "impl_fn")
+
+ Closure notation in type and chaining inlay hints.
+
+
+**rust-analyzer.inlayHints.discriminantHints.enable** (default: "never")
+
+ Whether to show enum variant discriminant hints.
+
+
+**rust-analyzer.inlayHints.expressionAdjustmentHints.enable** (default: "never")
+
+ Whether to show inlay hints for type adjustments.
+
+
+**rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe** (default: false)
+
+ Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
+
+
+**rust-analyzer.inlayHints.expressionAdjustmentHints.mode** (default: "prefix")
+
+ Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).
+
+
+**rust-analyzer.inlayHints.genericParameterHints.const.enable** (default: true)
+
+ Whether to show const generic parameter name inlay hints.
+
+
+**rust-analyzer.inlayHints.genericParameterHints.lifetime.enable** (default: false)
+
+ Whether to show generic lifetime parameter name inlay hints.
+
+
+**rust-analyzer.inlayHints.genericParameterHints.type.enable** (default: false)
+
+ Whether to show generic type parameter name inlay hints.
+
+
+**rust-analyzer.inlayHints.implicitDrops.enable** (default: false)
+
+ Whether to show implicit drop hints.
+
+
+**rust-analyzer.inlayHints.implicitSizedBoundHints.enable** (default: false)
+
+ Whether to show inlay hints for the implied type parameter `Sized` bound.
+
+
+**rust-analyzer.inlayHints.lifetimeElisionHints.enable** (default: "never")
+
+ Whether to show inlay type hints for elided lifetimes in function signatures.
+
+
+**rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames** (default: false)
+
+ Whether to prefer using parameter names as the name for elided lifetime hints if possible.
+
+
+**rust-analyzer.inlayHints.maxLength** (default: 25)
+
+ Maximum length for inlay hints. Set to null to have an unlimited length.
+
+
+**rust-analyzer.inlayHints.parameterHints.enable** (default: true)
+
+ Whether to show function parameter name inlay hints at the call
+site.
+
+
+**rust-analyzer.inlayHints.rangeExclusiveHints.enable** (default: false)
+
+ Whether to show exclusive range inlay hints.
+
+
+**rust-analyzer.inlayHints.reborrowHints.enable** (default: "never")
+
+ Whether to show inlay hints for compiler inserted reborrows.
+This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.
+
+
+**rust-analyzer.inlayHints.renderColons** (default: true)
+
+ Whether to render leading colons for type hints, and trailing colons for parameter hints.
+
+
+**rust-analyzer.inlayHints.typeHints.enable** (default: true)
+
+ Whether to show inlay type hints for variables.
+
+
+**rust-analyzer.inlayHints.typeHints.hideClosureInitialization** (default: false)
+
+ Whether to hide inlay type hints for `let` statements that initialize to a closure.
+Only applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`.
+
+
+**rust-analyzer.inlayHints.typeHints.hideClosureParameter** (default: false)
+
+ Whether to hide inlay parameter type hints for closures.
+
+
+**rust-analyzer.inlayHints.typeHints.hideNamedConstructor** (default: false)
+
+ Whether to hide inlay type hints for constructors.
+
+
+**rust-analyzer.interpret.tests** (default: false)
+
+ Enables the experimental support for interpreting tests.
+
+
+**rust-analyzer.joinLines.joinAssignments** (default: true)
+
+ Join lines merges consecutive declaration and initialization of an assignment.
+
+
+**rust-analyzer.joinLines.joinElseIf** (default: true)
+
+ Join lines inserts else between consecutive ifs.
+
+
+**rust-analyzer.joinLines.removeTrailingComma** (default: true)
+
+ Join lines removes trailing commas.
+
+
+**rust-analyzer.joinLines.unwrapTrivialBlock** (default: true)
+
+ Join lines unwraps trivial blocks.
+
+
+**rust-analyzer.lens.debug.enable** (default: true)
+
+ Whether to show `Debug` lens. Only applies when
+`#rust-analyzer.lens.enable#` is set.
+
+
+**rust-analyzer.lens.enable** (default: true)
+
+ Whether to show CodeLens in Rust files.
+
+
+**rust-analyzer.lens.implementations.enable** (default: true)
+
+ Whether to show `Implementations` lens. Only applies when
+`#rust-analyzer.lens.enable#` is set.
+
+
+**rust-analyzer.lens.location** (default: "above_name")
+
+ Where to render annotations.
+
+
+**rust-analyzer.lens.references.adt.enable** (default: false)
+
+ Whether to show `References` lens for Struct, Enum, and Union.
+Only applies when `#rust-analyzer.lens.enable#` is set.
+
+
+**rust-analyzer.lens.references.enumVariant.enable** (default: false)
+
+ Whether to show `References` lens for Enum Variants.
+Only applies when `#rust-analyzer.lens.enable#` is set.
+
+
+**rust-analyzer.lens.references.method.enable** (default: false)
+
+ Whether to show `Method References` lens. Only applies when
+`#rust-analyzer.lens.enable#` is set.
+
+
+**rust-analyzer.lens.references.trait.enable** (default: false)
+
+ Whether to show `References` lens for Trait.
+Only applies when `#rust-analyzer.lens.enable#` is set.
+
+
+**rust-analyzer.lens.run.enable** (default: true)
+
+ Whether to show `Run` lens. Only applies when
+`#rust-analyzer.lens.enable#` is set.
+
+
+**rust-analyzer.lens.updateTest.enable** (default: true)
+
+ Whether to show `Update Test` lens. Only applies when
+`#rust-analyzer.lens.enable#` and `#rust-analyzer.lens.run.enable#` are set.
+
+
+**rust-analyzer.linkedProjects** (default: [])
+
+ Disable project auto-discovery in favor of explicitly specified set
+of projects.
+
+Elements must be paths pointing to `Cargo.toml`,
+`rust-project.json`, `.rs` files (which will be treated as standalone files) or JSON
+objects in `rust-project.json` format.
+
+
+**rust-analyzer.lru.capacity** (default: null)
+
+ Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
+
+
+**rust-analyzer.lru.query.capacities** (default: {})
+
+ Sets the LRU capacity of the specified queries.
+
+
+**rust-analyzer.notifications.cargoTomlNotFound** (default: true)
+
+ Whether to show `can't find Cargo.toml` error message.
+
+
+**rust-analyzer.numThreads** (default: null)
+
+ How many worker threads in the main loop. The default `null` means to pick automatically.
+
+
+**rust-analyzer.procMacro.attributes.enable** (default: true)
+
+ Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.
+
+
+**rust-analyzer.procMacro.enable** (default: true)
+
+ Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`.
+
+
+**rust-analyzer.procMacro.ignored** (default: {})
+
+ These proc-macros will be ignored when trying to expand them.
+
+This config takes a map of crate names with the exported proc-macro names to ignore as values.
+
+
+**rust-analyzer.procMacro.server** (default: null)
+
+ Internal config, path to proc-macro server executable.
+
+
+**rust-analyzer.references.excludeImports** (default: false)
+
+ Exclude imports from find-all-references.
+
+
+**rust-analyzer.references.excludeTests** (default: false)
+
+ Exclude tests from find-all-references and call-hierarchy.
+
+
+**rust-analyzer.runnables.command** (default: null)
+
+ Command to be executed instead of 'cargo' for runnables.
+
+
+**rust-analyzer.runnables.extraArgs** (default: [])
+
+ Additional arguments to be passed to cargo for runnables such as
+tests or binaries. For example, it may be `--release`.
+
+
+ **rust-analyzer.runnables.extraTestBinaryArgs**
+
+Default:
+
+```[
+  "--show-output"
+]
+
+```
+
+ Additional arguments to be passed through Cargo to launched tests, benchmarks, or
+doc-tests.
+
+Unless the launched target uses a
+[custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field),
+they will end up being interpreted as options to
+[`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
+
+
+ **rust-analyzer.rustc.source** (default: null)
+
+ Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
+projects, or "discover" to try to automatically find it if the `rustc-dev` component
+is installed.
+
+Any project which uses rust-analyzer with the rustcPrivate
+crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it.
+
+This option does not take effect until rust-analyzer is restarted.
+
+
+**rust-analyzer.rustfmt.extraArgs** (default: [])
+
+ Additional arguments to `rustfmt`.
+
+
+**rust-analyzer.rustfmt.overrideCommand** (default: null)
+
+ Advanced option, fully override the command rust-analyzer uses for
+formatting. This should be the equivalent of `rustfmt` here, and
+not that of `cargo fmt`. The file contents will be passed on the
+standard input and the formatted result will be read from the
+standard output.
+
+
+**rust-analyzer.rustfmt.rangeFormatting.enable** (default: false)
+
+ Enables the use of rustfmt's unstable range formatting command for the
+`textDocument/rangeFormatting` request. The rustfmt option is unstable and only
+available on a nightly build.
+
+
+**rust-analyzer.semanticHighlighting.doc.comment.inject.enable** (default: true)
+
+ Inject additional highlighting into doc comments.
+
+When enabled, rust-analyzer will highlight rust source in doc comments as well as intra
+doc links.
+
+
+**rust-analyzer.semanticHighlighting.nonStandardTokens** (default: true)
+
+ Whether the server is allowed to emit non-standard tokens and modifiers.
+
+
+**rust-analyzer.semanticHighlighting.operator.enable** (default: true)
+
+ Use semantic tokens for operators.
+
+When disabled, rust-analyzer will emit semantic tokens only for operator tokens when
+they are tagged with modifiers.
+
+
+**rust-analyzer.semanticHighlighting.operator.specialization.enable** (default: false)
+
+ Use specialized semantic tokens for operators.
+
+When enabled, rust-analyzer will emit special token types for operator tokens instead
+of the generic `operator` token type.
+
+
+**rust-analyzer.semanticHighlighting.punctuation.enable** (default: false)
+
+ Use semantic tokens for punctuation.
+
+When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when
+they are tagged with modifiers or have a special role.
+
+
+**rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang** (default: false)
+
+ When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro
+calls.
+
+
+**rust-analyzer.semanticHighlighting.punctuation.specialization.enable** (default: false)
+
+ Use specialized semantic tokens for punctuation.
+
+When enabled, rust-analyzer will emit special token types for punctuation tokens instead
+of the generic `punctuation` token type.
+
+
+**rust-analyzer.semanticHighlighting.strings.enable** (default: true)
+
+ Use semantic tokens for strings.
+
+In some editors (e.g. vscode) semantic tokens override other highlighting grammars.
+By disabling semantic tokens for strings, other grammars can be used to highlight
+their contents.
+
+
+**rust-analyzer.signatureInfo.detail** (default: "full")
+
+ Show full signature of the callable. Only shows parameters if disabled.
+
+
+**rust-analyzer.signatureInfo.documentation.enable** (default: true)
+
+ Show documentation.
+
+
+**rust-analyzer.typing.triggerChars** (default: "=.")
+
+ Specify the characters allowed to invoke special on typing triggers.
+- typing `=` after `let` tries to smartly add `;` if `=` is followed by an existing expression
+- typing `=` between two expressions adds `;` when in statement position
+- typing `=` to turn an assignment into an equality comparison removes `;` when in expression position
+- typing `.` in a chain method call auto-indents
+- typing `{` or `(` in front of an expression inserts a closing `}` or `)` after the expression
+- typing `{` in a use item adds a closing `}` in the right place
+- typing `>` to complete a return type `->` will insert a whitespace after it
+- typing `<` in a path or type position inserts a closing `>` after the path or type.
+
+
+**rust-analyzer.vfs.extraIncludes** (default: [])
+
+ Additional paths to include in the VFS. Generally for code that is
+generated or otherwise managed by a build system outside of Cargo,
+though Cargo might be the eventual consumer.
+
+
+**rust-analyzer.workspace.discoverConfig** (default: null)
+
+ Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].
+
+[`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`.
+`progress_label` is used for the title in progress indicators, whereas `files_to_watch`
+is used to determine which build system-specific files should be watched in order to
+reload rust-analyzer.
+
+Below is an example of a valid configuration:
+```json
+"rust-analyzer.workspace.discoverConfig": {
+    "command": [
+        "rust-project",
+        "develop-json"
+    ],
+    "progressLabel": "rust-analyzer",
+    "filesToWatch": [
+        "BUCK"
+    ]
+}
+```
+
+## On `DiscoverWorkspaceConfig::command`
+
+**Warning**: This format is provisional and subject to change.
+
+[`DiscoverWorkspaceConfig::command`] *must* return a JSON object
+corresponding to `DiscoverProjectData::Finished`:
+
+```norun
+#[derive(Debug, Clone, Deserialize, Serialize)]
+#[serde(tag = "kind")]
+#[serde(rename_all = "snake_case")]
+enum DiscoverProjectData {
+    Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },
+    Error { error: String, source: Option<String> },
+    Progress { message: String },
+}
+```
+
+As JSON, `DiscoverProjectData::Finished` is:
+
+```json
+{
+    // the internally-tagged representation of the enum.
+    "kind": "finished",
+    // the file used by a non-Cargo build system to define
+    // a package or target.
+    "buildfile": "rust-analyzer/BUILD",
+    // the contents of a rust-project.json, elided for brevity
+    "project": {
+        "sysroot": "foo",
+        "crates": []
+    }
+}
+```
+
+It is encouraged, but not required, to use the other variants on
+`DiscoverProjectData` to provide a more polished end-user experience.
+
+`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`,
+which will be substituted with the JSON-serialized form of the following
+enum:
+
+```norun
+#[derive(PartialEq, Clone, Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub enum DiscoverArgument {
+   Path(AbsPathBuf),
+   Buildfile(AbsPathBuf),
+}
+```
+
+The JSON representation of `DiscoverArgument::Path` is:
+
+```json
+{
+    "path": "src/main.rs"
+}
+```
+
+Similarly, the JSON representation of `DiscoverArgument::Buildfile` is:
+
+```
+{
+    "buildfile": "BUILD"
+}
+```
+
+`DiscoverArgument::Path` is used to find and generate a `rust-project.json`,
+and therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to
+to update an existing workspace. As a reference for implementors,
+buck2's `rust-project` will likely be useful:
+https://github.com/facebook/buck2/tree/main/integrations/rust-project.
+
+
+**rust-analyzer.workspace.symbol.search.kind** (default: "only_types")
+
+ Workspace symbol search kind.
+
+
+**rust-analyzer.workspace.symbol.search.limit** (default: 128)
+
+ Limits the number of items returned from a workspace symbol search (Defaults to 128).
+Some clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search.
+Other clients requires all results upfront and might require a higher limit.
+
+
+**rust-analyzer.workspace.symbol.search.scope** (default: "workspace")
+
+ Workspace symbol search scope.
+
+
diff --git a/src/tools/rust-analyzer/docs/book/src/diagnostics.md b/src/tools/rust-analyzer/docs/book/src/diagnostics.md
new file mode 100644
index 00000000000..60685c98da7
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/diagnostics.md
@@ -0,0 +1,16 @@
+# Diagnostics
+
+While most errors and warnings provided by rust-analyzer come from the
+`cargo check` integration, there’s a growing number of diagnostics
+implemented using rust-analyzer’s own analysis. Some of these
+diagnostics don’t respect `#[allow]` or `#[deny]` attributes yet, but
+can be turned off using the `rust-analyzer.diagnostics.enable`,
+`rust-analyzer.diagnostics.experimental.enable` or
+`rust-analyzer.diagnostics.disabled` settings.
+
+## Clippy
+
+To run `cargo clippy` instead of `cargo check`, you can set
+`"rust-analyzer.check.command": "clippy"`.
+
+{{#include diagnostics_generated.md:2:}}
diff --git a/src/tools/rust-analyzer/docs/book/src/editor_features.md b/src/tools/rust-analyzer/docs/book/src/editor_features.md
new file mode 100644
index 00000000000..73fe9f49a96
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/editor_features.md
@@ -0,0 +1,204 @@
+# Editor Features
+
+
+## VS Code
+
+### Color configurations
+
+It is possible to change the foreground/background color and font
+family/size of inlay hints. Just add this to your `settings.json`:
+
+```json
+{
+  "editor.inlayHints.fontFamily": "Courier New",
+  "editor.inlayHints.fontSize": 11,
+
+  "workbench.colorCustomizations": {
+    // Name of the theme you are currently using
+    "[Default Dark+]": {
+      "editorInlayHint.foreground": "#868686f0",
+      "editorInlayHint.background": "#3d3d3d48",
+
+      // Overrides for specific kinds of inlay hints
+      "editorInlayHint.typeForeground": "#fdb6fdf0",
+      "editorInlayHint.parameterForeground": "#fdb6fdf0",
+    }
+  }
+}
+```
+
+### Semantic style customizations
+
+You can customize the look of different semantic elements in the source
+code. For example, mutable bindings are underlined by default and you
+can override this behavior by adding the following section to your
+`settings.json`:
+
+```json
+{
+  "editor.semanticTokenColorCustomizations": {
+    "rules": {
+      "*.mutable": {
+        "fontStyle": "", // underline is the default
+      },
+    }
+  },
+}
+```
+
+Most themes doesn’t support styling unsafe operations differently yet.
+You can fix this by adding overrides for the rules `operator.unsafe`,
+`function.unsafe`, and `method.unsafe`:
+
+```json
+{
+   "editor.semanticTokenColorCustomizations": {
+         "rules": {
+             "operator.unsafe": "#ff6600",
+             "function.unsafe": "#ff6600",
+             "method.unsafe": "#ff6600"
+         }
+    },
+}
+```
+
+In addition to the top-level rules you can specify overrides for
+specific themes. For example, if you wanted to use a darker text color
+on a specific light theme, you might write:
+
+```json
+{
+   "editor.semanticTokenColorCustomizations": {
+         "rules": {
+             "operator.unsafe": "#ff6600"
+         },
+         "[Ayu Light]": {
+            "rules": {
+               "operator.unsafe": "#572300"
+            }
+         }
+    },
+}
+```
+
+Make sure you include the brackets around the theme name. For example,
+use `"[Ayu Light]"` to customize the theme Ayu Light.
+
+### Special `when` clause context for keybindings.
+
+You may use `inRustProject` context to configure keybindings for rust
+projects only. For example:
+
+```json
+{
+    "key": "ctrl+alt+d",
+    "command": "rust-analyzer.openDocs",
+    "when": "inRustProject"
+}
+```
+
+More about `when` clause contexts
+[here](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts).
+
+### Setting runnable environment variables
+
+You can use "rust-analyzer.runnables.extraEnv" setting to define
+runnable environment-specific substitution variables. The simplest way
+for all runnables in a bunch:
+
+```json
+"rust-analyzer.runnables.extraEnv": {
+    "RUN_SLOW_TESTS": "1"
+}
+```
+
+Or it is possible to specify vars more granularly:
+
+```json
+"rust-analyzer.runnables.extraEnv": [
+    {
+        // "mask": null, // null mask means that this rule will be applied for all runnables
+        env: {
+                "APP_ID": "1",
+                "APP_DATA": "asdf"
+        }
+    },
+    {
+        "mask": "test_name",
+        "env": {
+                "APP_ID": "2", // overwrites only APP_ID
+        }
+    }
+]
+```
+
+You can use any valid regular expression as a mask. Also note that a
+full runnable name is something like **run bin\_or\_example\_name**,
+**test some::mod::test\_name** or **test-mod some::mod**, so it is
+possible to distinguish binaries, single tests, and test modules with
+this masks: `"^run"`, `"^test "` (the trailing space matters!), and
+`"^test-mod"` respectively.
+
+If needed, you can set different values for different platforms:
+
+```json
+"rust-analyzer.runnables.extraEnv": [
+    {
+        "platform": "win32", // windows only
+        env: {
+                "APP_DATA": "windows specific data"
+        }
+    },
+    {
+        "platform": ["linux"],
+        "env": {
+                "APP_DATA": "linux data",
+        }
+    },
+    { // for all platforms
+        "env": {
+                "APP_COMMON_DATA": "xxx",
+        }
+    }
+]
+```
+
+### Compiler feedback from external commands
+
+Instead of relying on the built-in `cargo check`, you can configure Code
+to run a command in the background and use the `$rustc-watch` problem
+matcher to generate inline error markers from its output.
+
+To do this you need to create a new [VS Code
+Task](https://code.visualstudio.com/docs/editor/tasks) and set
+`"rust-analyzer.checkOnSave": false` in preferences.
+
+For example, if you want to run
+[`cargo watch`](https://crates.io/crates/cargo-watch) instead, you might
+add the following to `.vscode/tasks.json`:
+
+```json
+{
+    "label": "Watch",
+    "group": "build",
+    "type": "shell",
+    "command": "cargo watch",
+    "problemMatcher": "$rustc-watch",
+    "isBackground": true
+}
+```
+
+### Live Share
+
+VS Code Live Share has partial support for rust-analyzer.
+
+Live Share *requires* the official Microsoft build of VS Code, OSS
+builds will not work correctly.
+
+The host’s rust-analyzer instance will be shared with all guests joining
+the session. The guests do not have to have the rust-analyzer extension
+installed for this to work.
+
+If you are joining a Live Share session and *do* have rust-analyzer
+installed locally, commands from the command palette will not work
+correctly since they will attempt to communicate with the local server.
diff --git a/src/tools/rust-analyzer/docs/book/src/features.md b/src/tools/rust-analyzer/docs/book/src/features.md
new file mode 100644
index 00000000000..0829a0213b7
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/features.md
@@ -0,0 +1,3 @@
+# Features
+
+{{#include features_generated.md:2:}}
diff --git a/src/tools/rust-analyzer/docs/book/src/installation.md b/src/tools/rust-analyzer/docs/book/src/installation.md
new file mode 100644
index 00000000000..5b697e9bc33
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/installation.md
@@ -0,0 +1,644 @@
+# Installation
+
+In theory, one should be able to just install the [`rust-analyzer`
+binary](#rust-analyzer-language-server-binary) and have it automatically
+work with any editor. We are not there yet, so some editor specific
+setup is required.
+
+Additionally, rust-analyzer needs the sources of the standard library.
+If the source code is not present, rust-analyzer will attempt to install
+it automatically.
+
+To add the sources manually, run the following command:
+
+    $ rustup component add rust-src
+
+## Toolchain
+
+Only the latest stable standard library source is officially supported
+for use with rust-analyzer. If you are using an older toolchain or have
+an override set, rust-analyzer may fail to understand the Rust source.
+You will either need to update your toolchain or use an older version of
+rust-analyzer that is compatible with your toolchain.
+
+If you are using an override in your project, you can still force
+rust-analyzer to use the stable toolchain via the environment variable
+`RUSTUP_TOOLCHAIN`. For example, with VS Code or coc-rust-analyzer:
+
+    { "rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "stable" } }
+
+## VS Code
+
+This is the best supported editor at the moment. The rust-analyzer
+plugin for VS Code is maintained [in
+tree](https://github.com/rust-lang/rust-analyzer/tree/master/editors/code).
+
+You can install the latest release of the plugin from [the
+marketplace](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer).
+
+Note that the plugin may cause conflicts with the [previous official
+Rust
+plugin](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust).
+The latter is no longer maintained and should be uninstalled.
+
+The server binary is stored in the extension install directory, which
+starts with `rust-lang.rust-analyzer-` and is located under:
+
+-   Linux: `~/.vscode/extensions`
+
+-   Linux (Remote, such as WSL): `~/.vscode-server/extensions`
+
+-   macOS: `~/.vscode/extensions`
+
+-   Windows: `%USERPROFILE%\.vscode\extensions`
+
+As an exception, on NixOS, the extension makes a copy of the server and
+stores it under
+`~/.config/Code/User/globalStorage/rust-lang.rust-analyzer`.
+
+Note that we only support the two most recent versions of VS Code.
+
+### Updates
+
+The extension will be updated automatically as new versions become
+available. It will ask your permission to download the matching language
+server version binary if needed.
+
+#### Nightly
+
+We ship nightly releases for VS Code. To help us out by testing the
+newest code, you can enable pre-release versions in the Code extension
+page.
+
+### Manual installation
+
+Alternatively, download a VSIX corresponding to your platform from the
+[releases](https://github.com/rust-lang/rust-analyzer/releases) page.
+
+Install the extension with the `Extensions: Install from VSIX` command
+within VS Code, or from the command line via:
+
+    $ code --install-extension /path/to/rust-analyzer.vsix
+
+If you are running an unsupported platform, you can install
+`rust-analyzer-no-server.vsix` and compile or obtain a server binary.
+Copy the server anywhere, then add the path to your settings.json, for
+example:
+
+    { "rust-analyzer.server.path": "~/.local/bin/rust-analyzer-linux" }
+
+### Building From Source
+
+Both the server and the Code plugin can be installed from source:
+
+    $ git clone https://github.com/rust-lang/rust-analyzer.git && cd rust-analyzer
+    $ cargo xtask install
+
+You’ll need Cargo, nodejs (matching a supported version of VS Code) and
+npm for this.
+
+Note that installing via `xtask install` does not work for VS Code
+Remote, instead you’ll need to install the `.vsix` manually.
+
+If you’re not using Code, you can compile and install only the LSP
+server:
+
+    $ cargo xtask install --server
+
+Make sure that `.cargo/bin` is in `$PATH` and precedes paths where
+`rust-analyzer` may also be installed. Specifically, `rustup` includes a
+proxy called `rust-analyzer`, which can cause problems if you’re
+planning to use a source build or even a downloaded binary.
+
+## rust-analyzer Language Server Binary
+
+Other editors generally require the `rust-analyzer` binary to be in
+`$PATH`. You can download pre-built binaries from the
+[releases](https://github.com/rust-lang/rust-analyzer/releases) page.
+You will need to uncompress and rename the binary for your platform,
+e.g. from `rust-analyzer-aarch64-apple-darwin.gz` on Mac OS to
+`rust-analyzer`, make it executable, then move it into a directory in
+your `$PATH`.
+
+On Linux to install the `rust-analyzer` binary into `~/.local/bin`,
+these commands should work:
+
+    $ mkdir -p ~/.local/bin
+    $ curl -L https://github.com/rust-lang/rust-analyzer/releases/latest/download/rust-analyzer-x86_64-unknown-linux-gnu.gz | gunzip -c - > ~/.local/bin/rust-analyzer
+    $ chmod +x ~/.local/bin/rust-analyzer
+
+Make sure that `~/.local/bin` is listed in the `$PATH` variable and use
+the appropriate URL if you’re not on a `x86-64` system.
+
+You don’t have to use `~/.local/bin`, any other path like `~/.cargo/bin`
+or `/usr/local/bin` will work just as well.
+
+Alternatively, you can install it from source using the command below.
+You’ll need the latest stable version of the Rust toolchain.
+
+    $ git clone https://github.com/rust-lang/rust-analyzer.git && cd rust-analyzer
+    $ cargo xtask install --server
+
+If your editor can’t find the binary even though the binary is on your
+`$PATH`, the likely explanation is that it doesn’t see the same `$PATH`
+as the shell, see [this
+issue](https://github.com/rust-lang/rust-analyzer/issues/1811). On Unix,
+running the editor from a shell or changing the `.desktop` file to set
+the environment should help.
+
+### rustup
+
+`rust-analyzer` is available in `rustup`:
+
+    $ rustup component add rust-analyzer
+
+### Arch Linux
+
+The `rust-analyzer` binary can be installed from the repos or AUR (Arch
+User Repository):
+
+-   [`rust-analyzer`](https://www.archlinux.org/packages/extra/x86_64/rust-analyzer/)
+    (built from latest tagged source)
+
+-   [`rust-analyzer-git`](https://aur.archlinux.org/packages/rust-analyzer-git)
+    (latest Git version)
+
+Install it with pacman, for example:
+
+    $ pacman -S rust-analyzer
+
+### Gentoo Linux
+
+`rust-analyzer` is installed when the `rust-analyzer` use flag is set for dev-lang/rust or dev-lang/rust-bin. You also need to set the `rust-src` use flag.
+
+### macOS
+
+The `rust-analyzer` binary can be installed via
+[Homebrew](https://brew.sh/).
+
+    $ brew install rust-analyzer
+
+### Windows
+
+It is recommended to install the latest Microsoft Visual C++ Redistributable prior to installation.
+Download links can be found
+[here](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist).
+
+## VS Code or VSCodium in Flatpak
+
+Setting up `rust-analyzer` with a Flatpak version of Code is not trivial
+because of the Flatpak sandbox. While the sandbox can be disabled for
+some directories, `/usr/bin` will always be mounted under
+`/run/host/usr/bin`. This prevents access to the system’s C compiler, a
+system-wide installation of Rust, or any other libraries you might want
+to link to. Some compilers and libraries can be acquired as Flatpak
+SDKs, such as `org.freedesktop.Sdk.Extension.rust-stable` or
+`org.freedesktop.Sdk.Extension.llvm15`.
+
+If you use a Flatpak SDK for Rust, it must be in your `PATH`:
+
+ * install the SDK extensions with `flatpak install org.freedesktop.Sdk.Extension.{llvm15,rust-stable}//23.08`
+ * enable SDK extensions in the editor with the environment variable `FLATPAK_ENABLE_SDK_EXT=llvm15,rust-stable` (this can be done using flatseal or `flatpak override`)
+
+If you want to use Flatpak in combination with `rustup`, the following
+steps might help:
+
+-   both Rust and `rustup` have to be installed using
+    <https://rustup.rs>. Distro packages *will not* work.
+
+-   you need to launch Code, open a terminal and run `echo $PATH`
+
+-   using
+    [Flatseal](https://flathub.org/apps/details/com.github.tchx84.Flatseal),
+    you must add an environment variable called `PATH`. Set its value to
+    the output from above, appending `:~/.cargo/bin`, where `~` is the
+    path to your home directory. You must replace `~`, as it won’t be
+    expanded otherwise.
+
+-   while Flatseal is open, you must enable access to "All user files"
+
+A C compiler should already be available via `org.freedesktop.Sdk`. Any
+other tools or libraries you will need to acquire from Flatpak.
+
+## Emacs
+
+Prerequisites: You have installed the [`rust-analyzer`
+binary](#rust-analyzer-language-server-binary).
+
+To use `rust-analyzer`, you need to install and enable one of the two
+popular LSP client implementations for Emacs,
+[Eglot](https://github.com/joaotavora/eglot) or [LSP
+Mode](https://github.com/emacs-lsp/lsp-mode). Both enable
+`rust-analyzer` by default in rust buffers if it is available.
+
+### Eglot
+
+Eglot is the more minimalistic and lightweight LSP client for Emacs,
+integrates well with existing Emacs functionality and is built into
+Emacs starting from release 29.
+
+After installing Eglot, e.g. via `M-x package-install` (not needed from
+Emacs 29), you can enable it via the `M-x eglot` command or load it
+automatically in `rust-mode` via
+
+    (add-hook 'rust-mode-hook 'eglot-ensure)
+
+To enable clippy, you will need to configure the initialization options
+to pass the `check.command` setting.
+
+    (add-to-list 'eglot-server-programs
+                 '((rust-ts-mode rust-mode) .
+                   ("rust-analyzer" :initializationOptions (:check (:command "clippy")))))
+
+For more detailed instructions and options see the [Eglot
+manual](https://joaotavora.github.io/eglot) (also available from Emacs
+via `M-x info`) and the [Eglot
+readme](https://github.com/joaotavora/eglot/blob/master/README.md).
+
+Eglot does not support the rust-analyzer extensions to the
+language-server protocol and does not aim to do so in the future. The
+[eglot-x](https://github.com/nemethf/eglot-x#rust-analyzer-extensions)
+package adds experimental support for those LSP extensions.
+
+### LSP Mode
+
+LSP-mode is the original LSP-client for emacs. Compared to Eglot it has
+a larger codebase and supports more features, like LSP protocol
+extensions. With extension packages like [LSP
+UI](https://github.com/emacs-lsp/lsp-mode) it offers a lot of visual
+eyecandy. Further it integrates well with [DAP
+mode](https://github.com/emacs-lsp/dap-mode) for support of the Debug
+Adapter Protocol.
+
+You can install LSP-mode via `M-x package-install` and then run it via
+the `M-x lsp` command or load it automatically in rust buffers with
+
+    (add-hook 'rust-mode-hook 'lsp-deferred)
+
+For more information on how to set up LSP mode and its extension package
+see the instructions in the [LSP mode
+manual](https://emacs-lsp.github.io/lsp-mode/page/installation). Also
+see the [rust-analyzer
+section](https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/)
+for `rust-analyzer` specific options and commands, which you can
+optionally bind to keys.
+
+Note the excellent
+[guide](https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/) from
+[@rksm](https://github.com/rksm) on how to set-up Emacs for Rust
+development with LSP mode and several other packages.
+
+## Vim/Neovim
+
+Prerequisites: You have installed the [`rust-analyzer`
+binary](#rust-analyzer-language-server-binary). Not needed if the
+extension can install/update it on its own, coc-rust-analyzer is one
+example.
+
+There are several LSP client implementations for Vim or Neovim:
+
+### coc-rust-analyzer
+
+1.  Install coc.nvim by following the instructions at
+    [coc.nvim](https://github.com/neoclide/coc.nvim) (Node.js required)
+
+2.  Run `:CocInstall coc-rust-analyzer` to install
+    [coc-rust-analyzer](https://github.com/fannheyward/coc-rust-analyzer),
+    this extension implements *most* of the features supported in the
+    VSCode extension:
+
+    -   automatically install and upgrade stable/nightly releases
+
+    -   same configurations as VSCode extension,
+        `rust-analyzer.server.path`, `rust-analyzer.cargo.features` etc.
+
+    -   same commands too, `rust-analyzer.analyzerStatus`,
+        `rust-analyzer.ssr` etc.
+
+    -   inlay hints for variables and method chaining, *Neovim Only*
+
+Note: for code actions, use `coc-codeaction-cursor` and
+`coc-codeaction-selected`; `coc-codeaction` and `coc-codeaction-line`
+are unlikely to be useful.
+
+### LanguageClient-neovim
+
+1.  Install LanguageClient-neovim by following the instructions
+    [here](https://github.com/autozimu/LanguageClient-neovim)
+
+    -   The GitHub project wiki has extra tips on configuration
+
+2.  Configure by adding this to your Vim/Neovim config file (replacing
+    the existing Rust-specific line if it exists):
+
+        let g:LanguageClient_serverCommands = {
+        \ 'rust': ['rust-analyzer'],
+        \ }
+
+### YouCompleteMe
+
+Install YouCompleteMe by following the instructions
+[here](https://github.com/ycm-core/YouCompleteMe#installation).
+
+rust-analyzer is the default in ycm, it should work out of the box.
+
+### ALE
+
+To use the LSP server in [ale](https://github.com/dense-analysis/ale):
+
+    let g:ale_linters = {'rust': ['analyzer']}
+
+### nvim-lsp
+
+Neovim 0.5 has built-in language server support. For a quick start
+configuration of rust-analyzer, use
+[neovim/nvim-lspconfig](https://github.com/neovim/nvim-lspconfig#rust_analyzer).
+Once `neovim/nvim-lspconfig` is installed, use
+`lua require'lspconfig'.rust_analyzer.setup({})` in your `init.vim`.
+
+You can also pass LSP settings to the server:
+
+    lua << EOF
+    local lspconfig = require'lspconfig'
+
+    local on_attach = function(client)
+        require'completion'.on_attach(client)
+    end
+
+    lspconfig.rust_analyzer.setup({
+        on_attach = on_attach,
+        settings = {
+            ["rust-analyzer"] = {
+                imports = {
+                    granularity = {
+                        group = "module",
+                    },
+                    prefix = "self",
+                },
+                cargo = {
+                    buildScripts = {
+                        enable = true,
+                    },
+                },
+                procMacro = {
+                    enable = true
+                },
+            }
+        }
+    })
+    EOF
+
+If you're running Neovim 0.10 or later, you can enable inlay hints via `on_attach`:
+
+```vim
+lspconfig.rust_analyzer.setup({
+    on_attach = function(client, bufnr)
+        vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
+    end
+})
+```
+
+Note that the hints are only visible after `rust-analyzer` has finished loading **and** you have to
+edit the file to trigger a re-render.
+
+See <https://sharksforarms.dev/posts/neovim-rust/> for more tips on
+getting started.
+
+Check out <https://github.com/mrcjkb/rustaceanvim> for a batteries
+included rust-analyzer setup for Neovim.
+
+### vim-lsp
+
+vim-lsp is installed by following [the plugin
+instructions](https://github.com/prabirshrestha/vim-lsp). It can be as
+simple as adding this line to your `.vimrc`:
+
+    Plug 'prabirshrestha/vim-lsp'
+
+Next you need to register the `rust-analyzer` binary. If it is avim.lspvailable
+in `$PATH`, you may want to add this to your `.vimrc`:
+
+    if executable('rust-analyzer')
+      au User lsp_setup call lsp#register_server({
+            \   'name': 'Rust Language Server',
+            \   'cmd': {server_info->['rust-analyzer']},
+            \   'whitelist': ['rust'],
+            \ })
+    endif
+
+There is no dedicated UI for the server configuration, so you would need
+to send any options as a value of the `initialization_options` field, as
+described in the [Configuration](#configuration) section. Here is an
+example of how to enable the proc-macro support:
+
+    if executable('rust-analyzer')
+      au User lsp_setup call lsp#register_server({
+            \   'name': 'Rust Language Server',
+            \   'cmd': {server_info->['rust-analyzer']},
+            \   'whitelist': ['rust'],
+            \   'initialization_options': {
+            \     'cargo': {
+            \       'buildScripts': {
+            \         'enable': v:true,
+            \       },
+            \     },
+            \     'procMacro': {
+            \       'enable': v:true,
+            \     },
+            \   },
+            \ })
+    endif
+
+## Sublime Text
+
+### Sublime Text 4:
+
+-   Follow the instructions in
+    [LSP-rust-analyzer](https://github.com/sublimelsp/LSP-rust-analyzer).
+
+Install
+[LSP-file-watcher-chokidar](https://packagecontrol.io/packages/LSP-file-watcher-chokidar)
+to enable file watching (`workspace/didChangeWatchedFiles`).
+
+### Sublime Text 3:
+
+-   Install the [`rust-analyzer`
+    binary](#rust-analyzer-language-server-binary).
+
+-   Install the [LSP package](https://packagecontrol.io/packages/LSP).
+
+-   From the command palette, run `LSP: Enable Language Server Globally`
+    and select `rust-analyzer`.
+
+If it worked, you should see "rust-analyzer, Line X, Column Y" on the
+left side of the status bar, and after waiting a bit, functionalities
+like tooltips on hovering over variables should become available.
+
+If you get an error saying `No such file or directory: 'rust-analyzer'`,
+see the [`rust-analyzer` binary](#rust-analyzer-language-server-binary)
+section on installing the language server binary.
+
+## GNOME Builder
+
+GNOME Builder 3.37.1 and newer has native `rust-analyzer` support. If
+the LSP binary is not available, GNOME Builder can install it when
+opening a Rust file.
+
+## Eclipse IDE
+
+Support for Rust development in the Eclipse IDE is provided by [Eclipse
+Corrosion](https://github.com/eclipse/corrosion). If available in PATH
+or in some standard location, `rust-analyzer` is detected and powers
+editing of Rust files without further configuration. If `rust-analyzer`
+is not detected, Corrosion will prompt you for configuration of your
+Rust toolchain and language server with a link to the *Window &gt;
+Preferences &gt; Rust* preference page; from here a button allows to
+download and configure `rust-analyzer`, but you can also reference
+another installation. You’ll need to close and reopen all .rs and Cargo
+files, or to restart the IDE, for this change to take effect.
+
+## Kate Text Editor
+
+Support for the language server protocol is built into Kate through the
+LSP plugin, which is included by default. It is preconfigured to use
+rust-analyzer for Rust sources since Kate 21.12.
+
+To change rust-analyzer config options, start from the following example
+and put it into Kate’s "User Server Settings" tab (located under the LSP
+Client settings):
+
+    {
+        "servers": {
+            "rust": {
+                "initializationOptions": {
+                    "cachePriming": {
+                        "enable": false
+                    },
+                    "check": {
+                        "allTargets": false
+                    },
+                    "checkOnSave": false
+                }
+            }
+        }
+    }
+
+Then click on apply, and restart the LSP server for your rust project.
+
+## juCi++
+
+[juCi++](https://gitlab.com/cppit/jucipp) has built-in support for the
+language server protocol, and since version 1.7.0 offers installation of
+both Rust and rust-analyzer when opening a Rust file.
+
+## Kakoune
+
+[Kakoune](https://kakoune.org/) supports LSP with the help of
+[`kak-lsp`](https://github.com/kak-lsp/kak-lsp). Follow the
+[instructions](https://github.com/kak-lsp/kak-lsp#installation) to
+install `kak-lsp`. To configure `kak-lsp`, refer to the [configuration
+section](https://github.com/kak-lsp/kak-lsp#configuring-kak-lsp) which
+is basically about copying the [configuration
+file](https://github.com/kak-lsp/kak-lsp/blob/master/kak-lsp.toml) in
+the right place (latest versions should use `rust-analyzer` by default).
+
+Finally, you need to configure Kakoune to talk to `kak-lsp` (see [Usage
+section](https://github.com/kak-lsp/kak-lsp#usage)). A basic
+configuration will only get you LSP but you can also activate inlay
+diagnostics and auto-formatting on save. The following might help you
+get all of this.
+
+    eval %sh{kak-lsp --kakoune -s $kak_session}  # Not needed if you load it with plug.kak.
+    hook global WinSetOption filetype=rust %{
+        # Enable LSP
+        lsp-enable-window
+
+        # Auto-formatting on save
+        hook window BufWritePre .* lsp-formatting-sync
+
+        # Configure inlay hints (only on save)
+        hook window -group rust-inlay-hints BufWritePost .* rust-analyzer-inlay-hints
+        hook -once -always window WinSetOption filetype=.* %{
+            remove-hooks window rust-inlay-hints
+        }
+    }
+
+## Helix
+
+[Helix](https://docs.helix-editor.com/) supports LSP by default.
+However, it won’t install `rust-analyzer` automatically. You can follow
+instructions for installing [`rust-analyzer`
+binary](#rust-analyzer-language-server-binary).
+
+## Visual Studio 2022
+
+There are multiple rust-analyzer extensions for Visual Studio 2022 on
+Windows:
+
+### rust-analyzer.vs
+
+(License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0
+International)
+
+[Visual Studio
+Marketplace](https://marketplace.visualstudio.com/items?itemName=kitamstudios.RustAnalyzer)
+
+[GitHub](https://github.com/kitamstudios/rust-analyzer/)
+
+Support for Rust development in the Visual Studio IDE is enabled by the
+[rust-analyzer](https://marketplace.visualstudio.com/items?itemName=kitamstudios.RustAnalyzer)
+package. Either click on the download link or install from IDE’s
+extension manager. For now [Visual Studio
+2022](https://visualstudio.microsoft.com/downloads/) is required. All
+editions are supported viz. Community, Professional & Enterprise. The
+package aims to provide 0-friction installation and therefore comes
+loaded with most things required including rust-analyzer binary. If
+anything it needs is missing, appropriate errors / warnings will guide
+the user. E.g. cargo.exe needs to be in path and the package will tell
+you as much. This package is under rapid active development. So if you
+encounter any issues please file it at
+[rust-analyzer.vs](https://github.com/kitamstudios/rust-analyzer/).
+
+### VS\_RustAnalyzer
+
+(License: GPL)
+
+[Visual Studio
+Marketplace](https://marketplace.visualstudio.com/items?itemName=cchharris.vsrustanalyzer)
+
+[GitHub](https://github.com/cchharris/VS-RustAnalyzer)
+
+### SourceGear Rust
+
+(License: closed source)
+
+[Visual Studio
+Marketplace](https://marketplace.visualstudio.com/items?itemName=SourceGear.SourceGearRust)
+
+[GitHub (docs, issues,
+discussions)](https://github.com/sourcegear/rust-vs-extension)
+
+-   Free (no-cost)
+
+-   Supports all editions of Visual Studio 2022 on Windows: Community,
+    Professional, or Enterprise
+
+## Lapce
+
+[Lapce](https://lapce.dev/) has a Rust plugin which you can install
+directly. Unfortunately, it downloads an old version of `rust-analyzer`,
+but you can set the server path under Settings.
+
+## Crates
+
+There is a package named `ra_ap_rust_analyzer` available on
+[crates.io](https://crates.io/crates/ra_ap_rust-analyzer), for someone
+who wants to use it programmatically.
+
+For more details, see [the publish
+workflow](https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/autopublish.yaml).
+
+## Zed
+
+[Zed](https://zed.dev) has native `rust-analyzer` support. If the LSP
+binary is not available, Zed can install it when opening a Rust file.
diff --git a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md
new file mode 100644
index 00000000000..151f8758a17
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md
@@ -0,0 +1,246 @@
+# Non-Cargo Based Projects
+
+rust-analyzer does not require Cargo. However, if you use some other
+build system, you’ll have to describe the structure of your project for
+rust-analyzer in the `rust-project.json` format:
+
+```typescript
+interface JsonProject {
+    /// Path to the sysroot directory.
+    ///
+    /// The sysroot is where rustc looks for the
+    /// crates that are built-in to rust, such as
+    /// std.
+    ///
+    /// https://doc.rust-lang.org/rustc/command-line-arguments.html#--sysroot-override-the-system-root
+    ///
+    /// To see the current value of sysroot, you
+    /// can query rustc:
+    ///
+    /// ```
+    /// $ rustc --print sysroot
+    /// /Users/yourname/.rustup/toolchains/stable-x86_64-apple-darwin
+    /// ```
+    sysroot?: string;
+    /// Path to the directory with *source code* of
+    /// sysroot crates.
+    ///
+    /// By default, this is `lib/rustlib/src/rust/library`
+    /// relative to the sysroot.
+    ///
+    /// It should point to the directory where std,
+    /// core, and friends can be found:
+    ///
+    /// https://github.com/rust-lang/rust/tree/master/library.
+    ///
+    /// If provided, rust-analyzer automatically adds
+    /// dependencies on sysroot crates. Conversely,
+    /// if you omit this path, you can specify sysroot
+    /// dependencies yourself and, for example, have
+    /// several different "sysroots" in one graph of
+    /// crates.
+    sysroot_src?: string;
+    /// List of groups of common cfg values, to allow
+    /// sharing them between crates.
+    ///
+    /// Maps from group name to its cfgs. Cfg follow
+    /// the same format as `Crate.cfg`.
+    cfg_groups?: { [key: string]: string[]; };
+    /// The set of crates comprising the current
+    /// project. Must include all transitive
+    /// dependencies as well as sysroot crate (libstd,
+    /// libcore and such).
+    crates: Crate[];
+    /// Configuration for CLI commands.
+    ///
+    /// These are used for running and debugging binaries
+    /// and tests without encoding build system-specific
+    /// knowledge into rust-analyzer.
+    ///
+    /// # Example
+    ///
+    /// Below is an example of a test runnable. `{label}` and `{test_id}`
+    /// are explained in `Runnable::args`'s documentation below.
+    ///
+    /// ```json
+    /// {
+    ///     "program": "buck",
+    ///     "args": [
+    ///         "test",
+    ///          "{label}",
+    ///          "--",
+    ///          "{test_id}",
+    ///          "--print-passing-details"
+    ///     ],
+    ///     "cwd": "/home/user/repo-root/",
+    ///     "kind": "testOne"
+    /// }
+    /// ```
+    runnables?: Runnable[];
+}
+
+interface Crate {
+    /// Optional crate name used for display purposes,
+    /// without affecting semantics. See the `deps`
+    /// key for semantically-significant crate names.
+    display_name?: string;
+    /// Path to the root module of the crate.
+    root_module: string;
+    /// Edition of the crate.
+    edition: '2015' | '2018' | '2021' | '2024';
+    /// The version of the crate. Used for calculating
+    /// the correct docs.rs URL.
+    version?: string;
+    /// Dependencies
+    deps: Dep[];
+    /// Should this crate be treated as a member of
+    /// current "workspace".
+    ///
+    /// By default, inferred from the `root_module`
+    /// (members are the crates which reside inside
+    /// the directory opened in the editor).
+    ///
+    /// Set this to `false` for things like standard
+    /// library and 3rd party crates to enable
+    /// performance optimizations (rust-analyzer
+    /// assumes that non-member crates don't change).
+    is_workspace_member?: boolean;
+    /// Optionally specify the (super)set of `.rs`
+    /// files comprising this crate.
+    ///
+    /// By default, rust-analyzer assumes that only
+    /// files under `root_module.parent` can belong
+    /// to a crate. `include_dirs` are included
+    /// recursively, unless a subdirectory is in
+    /// `exclude_dirs`.
+    ///
+    /// Different crates can share the same `source`.
+    ///
+    /// If two crates share an `.rs` file in common,
+    /// they *must* have the same `source`.
+    /// rust-analyzer assumes that files from one
+    /// source can't refer to files in another source.
+    source?: {
+        include_dirs: string[];
+        exclude_dirs: string[];
+    };
+    /// List of cfg groups this crate inherits.
+    ///
+    /// All cfg in these groups will be concatenated to
+    /// `cfg`. It is impossible to replace a value from
+    /// the groups.
+    cfg_groups?: string[];
+    /// The set of cfgs activated for a given crate, like
+    /// `["unix", "feature=\"foo\"", "feature=\"bar\""]`.
+    cfg: string[];
+    /// Target tuple for this Crate.
+    ///
+    /// Used when running `rustc --print cfg`
+    /// to get target-specific cfgs.
+    target?: string;
+    /// Environment variables, used for
+    /// the `env!` macro
+    env: { [key: string]: string; };
+
+    /// Whether the crate is a proc-macro crate.
+    is_proc_macro: boolean;
+    /// For proc-macro crates, path to compiled
+    /// proc-macro (.so file).
+    proc_macro_dylib_path?: string;
+
+    /// Repository, matching the URL that would be used
+    /// in Cargo.toml.
+    repository?: string;
+
+    /// Build-specific data about this crate.
+    build?: BuildInfo;
+}
+
+interface Dep {
+    /// Index of a crate in the `crates` array.
+    crate: number;
+    /// Name as should appear in the (implicit)
+    /// `extern crate name` declaration.
+    name: string;
+}
+
+interface BuildInfo {
+    /// The name associated with this crate.
+    ///
+    /// This is determined by the build system that produced
+    /// the `rust-project.json` in question. For instance, if buck were used,
+    /// the label might be something like `//ide/rust/rust-analyzer:rust-analyzer`.
+    ///
+    /// Do not attempt to parse the contents of this string; it is a build system-specific
+    /// identifier similar to `Crate::display_name`.
+    label: string;
+    /// Path corresponding to the build system-specific file defining the crate.
+    build_file: string;
+    /// The kind of target.
+    ///
+    /// This information is used to determine what sort
+    /// of runnable codelens to provide, if any.
+    target_kind: 'bin' | 'lib' | 'test';
+}
+
+interface Runnable {
+    /// The program invoked by the runnable.
+    ///
+    /// For example, this might be `cargo`, `buck`, or `bazel`.
+    program: string;
+    /// The arguments passed to `program`.
+    args: string[];
+    /// The current working directory of the runnable.
+    cwd: string;
+    /// Used to decide what code lens to offer.
+    ///
+    /// `testOne`: This runnable will be used when the user clicks the 'Run Test'
+    /// CodeLens above a test.
+    ///
+    /// The args for testOne can contain two template strings:
+    /// `{label}` and `{test_id}`. `{label}` will be replaced
+    /// with the `Build::label` and `{test_id}` will be replaced
+    /// with the test name.
+    kind: 'testOne' | string;
+}
+```
+
+This format is provisional and subject to change. Specifically, the
+`roots` setup will be different eventually.
+
+There are three ways to feed `rust-project.json` to rust-analyzer:
+
+-   Place `rust-project.json` file at the root of the project, and
+    rust-analyzer will discover it.
+
+-   Specify
+    `"rust-analyzer.linkedProjects": [ "path/to/rust-project.json" ]` in
+    the settings (and make sure that your LSP client sends settings as a
+    part of initialize request).
+
+-   Specify
+    `"rust-analyzer.linkedProjects": [ { "roots": […​], "crates": […​] }]`
+    inline.
+
+Relative paths are interpreted relative to `rust-project.json` file
+location or (for inline JSON) relative to `rootUri`.
+
+You can set the `RA_LOG` environment variable to `rust_analyzer=info` to
+inspect how rust-analyzer handles config and project loading.
+
+Note that calls to `cargo check` are disabled when using
+`rust-project.json` by default, so compilation errors and warnings will
+no longer be sent to your LSP client. To enable these compilation errors
+you will need to specify explicitly what command rust-analyzer should
+run to perform the checks using the
+`rust-analyzer.check.overrideCommand` configuration. As an example, the
+following configuration explicitly sets `cargo check` as the `check`
+command.
+
+    { "rust-analyzer.check.overrideCommand": ["cargo", "check", "--message-format=json"] }
+
+`check.overrideCommand` requires the command specified to output json
+error messages for rust-analyzer to consume. The `--message-format=json`
+flag does this for `cargo check` so whichever command you use must also
+output errors in this format. See the [Configuration](#_configuration)
+section for more information.
diff --git a/src/tools/rust-analyzer/docs/book/src/privacy.md b/src/tools/rust-analyzer/docs/book/src/privacy.md
new file mode 100644
index 00000000000..602c68d6f67
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/privacy.md
@@ -0,0 +1,15 @@
+# Privacy
+
+The LSP server performs no network access in itself, but runs
+`cargo metadata` which will update or download the crate registry and
+the source code of the project dependencies. If enabled (the default),
+build scripts and procedural macros can do anything.
+
+The Code extension does not access the network.
+
+Any other editor plugins are not under the control of the
+`rust-analyzer` developers. For any privacy concerns, you should check
+with their respective developers.
+
+For `rust-analyzer` developers, `cargo xtask release` uses the GitHub
+API to put together the release notes.
diff --git a/src/tools/rust-analyzer/docs/book/src/security.md b/src/tools/rust-analyzer/docs/book/src/security.md
new file mode 100644
index 00000000000..1444af03248
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/security.md
@@ -0,0 +1,19 @@
+# Security
+
+At the moment, rust-analyzer assumes that all code is trusted. Here is a
+**non-exhaustive** list of ways to make rust-analyzer execute arbitrary
+code:
+
+-   proc macros and build scripts are executed by default
+
+-   `.cargo/config` can override `rustc` with an arbitrary executable
+
+-   `rust-toolchain.toml` can override `rustc` with an arbitrary
+    executable
+
+-   VS Code plugin reads configuration from project directory, and that
+    can be used to override paths to various executables, like `rustfmt`
+    or `rust-analyzer` itself.
+
+-   rust-analyzer’s syntax trees library uses a lot of `unsafe` and
+    hasn’t been properly audited for memory safety.
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/docs/book/src/troubleshooting.md b/src/tools/rust-analyzer/docs/book/src/troubleshooting.md
new file mode 100644
index 00000000000..4092b9de990
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/book/src/troubleshooting.md
@@ -0,0 +1,50 @@
+# Troubleshooting
+
+Start with looking at the rust-analyzer version. Try **rust-analyzer:
+Show RA Version** in VS Code (using **Command Palette** feature
+typically activated by Ctrl+Shift+P) or `rust-analyzer --version` in the
+command line. If the date is more than a week ago, it’s better to update
+rust-analyzer version.
+
+The next thing to check would be panic messages in rust-analyzer’s log.
+Log messages are printed to stderr, in VS Code you can see them in the
+`Output > Rust Analyzer Language Server` tab of the panel. To see more
+logs, set the `RA_LOG=info` environment variable, this can be done
+either by setting the environment variable manually or by using
+`rust-analyzer.server.extraEnv`, note that both of these approaches
+require the server to be restarted.
+
+To fully capture LSP messages between the editor and the server, run
+the `rust-analyzer: Toggle LSP Logs` command and check `Output > Rust
+Analyzer Language Server Trace`.
+
+The root cause for many "nothing works" problems is that rust-analyzer
+fails to understand the project structure. To debug that, first note the
+`rust-analyzer` section in the status bar. If it has an error icon and
+red, that’s the problem (hover will have somewhat helpful error
+message). **rust-analyzer: Status** prints dependency information for
+the current file. Finally, `RA_LOG=project_model=debug` enables verbose
+logs during project loading.
+
+If rust-analyzer outright crashes, try running
+`rust-analyzer analysis-stats /path/to/project/directory/` on the
+command line. This command type checks the whole project in batch mode
+bypassing LSP machinery.
+
+When filing issues, it is useful (but not necessary) to try to minimize
+examples. An ideal bug reproduction looks like this:
+
+```shell
+$ git clone https://github.com/username/repo.git && cd repo && git switch --detach commit-hash
+$ rust-analyzer --version
+rust-analyzer dd12184e4 2021-05-08 dev
+$ rust-analyzer analysis-stats .
+💀 💀 💀
+```
+
+It is especially useful when the `repo` doesn’t use external crates or
+the standard library.
+
+If you want to go as far as to modify the source code to debug the
+problem, be sure to take a look at the [dev
+docs](https://github.com/rust-lang/rust-analyzer/tree/master/docs/dev)!
diff --git a/src/tools/rust-analyzer/docs/dev/style.md b/src/tools/rust-analyzer/docs/dev/style.md
index 4c5299bde3e..51b60ab2ebb 100644
--- a/src/tools/rust-analyzer/docs/dev/style.md
+++ b/src/tools/rust-analyzer/docs/dev/style.md
@@ -873,7 +873,7 @@ Use `anyhow::format_err!` rather than `anyhow::anyhow`.
 **Rationale:** consistent, boring, avoids stuttering.
 
 There's no specific guidance on the formatting of error messages, see [anyhow/#209](https://github.com/dtolnay/anyhow/issues/209).
-Do not end error and context messages with `.` though. 
+Do not end error and context messages with `.` though.
 
 ## Early Returns
 
@@ -1172,7 +1172,7 @@ MergeBehavior::Last => {
 **Rationale:** writing a sentence (or maybe even a paragraph) rather just "a comment" creates a more appropriate frame of mind.
 It tricks you into writing down more of the context you keep in your head while coding.
 
-For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines.
+For `.md` files prefer a sentence-per-line format, don't wrap lines.
 If the line is too long, you want to split the sentence in two :-)
 
 **Rationale:** much easier to edit the text and read the diff, see [this link](https://asciidoctor.org/docs/asciidoc-recommended-practices/#one-sentence-per-line).
diff --git a/src/tools/rust-analyzer/docs/user/.gitignore b/src/tools/rust-analyzer/docs/user/.gitignore
deleted file mode 100644
index c32b1bcec2e..00000000000
--- a/src/tools/rust-analyzer/docs/user/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-manual.html
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
deleted file mode 100644
index b33de1956b8..00000000000
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ /dev/null
@@ -1,1197 +0,0 @@
-[[rust-analyzer.assist.emitMustUse]]rust-analyzer.assist.emitMustUse (default: `false`)::
-+
---
-Whether to insert #[must_use] when generating `as_` methods
-for enum variants.
---
-[[rust-analyzer.assist.expressionFillDefault]]rust-analyzer.assist.expressionFillDefault (default: `"todo"`)::
-+
---
-Placeholder expression to use for missing expressions in assists.
---
-[[rust-analyzer.assist.termSearch.borrowcheck]]rust-analyzer.assist.termSearch.borrowcheck (default: `true`)::
-+
---
-Enable borrow checking for term search code assists. If set to false, also there will be more suggestions, but some of them may not borrow-check.
---
-[[rust-analyzer.assist.termSearch.fuel]]rust-analyzer.assist.termSearch.fuel (default: `1800`)::
-+
---
-Term search fuel in "units of work" for assists (Defaults to 1800).
---
-[[rust-analyzer.cachePriming.enable]]rust-analyzer.cachePriming.enable (default: `true`)::
-+
---
-Warm up caches on project load.
---
-[[rust-analyzer.cachePriming.numThreads]]rust-analyzer.cachePriming.numThreads (default: `"physical"`)::
-+
---
-How many worker threads to handle priming caches. The default `0` means to pick automatically.
---
-[[rust-analyzer.cargo.allTargets]]rust-analyzer.cargo.allTargets (default: `true`)::
-+
---
-Pass `--all-targets` to cargo invocation.
---
-[[rust-analyzer.cargo.autoreload]]rust-analyzer.cargo.autoreload (default: `true`)::
-+
---
-Automatically refresh project info via `cargo metadata` on
-`Cargo.toml` or `.cargo/config.toml` changes.
---
-[[rust-analyzer.cargo.buildScripts.enable]]rust-analyzer.cargo.buildScripts.enable (default: `true`)::
-+
---
-Run build scripts (`build.rs`) for more precise code analysis.
---
-[[rust-analyzer.cargo.buildScripts.invocationStrategy]]rust-analyzer.cargo.buildScripts.invocationStrategy (default: `"per_workspace"`)::
-+
---
-Specifies the invocation strategy to use when running the build scripts command.
-If `per_workspace` is set, the command will be executed for each Rust workspace with the
-workspace as the working directory.
-If `once` is set, the command will be executed once with the opened project as the
-working directory.
-This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
-is set.
---
-[[rust-analyzer.cargo.buildScripts.overrideCommand]]rust-analyzer.cargo.buildScripts.overrideCommand (default: `null`)::
-+
---
-Override the command rust-analyzer uses to run build scripts and
-build procedural macros. The command is required to output json
-and should therefore include `--message-format=json` or a similar
-option.
-
-If there are multiple linked projects/workspaces, this command is invoked for
-each of them, with the working directory being the workspace root
-(i.e., the folder containing the `Cargo.toml`). This can be overwritten
-by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`.
-
-By default, a cargo invocation will be constructed for the configured
-targets and features, with the following base command line:
-
-```bash
-cargo check --quiet --workspace --message-format=json --all-targets --keep-going
-```
-.
---
-[[rust-analyzer.cargo.buildScripts.rebuildOnSave]]rust-analyzer.cargo.buildScripts.rebuildOnSave (default: `true`)::
-+
---
-Rerun proc-macros building/build-scripts running when proc-macro
-or build-script sources change and are saved.
---
-[[rust-analyzer.cargo.buildScripts.useRustcWrapper]]rust-analyzer.cargo.buildScripts.useRustcWrapper (default: `true`)::
-+
---
-Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
-avoid checking unnecessary things.
---
-[[rust-analyzer.cargo.cfgs]]rust-analyzer.cargo.cfgs::
-+
---
-Default:
-----
-[
-  "debug_assertions",
-  "miri"
-]
-----
-List of cfg options to enable with the given values.
-
---
-[[rust-analyzer.cargo.extraArgs]]rust-analyzer.cargo.extraArgs (default: `[]`)::
-+
---
-Extra arguments that are passed to every cargo invocation.
---
-[[rust-analyzer.cargo.extraEnv]]rust-analyzer.cargo.extraEnv (default: `{}`)::
-+
---
-Extra environment variables that will be set when running cargo, rustc
-or other commands within the workspace. Useful for setting RUSTFLAGS.
---
-[[rust-analyzer.cargo.features]]rust-analyzer.cargo.features (default: `[]`)::
-+
---
-List of features to activate.
-
-Set this to `"all"` to pass `--all-features` to cargo.
---
-[[rust-analyzer.cargo.noDefaultFeatures]]rust-analyzer.cargo.noDefaultFeatures (default: `false`)::
-+
---
-Whether to pass `--no-default-features` to cargo.
---
-[[rust-analyzer.cargo.sysroot]]rust-analyzer.cargo.sysroot (default: `"discover"`)::
-+
---
-Relative path to the sysroot, or "discover" to try to automatically find it via
-"rustc --print sysroot".
-
-Unsetting this disables sysroot loading.
-
-This option does not take effect until rust-analyzer is restarted.
---
-[[rust-analyzer.cargo.sysrootSrc]]rust-analyzer.cargo.sysrootSrc (default: `null`)::
-+
---
-Relative path to the sysroot library sources. If left unset, this will default to
-`{cargo.sysroot}/lib/rustlib/src/rust/library`.
-
-This option does not take effect until rust-analyzer is restarted.
---
-[[rust-analyzer.cargo.target]]rust-analyzer.cargo.target (default: `null`)::
-+
---
-Compilation target override (target tuple).
---
-[[rust-analyzer.cargo.targetDir]]rust-analyzer.cargo.targetDir (default: `null`)::
-+
---
-Optional path to a rust-analyzer specific target directory.
-This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro
-building from locking the `Cargo.lock` at the expense of duplicating build artifacts.
-
-Set to `true` to use a subdirectory of the existing target directory or
-set to a path relative to the workspace to use that path.
---
-[[rust-analyzer.cfg.setTest]]rust-analyzer.cfg.setTest (default: `true`)::
-+
---
-Set `cfg(test)` for local crates. Defaults to true.
---
-[[rust-analyzer.checkOnSave]]rust-analyzer.checkOnSave (default: `true`)::
-+
---
-Run the check command for diagnostics on save.
---
-[[rust-analyzer.check.allTargets]]rust-analyzer.check.allTargets (default: `null`)::
-+
---
-Check all targets and tests (`--all-targets`). Defaults to
-`#rust-analyzer.cargo.allTargets#`.
---
-[[rust-analyzer.check.command]]rust-analyzer.check.command (default: `"check"`)::
-+
---
-Cargo command to use for `cargo check`.
---
-[[rust-analyzer.check.extraArgs]]rust-analyzer.check.extraArgs (default: `[]`)::
-+
---
-Extra arguments for `cargo check`.
---
-[[rust-analyzer.check.extraEnv]]rust-analyzer.check.extraEnv (default: `{}`)::
-+
---
-Extra environment variables that will be set when running `cargo check`.
-Extends `#rust-analyzer.cargo.extraEnv#`.
---
-[[rust-analyzer.check.features]]rust-analyzer.check.features (default: `null`)::
-+
---
-List of features to activate. Defaults to
-`#rust-analyzer.cargo.features#`.
-
-Set to `"all"` to pass `--all-features` to Cargo.
---
-[[rust-analyzer.check.ignore]]rust-analyzer.check.ignore (default: `[]`)::
-+
---
-List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.
-
-For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...
---
-[[rust-analyzer.check.invocationStrategy]]rust-analyzer.check.invocationStrategy (default: `"per_workspace"`)::
-+
---
-Specifies the invocation strategy to use when running the check command.
-If `per_workspace` is set, the command will be executed for each workspace.
-If `once` is set, the command will be executed once.
-This config only has an effect when `#rust-analyzer.check.overrideCommand#`
-is set.
---
-[[rust-analyzer.check.noDefaultFeatures]]rust-analyzer.check.noDefaultFeatures (default: `null`)::
-+
---
-Whether to pass `--no-default-features` to Cargo. Defaults to
-`#rust-analyzer.cargo.noDefaultFeatures#`.
---
-[[rust-analyzer.check.overrideCommand]]rust-analyzer.check.overrideCommand (default: `null`)::
-+
---
-Override the command rust-analyzer uses instead of `cargo check` for
-diagnostics on save. The command is required to output json and
-should therefore include `--message-format=json` or a similar option
-(if your client supports the `colorDiagnosticOutput` experimental
-capability, you can use `--message-format=json-diagnostic-rendered-ansi`).
-
-If you're changing this because you're using some tool wrapping
-Cargo, you might also want to change
-`#rust-analyzer.cargo.buildScripts.overrideCommand#`.
-
-If there are multiple linked projects/workspaces, this command is invoked for
-each of them, with the working directory being the workspace root
-(i.e., the folder containing the `Cargo.toml`). This can be overwritten
-by changing `#rust-analyzer.check.invocationStrategy#`.
-
-If `$saved_file` is part of the command, rust-analyzer will pass
-the absolute path of the saved file to the provided command. This is
-intended to be used with non-Cargo build systems.
-Note that `$saved_file` is experimental and may be removed in the future.
-
-An example command would be:
-
-```bash
-cargo check --workspace --message-format=json --all-targets
-```
-.
---
-[[rust-analyzer.check.targets]]rust-analyzer.check.targets (default: `null`)::
-+
---
-Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.
-
-Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g.
-`["aarch64-apple-darwin", "x86_64-apple-darwin"]`.
-
-Aliased as `"checkOnSave.targets"`.
---
-[[rust-analyzer.check.workspace]]rust-analyzer.check.workspace (default: `true`)::
-+
---
-Whether `--workspace` should be passed to `cargo check`.
-If false, `-p <package>` will be passed instead if applicable. In case it is not, no
-check will be performed.
---
-[[rust-analyzer.completion.addSemicolonToUnit]]rust-analyzer.completion.addSemicolonToUnit (default: `true`)::
-+
---
-Whether to automatically add a semicolon when completing unit-returning functions.
-
-In `match` arms it completes a comma instead.
---
-[[rust-analyzer.completion.autoAwait.enable]]rust-analyzer.completion.autoAwait.enable (default: `true`)::
-+
---
-Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.
---
-[[rust-analyzer.completion.autoIter.enable]]rust-analyzer.completion.autoIter.enable (default: `true`)::
-+
---
-Toggles the additional completions that automatically show method calls with `iter()` or `into_iter()` prefixed to them when completing on a type that has them.
---
-[[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::
-+
---
-Toggles the additional completions that automatically add imports when completed.
-Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
---
-[[rust-analyzer.completion.autoimport.exclude]]rust-analyzer.completion.autoimport.exclude::
-+
---
-Default:
-----
-[
-  {
-    "path": "core::borrow::Borrow",
-    "type": "methods"
-  },
-  {
-    "path": "core::borrow::BorrowMut",
-    "type": "methods"
-  }
-]
-----
-A list of full paths to items to exclude from auto-importing completions.
-
-Traits in this list won't have their methods suggested in completions unless the trait
-is in scope.
-
-You can either specify a string path which defaults to type "always" or use the more verbose
-form `{ "path": "path::to::item", type: "always" }`.
-
-For traits the type "methods" can be used to only exclude the methods but not the trait itself.
-
-This setting also inherits `#rust-analyzer.completion.excludeTraits#`.
-
---
-[[rust-analyzer.completion.autoself.enable]]rust-analyzer.completion.autoself.enable (default: `true`)::
-+
---
-Toggles the additional completions that automatically show method calls and field accesses
-with `self` prefixed to them when inside a method.
---
-[[rust-analyzer.completion.callable.snippets]]rust-analyzer.completion.callable.snippets (default: `"fill_arguments"`)::
-+
---
-Whether to add parenthesis and argument snippets when completing function.
---
-[[rust-analyzer.completion.excludeTraits]]rust-analyzer.completion.excludeTraits (default: `[]`)::
-+
---
-A list of full paths to traits whose methods to exclude from completion.
-
-Methods from these traits won't be completed, even if the trait is in scope. However, they will still be suggested on expressions whose type is `dyn Trait`, `impl Trait` or `T where T: Trait`.
-
-Note that the trait themselves can still be completed.
---
-[[rust-analyzer.completion.fullFunctionSignatures.enable]]rust-analyzer.completion.fullFunctionSignatures.enable (default: `false`)::
-+
---
-Whether to show full function/method signatures in completion docs.
---
-[[rust-analyzer.completion.hideDeprecated]]rust-analyzer.completion.hideDeprecated (default: `false`)::
-+
---
-Whether to omit deprecated items from autocompletion. By default they are marked as deprecated but not hidden.
---
-[[rust-analyzer.completion.limit]]rust-analyzer.completion.limit (default: `null`)::
-+
---
-Maximum number of completions to return. If `None`, the limit is infinite.
---
-[[rust-analyzer.completion.postfix.enable]]rust-analyzer.completion.postfix.enable (default: `true`)::
-+
---
-Whether to show postfix snippets like `dbg`, `if`, `not`, etc.
---
-[[rust-analyzer.completion.privateEditable.enable]]rust-analyzer.completion.privateEditable.enable (default: `false`)::
-+
---
-Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position.
---
-[[rust-analyzer.completion.snippets.custom]]rust-analyzer.completion.snippets.custom::
-+
---
-Default:
-----
-{
-  "Ok": {
-    "postfix": "ok",
-    "body": "Ok(${receiver})",
-    "description": "Wrap the expression in a `Result::Ok`",
-    "scope": "expr"
-  },
-  "Box::pin": {
-    "postfix": "pinbox",
-    "body": "Box::pin(${receiver})",
-    "requires": "std::boxed::Box",
-    "description": "Put the expression into a pinned `Box`",
-    "scope": "expr"
-  },
-  "Arc::new": {
-    "postfix": "arc",
-    "body": "Arc::new(${receiver})",
-    "requires": "std::sync::Arc",
-    "description": "Put the expression into an `Arc`",
-    "scope": "expr"
-  },
-  "Some": {
-    "postfix": "some",
-    "body": "Some(${receiver})",
-    "description": "Wrap the expression in an `Option::Some`",
-    "scope": "expr"
-  },
-  "Err": {
-    "postfix": "err",
-    "body": "Err(${receiver})",
-    "description": "Wrap the expression in a `Result::Err`",
-    "scope": "expr"
-  },
-  "Rc::new": {
-    "postfix": "rc",
-    "body": "Rc::new(${receiver})",
-    "requires": "std::rc::Rc",
-    "description": "Put the expression into an `Rc`",
-    "scope": "expr"
-  }
-}
-----
-Custom completion snippets.
-
---
-[[rust-analyzer.completion.termSearch.enable]]rust-analyzer.completion.termSearch.enable (default: `false`)::
-+
---
-Whether to enable term search based snippets like `Some(foo.bar().baz())`.
---
-[[rust-analyzer.completion.termSearch.fuel]]rust-analyzer.completion.termSearch.fuel (default: `1000`)::
-+
---
-Term search fuel in "units of work" for autocompletion (Defaults to 1000).
---
-[[rust-analyzer.diagnostics.disabled]]rust-analyzer.diagnostics.disabled (default: `[]`)::
-+
---
-List of rust-analyzer diagnostics to disable.
---
-[[rust-analyzer.diagnostics.enable]]rust-analyzer.diagnostics.enable (default: `true`)::
-+
---
-Whether to show native rust-analyzer diagnostics.
---
-[[rust-analyzer.diagnostics.experimental.enable]]rust-analyzer.diagnostics.experimental.enable (default: `false`)::
-+
---
-Whether to show experimental rust-analyzer diagnostics that might
-have more false positives than usual.
---
-[[rust-analyzer.diagnostics.remapPrefix]]rust-analyzer.diagnostics.remapPrefix (default: `{}`)::
-+
---
-Map of prefixes to be substituted when parsing diagnostic file paths.
-This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`.
---
-[[rust-analyzer.diagnostics.styleLints.enable]]rust-analyzer.diagnostics.styleLints.enable (default: `false`)::
-+
---
-Whether to run additional style lints.
---
-[[rust-analyzer.diagnostics.warningsAsHint]]rust-analyzer.diagnostics.warningsAsHint (default: `[]`)::
-+
---
-List of warnings that should be displayed with hint severity.
-
-The warnings will be indicated by faded text or three dots in code
-and will not show up in the `Problems Panel`.
---
-[[rust-analyzer.diagnostics.warningsAsInfo]]rust-analyzer.diagnostics.warningsAsInfo (default: `[]`)::
-+
---
-List of warnings that should be displayed with info severity.
-
-The warnings will be indicated by a blue squiggly underline in code
-and a blue icon in the `Problems Panel`.
---
-[[rust-analyzer.files.excludeDirs]]rust-analyzer.files.excludeDirs (default: `[]`)::
-+
---
-These directories will be ignored by rust-analyzer. They are
-relative to the workspace root, and globs are not supported. You may
-also need to add the folders to Code's `files.watcherExclude`.
---
-[[rust-analyzer.files.watcher]]rust-analyzer.files.watcher (default: `"client"`)::
-+
---
-Controls file watching implementation.
---
-[[rust-analyzer.highlightRelated.breakPoints.enable]]rust-analyzer.highlightRelated.breakPoints.enable (default: `true`)::
-+
---
-Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords.
---
-[[rust-analyzer.highlightRelated.closureCaptures.enable]]rust-analyzer.highlightRelated.closureCaptures.enable (default: `true`)::
-+
---
-Enables highlighting of all captures of a closure while the cursor is on the `|` or move keyword of a closure.
---
-[[rust-analyzer.highlightRelated.exitPoints.enable]]rust-analyzer.highlightRelated.exitPoints.enable (default: `true`)::
-+
---
-Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`).
---
-[[rust-analyzer.highlightRelated.references.enable]]rust-analyzer.highlightRelated.references.enable (default: `true`)::
-+
---
-Enables highlighting of related references while the cursor is on any identifier.
---
-[[rust-analyzer.highlightRelated.yieldPoints.enable]]rust-analyzer.highlightRelated.yieldPoints.enable (default: `true`)::
-+
---
-Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords.
---
-[[rust-analyzer.hover.actions.debug.enable]]rust-analyzer.hover.actions.debug.enable (default: `true`)::
-+
---
-Whether to show `Debug` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
---
-[[rust-analyzer.hover.actions.enable]]rust-analyzer.hover.actions.enable (default: `true`)::
-+
---
-Whether to show HoverActions in Rust files.
---
-[[rust-analyzer.hover.actions.gotoTypeDef.enable]]rust-analyzer.hover.actions.gotoTypeDef.enable (default: `true`)::
-+
---
-Whether to show `Go to Type Definition` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
---
-[[rust-analyzer.hover.actions.implementations.enable]]rust-analyzer.hover.actions.implementations.enable (default: `true`)::
-+
---
-Whether to show `Implementations` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
---
-[[rust-analyzer.hover.actions.references.enable]]rust-analyzer.hover.actions.references.enable (default: `false`)::
-+
---
-Whether to show `References` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
---
-[[rust-analyzer.hover.actions.run.enable]]rust-analyzer.hover.actions.run.enable (default: `true`)::
-+
---
-Whether to show `Run` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
---
-[[rust-analyzer.hover.actions.updateTest.enable]]rust-analyzer.hover.actions.updateTest.enable (default: `true`)::
-+
---
-Whether to show `Update Test` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` and `#rust-analyzer.hover.actions.run.enable#` are set.
---
-[[rust-analyzer.hover.documentation.enable]]rust-analyzer.hover.documentation.enable (default: `true`)::
-+
---
-Whether to show documentation on hover.
---
-[[rust-analyzer.hover.documentation.keywords.enable]]rust-analyzer.hover.documentation.keywords.enable (default: `true`)::
-+
---
-Whether to show keyword hover popups. Only applies when
-`#rust-analyzer.hover.documentation.enable#` is set.
---
-[[rust-analyzer.hover.links.enable]]rust-analyzer.hover.links.enable (default: `true`)::
-+
---
-Use markdown syntax for links on hover.
---
-[[rust-analyzer.hover.maxSubstitutionLength]]rust-analyzer.hover.maxSubstitutionLength (default: `20`)::
-+
---
-Whether to show what types are used as generic arguments in calls etc. on hover, and what is their max length to show such types, beyond it they will be shown with ellipsis.
-
-This can take three values: `null` means "unlimited", the string `"hide"` means to not show generic substitutions at all, and a number means to limit them to X characters.
-
-The default is 20 characters.
---
-[[rust-analyzer.hover.memoryLayout.alignment]]rust-analyzer.hover.memoryLayout.alignment (default: `"hexadecimal"`)::
-+
---
-How to render the align information in a memory layout hover.
---
-[[rust-analyzer.hover.memoryLayout.enable]]rust-analyzer.hover.memoryLayout.enable (default: `true`)::
-+
---
-Whether to show memory layout data on hover.
---
-[[rust-analyzer.hover.memoryLayout.niches]]rust-analyzer.hover.memoryLayout.niches (default: `false`)::
-+
---
-How to render the niche information in a memory layout hover.
---
-[[rust-analyzer.hover.memoryLayout.offset]]rust-analyzer.hover.memoryLayout.offset (default: `"hexadecimal"`)::
-+
---
-How to render the offset information in a memory layout hover.
---
-[[rust-analyzer.hover.memoryLayout.size]]rust-analyzer.hover.memoryLayout.size (default: `"both"`)::
-+
---
-How to render the size information in a memory layout hover.
---
-[[rust-analyzer.hover.show.enumVariants]]rust-analyzer.hover.show.enumVariants (default: `5`)::
-+
---
-How many variants of an enum to display when hovering on. Show none if empty.
---
-[[rust-analyzer.hover.show.fields]]rust-analyzer.hover.show.fields (default: `5`)::
-+
---
-How many fields of a struct, variant or union to display when hovering on. Show none if empty.
---
-[[rust-analyzer.hover.show.traitAssocItems]]rust-analyzer.hover.show.traitAssocItems (default: `null`)::
-+
---
-How many associated items of a trait to display when hovering a trait.
---
-[[rust-analyzer.imports.granularity.enforce]]rust-analyzer.imports.granularity.enforce (default: `false`)::
-+
---
-Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file.
---
-[[rust-analyzer.imports.granularity.group]]rust-analyzer.imports.granularity.group (default: `"crate"`)::
-+
---
-How imports should be grouped into use statements.
---
-[[rust-analyzer.imports.group.enable]]rust-analyzer.imports.group.enable (default: `true`)::
-+
---
-Group inserted imports by the https://rust-analyzer.github.io/manual.html#auto-import[following order]. Groups are separated by newlines.
---
-[[rust-analyzer.imports.merge.glob]]rust-analyzer.imports.merge.glob (default: `true`)::
-+
---
-Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
---
-[[rust-analyzer.imports.preferNoStd]]rust-analyzer.imports.preferNoStd (default: `false`)::
-+
---
-Prefer to unconditionally use imports of the core and alloc crate, over the std crate.
---
-[[rust-analyzer.imports.preferPrelude]]rust-analyzer.imports.preferPrelude (default: `false`)::
-+
---
-Whether to prefer import paths containing a `prelude` module.
---
-[[rust-analyzer.imports.prefix]]rust-analyzer.imports.prefix (default: `"plain"`)::
-+
---
-The path structure for newly inserted paths to use.
---
-[[rust-analyzer.imports.prefixExternPrelude]]rust-analyzer.imports.prefixExternPrelude (default: `false`)::
-+
---
-Whether to prefix external (including std, core) crate imports with `::`. e.g. "use ::std::io::Read;".
---
-[[rust-analyzer.inlayHints.bindingModeHints.enable]]rust-analyzer.inlayHints.bindingModeHints.enable (default: `false`)::
-+
---
-Whether to show inlay type hints for binding modes.
---
-[[rust-analyzer.inlayHints.chainingHints.enable]]rust-analyzer.inlayHints.chainingHints.enable (default: `true`)::
-+
---
-Whether to show inlay type hints for method chains.
---
-[[rust-analyzer.inlayHints.closingBraceHints.enable]]rust-analyzer.inlayHints.closingBraceHints.enable (default: `true`)::
-+
---
-Whether to show inlay hints after a closing `}` to indicate what item it belongs to.
---
-[[rust-analyzer.inlayHints.closingBraceHints.minLines]]rust-analyzer.inlayHints.closingBraceHints.minLines (default: `25`)::
-+
---
-Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1
-to always show them).
---
-[[rust-analyzer.inlayHints.closureCaptureHints.enable]]rust-analyzer.inlayHints.closureCaptureHints.enable (default: `false`)::
-+
---
-Whether to show inlay hints for closure captures.
---
-[[rust-analyzer.inlayHints.closureReturnTypeHints.enable]]rust-analyzer.inlayHints.closureReturnTypeHints.enable (default: `"never"`)::
-+
---
-Whether to show inlay type hints for return types of closures.
---
-[[rust-analyzer.inlayHints.closureStyle]]rust-analyzer.inlayHints.closureStyle (default: `"impl_fn"`)::
-+
---
-Closure notation in type and chaining inlay hints.
---
-[[rust-analyzer.inlayHints.discriminantHints.enable]]rust-analyzer.inlayHints.discriminantHints.enable (default: `"never"`)::
-+
---
-Whether to show enum variant discriminant hints.
---
-[[rust-analyzer.inlayHints.expressionAdjustmentHints.enable]]rust-analyzer.inlayHints.expressionAdjustmentHints.enable (default: `"never"`)::
-+
---
-Whether to show inlay hints for type adjustments.
---
-[[rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe]]rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe (default: `false`)::
-+
---
-Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
---
-[[rust-analyzer.inlayHints.expressionAdjustmentHints.mode]]rust-analyzer.inlayHints.expressionAdjustmentHints.mode (default: `"prefix"`)::
-+
---
-Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).
---
-[[rust-analyzer.inlayHints.genericParameterHints.const.enable]]rust-analyzer.inlayHints.genericParameterHints.const.enable (default: `true`)::
-+
---
-Whether to show const generic parameter name inlay hints.
---
-[[rust-analyzer.inlayHints.genericParameterHints.lifetime.enable]]rust-analyzer.inlayHints.genericParameterHints.lifetime.enable (default: `false`)::
-+
---
-Whether to show generic lifetime parameter name inlay hints.
---
-[[rust-analyzer.inlayHints.genericParameterHints.type.enable]]rust-analyzer.inlayHints.genericParameterHints.type.enable (default: `false`)::
-+
---
-Whether to show generic type parameter name inlay hints.
---
-[[rust-analyzer.inlayHints.implicitDrops.enable]]rust-analyzer.inlayHints.implicitDrops.enable (default: `false`)::
-+
---
-Whether to show implicit drop hints.
---
-[[rust-analyzer.inlayHints.implicitSizedBoundHints.enable]]rust-analyzer.inlayHints.implicitSizedBoundHints.enable (default: `false`)::
-+
---
-Whether to show inlay hints for the implied type parameter `Sized` bound.
---
-[[rust-analyzer.inlayHints.lifetimeElisionHints.enable]]rust-analyzer.inlayHints.lifetimeElisionHints.enable (default: `"never"`)::
-+
---
-Whether to show inlay type hints for elided lifetimes in function signatures.
---
-[[rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames]]rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames (default: `false`)::
-+
---
-Whether to prefer using parameter names as the name for elided lifetime hints if possible.
---
-[[rust-analyzer.inlayHints.maxLength]]rust-analyzer.inlayHints.maxLength (default: `25`)::
-+
---
-Maximum length for inlay hints. Set to null to have an unlimited length.
---
-[[rust-analyzer.inlayHints.parameterHints.enable]]rust-analyzer.inlayHints.parameterHints.enable (default: `true`)::
-+
---
-Whether to show function parameter name inlay hints at the call
-site.
---
-[[rust-analyzer.inlayHints.rangeExclusiveHints.enable]]rust-analyzer.inlayHints.rangeExclusiveHints.enable (default: `false`)::
-+
---
-Whether to show exclusive range inlay hints.
---
-[[rust-analyzer.inlayHints.reborrowHints.enable]]rust-analyzer.inlayHints.reborrowHints.enable (default: `"never"`)::
-+
---
-Whether to show inlay hints for compiler inserted reborrows.
-This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.
---
-[[rust-analyzer.inlayHints.renderColons]]rust-analyzer.inlayHints.renderColons (default: `true`)::
-+
---
-Whether to render leading colons for type hints, and trailing colons for parameter hints.
---
-[[rust-analyzer.inlayHints.typeHints.enable]]rust-analyzer.inlayHints.typeHints.enable (default: `true`)::
-+
---
-Whether to show inlay type hints for variables.
---
-[[rust-analyzer.inlayHints.typeHints.hideClosureInitialization]]rust-analyzer.inlayHints.typeHints.hideClosureInitialization (default: `false`)::
-+
---
-Whether to hide inlay type hints for `let` statements that initialize to a closure.
-Only applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`.
---
-[[rust-analyzer.inlayHints.typeHints.hideNamedConstructor]]rust-analyzer.inlayHints.typeHints.hideNamedConstructor (default: `false`)::
-+
---
-Whether to hide inlay type hints for constructors.
---
-[[rust-analyzer.interpret.tests]]rust-analyzer.interpret.tests (default: `false`)::
-+
---
-Enables the experimental support for interpreting tests.
---
-[[rust-analyzer.joinLines.joinAssignments]]rust-analyzer.joinLines.joinAssignments (default: `true`)::
-+
---
-Join lines merges consecutive declaration and initialization of an assignment.
---
-[[rust-analyzer.joinLines.joinElseIf]]rust-analyzer.joinLines.joinElseIf (default: `true`)::
-+
---
-Join lines inserts else between consecutive ifs.
---
-[[rust-analyzer.joinLines.removeTrailingComma]]rust-analyzer.joinLines.removeTrailingComma (default: `true`)::
-+
---
-Join lines removes trailing commas.
---
-[[rust-analyzer.joinLines.unwrapTrivialBlock]]rust-analyzer.joinLines.unwrapTrivialBlock (default: `true`)::
-+
---
-Join lines unwraps trivial blocks.
---
-[[rust-analyzer.lens.debug.enable]]rust-analyzer.lens.debug.enable (default: `true`)::
-+
---
-Whether to show `Debug` lens. Only applies when
-`#rust-analyzer.lens.enable#` is set.
---
-[[rust-analyzer.lens.enable]]rust-analyzer.lens.enable (default: `true`)::
-+
---
-Whether to show CodeLens in Rust files.
---
-[[rust-analyzer.lens.implementations.enable]]rust-analyzer.lens.implementations.enable (default: `true`)::
-+
---
-Whether to show `Implementations` lens. Only applies when
-`#rust-analyzer.lens.enable#` is set.
---
-[[rust-analyzer.lens.location]]rust-analyzer.lens.location (default: `"above_name"`)::
-+
---
-Where to render annotations.
---
-[[rust-analyzer.lens.references.adt.enable]]rust-analyzer.lens.references.adt.enable (default: `false`)::
-+
---
-Whether to show `References` lens for Struct, Enum, and Union.
-Only applies when `#rust-analyzer.lens.enable#` is set.
---
-[[rust-analyzer.lens.references.enumVariant.enable]]rust-analyzer.lens.references.enumVariant.enable (default: `false`)::
-+
---
-Whether to show `References` lens for Enum Variants.
-Only applies when `#rust-analyzer.lens.enable#` is set.
---
-[[rust-analyzer.lens.references.method.enable]]rust-analyzer.lens.references.method.enable (default: `false`)::
-+
---
-Whether to show `Method References` lens. Only applies when
-`#rust-analyzer.lens.enable#` is set.
---
-[[rust-analyzer.lens.references.trait.enable]]rust-analyzer.lens.references.trait.enable (default: `false`)::
-+
---
-Whether to show `References` lens for Trait.
-Only applies when `#rust-analyzer.lens.enable#` is set.
---
-[[rust-analyzer.lens.run.enable]]rust-analyzer.lens.run.enable (default: `true`)::
-+
---
-Whether to show `Run` lens. Only applies when
-`#rust-analyzer.lens.enable#` is set.
---
-[[rust-analyzer.lens.updateTest.enable]]rust-analyzer.lens.updateTest.enable (default: `true`)::
-+
---
-Whether to show `Update Test` lens. Only applies when
-`#rust-analyzer.lens.enable#` and `#rust-analyzer.lens.run.enable#` are set.
---
-[[rust-analyzer.linkedProjects]]rust-analyzer.linkedProjects (default: `[]`)::
-+
---
-Disable project auto-discovery in favor of explicitly specified set
-of projects.
-
-Elements must be paths pointing to `Cargo.toml`,
-`rust-project.json`, `.rs` files (which will be treated as standalone files) or JSON
-objects in `rust-project.json` format.
---
-[[rust-analyzer.lru.capacity]]rust-analyzer.lru.capacity (default: `null`)::
-+
---
-Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
---
-[[rust-analyzer.lru.query.capacities]]rust-analyzer.lru.query.capacities (default: `{}`)::
-+
---
-Sets the LRU capacity of the specified queries.
---
-[[rust-analyzer.notifications.cargoTomlNotFound]]rust-analyzer.notifications.cargoTomlNotFound (default: `true`)::
-+
---
-Whether to show `can't find Cargo.toml` error message.
---
-[[rust-analyzer.numThreads]]rust-analyzer.numThreads (default: `null`)::
-+
---
-How many worker threads in the main loop. The default `null` means to pick automatically.
---
-[[rust-analyzer.procMacro.attributes.enable]]rust-analyzer.procMacro.attributes.enable (default: `true`)::
-+
---
-Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.
---
-[[rust-analyzer.procMacro.enable]]rust-analyzer.procMacro.enable (default: `true`)::
-+
---
-Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`.
---
-[[rust-analyzer.procMacro.ignored]]rust-analyzer.procMacro.ignored (default: `{}`)::
-+
---
-These proc-macros will be ignored when trying to expand them.
-
-This config takes a map of crate names with the exported proc-macro names to ignore as values.
---
-[[rust-analyzer.procMacro.server]]rust-analyzer.procMacro.server (default: `null`)::
-+
---
-Internal config, path to proc-macro server executable.
---
-[[rust-analyzer.references.excludeImports]]rust-analyzer.references.excludeImports (default: `false`)::
-+
---
-Exclude imports from find-all-references.
---
-[[rust-analyzer.references.excludeTests]]rust-analyzer.references.excludeTests (default: `false`)::
-+
---
-Exclude tests from find-all-references and call-hierarchy.
---
-[[rust-analyzer.runnables.command]]rust-analyzer.runnables.command (default: `null`)::
-+
---
-Command to be executed instead of 'cargo' for runnables.
---
-[[rust-analyzer.runnables.extraArgs]]rust-analyzer.runnables.extraArgs (default: `[]`)::
-+
---
-Additional arguments to be passed to cargo for runnables such as
-tests or binaries. For example, it may be `--release`.
---
-[[rust-analyzer.runnables.extraTestBinaryArgs]]rust-analyzer.runnables.extraTestBinaryArgs::
-+
---
-Default:
-----
-[
-  "--show-output"
-]
-----
-Additional arguments to be passed through Cargo to launched tests, benchmarks, or
-doc-tests.
-
-Unless the launched target uses a
-[custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field),
-they will end up being interpreted as options to
-[`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
-
---
-[[rust-analyzer.rustc.source]]rust-analyzer.rustc.source (default: `null`)::
-+
---
-Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
-projects, or "discover" to try to automatically find it if the `rustc-dev` component
-is installed.
-
-Any project which uses rust-analyzer with the rustcPrivate
-crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it.
-
-This option does not take effect until rust-analyzer is restarted.
---
-[[rust-analyzer.rustfmt.extraArgs]]rust-analyzer.rustfmt.extraArgs (default: `[]`)::
-+
---
-Additional arguments to `rustfmt`.
---
-[[rust-analyzer.rustfmt.overrideCommand]]rust-analyzer.rustfmt.overrideCommand (default: `null`)::
-+
---
-Advanced option, fully override the command rust-analyzer uses for
-formatting. This should be the equivalent of `rustfmt` here, and
-not that of `cargo fmt`. The file contents will be passed on the
-standard input and the formatted result will be read from the
-standard output.
---
-[[rust-analyzer.rustfmt.rangeFormatting.enable]]rust-analyzer.rustfmt.rangeFormatting.enable (default: `false`)::
-+
---
-Enables the use of rustfmt's unstable range formatting command for the
-`textDocument/rangeFormatting` request. The rustfmt option is unstable and only
-available on a nightly build.
---
-[[rust-analyzer.semanticHighlighting.doc.comment.inject.enable]]rust-analyzer.semanticHighlighting.doc.comment.inject.enable (default: `true`)::
-+
---
-Inject additional highlighting into doc comments.
-
-When enabled, rust-analyzer will highlight rust source in doc comments as well as intra
-doc links.
---
-[[rust-analyzer.semanticHighlighting.nonStandardTokens]]rust-analyzer.semanticHighlighting.nonStandardTokens (default: `true`)::
-+
---
-Whether the server is allowed to emit non-standard tokens and modifiers.
---
-[[rust-analyzer.semanticHighlighting.operator.enable]]rust-analyzer.semanticHighlighting.operator.enable (default: `true`)::
-+
---
-Use semantic tokens for operators.
-
-When disabled, rust-analyzer will emit semantic tokens only for operator tokens when
-they are tagged with modifiers.
---
-[[rust-analyzer.semanticHighlighting.operator.specialization.enable]]rust-analyzer.semanticHighlighting.operator.specialization.enable (default: `false`)::
-+
---
-Use specialized semantic tokens for operators.
-
-When enabled, rust-analyzer will emit special token types for operator tokens instead
-of the generic `operator` token type.
---
-[[rust-analyzer.semanticHighlighting.punctuation.enable]]rust-analyzer.semanticHighlighting.punctuation.enable (default: `false`)::
-+
---
-Use semantic tokens for punctuation.
-
-When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when
-they are tagged with modifiers or have a special role.
---
-[[rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang]]rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang (default: `false`)::
-+
---
-When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro
-calls.
---
-[[rust-analyzer.semanticHighlighting.punctuation.specialization.enable]]rust-analyzer.semanticHighlighting.punctuation.specialization.enable (default: `false`)::
-+
---
-Use specialized semantic tokens for punctuation.
-
-When enabled, rust-analyzer will emit special token types for punctuation tokens instead
-of the generic `punctuation` token type.
---
-[[rust-analyzer.semanticHighlighting.strings.enable]]rust-analyzer.semanticHighlighting.strings.enable (default: `true`)::
-+
---
-Use semantic tokens for strings.
-
-In some editors (e.g. vscode) semantic tokens override other highlighting grammars.
-By disabling semantic tokens for strings, other grammars can be used to highlight
-their contents.
---
-[[rust-analyzer.signatureInfo.detail]]rust-analyzer.signatureInfo.detail (default: `"full"`)::
-+
---
-Show full signature of the callable. Only shows parameters if disabled.
---
-[[rust-analyzer.signatureInfo.documentation.enable]]rust-analyzer.signatureInfo.documentation.enable (default: `true`)::
-+
---
-Show documentation.
---
-[[rust-analyzer.typing.triggerChars]]rust-analyzer.typing.triggerChars (default: `"=."`)::
-+
---
-Specify the characters allowed to invoke special on typing triggers.
-- typing `=` after `let` tries to smartly add `;` if `=` is followed by an existing expression
-- typing `=` between two expressions adds `;` when in statement position
-- typing `=` to turn an assignment into an equality comparison removes `;` when in expression position
-- typing `.` in a chain method call auto-indents
-- typing `{` or `(` in front of an expression inserts a closing `}` or `)` after the expression
-- typing `{` in a use item adds a closing `}` in the right place
-- typing `>` to complete a return type `->` will insert a whitespace after it
-- typing `<` in a path or type position inserts a closing `>` after the path or type.
---
-[[rust-analyzer.vfs.extraIncludes]]rust-analyzer.vfs.extraIncludes (default: `[]`)::
-+
---
-Additional paths to include in the VFS. Generally for code that is
-generated or otherwise managed by a build system outside of Cargo,
-though Cargo might be the eventual consumer.
---
-[[rust-analyzer.workspace.discoverConfig]]rust-analyzer.workspace.discoverConfig (default: `null`)::
-+
---
-Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].
-
-[`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`.
-`progress_label` is used for the title in progress indicators, whereas `files_to_watch`
-is used to determine which build system-specific files should be watched in order to
-reload rust-analyzer.
-
-Below is an example of a valid configuration:
-```json
-"rust-analyzer.workspace.discoverConfig": {
-    "command": [
-        "rust-project",
-        "develop-json"
-    ],
-    "progressLabel": "rust-analyzer",
-    "filesToWatch": [
-        "BUCK"
-    ]
-}
-```
-
-## On `DiscoverWorkspaceConfig::command`
-
-**Warning**: This format is provisional and subject to change.
-
-[`DiscoverWorkspaceConfig::command`] *must* return a JSON object
-corresponding to `DiscoverProjectData::Finished`:
-
-```norun
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(tag = "kind")]
-#[serde(rename_all = "snake_case")]
-enum DiscoverProjectData {
-    Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },
-    Error { error: String, source: Option<String> },
-    Progress { message: String },
-}
-```
-
-As JSON, `DiscoverProjectData::Finished` is:
-
-```json
-{
-    // the internally-tagged representation of the enum.
-    "kind": "finished",
-    // the file used by a non-Cargo build system to define
-    // a package or target.
-    "buildfile": "rust-analyzer/BUILD",
-    // the contents of a rust-project.json, elided for brevity
-    "project": {
-        "sysroot": "foo",
-        "crates": []
-    }
-}
-```
-
-It is encouraged, but not required, to use the other variants on
-`DiscoverProjectData` to provide a more polished end-user experience.
-
-`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`,
-which will be substituted with the JSON-serialized form of the following
-enum:
-
-```norun
-#[derive(PartialEq, Clone, Debug, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub enum DiscoverArgument {
-   Path(AbsPathBuf),
-   Buildfile(AbsPathBuf),
-}
-```
-
-The JSON representation of `DiscoverArgument::Path` is:
-
-```json
-{
-    "path": "src/main.rs"
-}
-```
-
-Similarly, the JSON representation of `DiscoverArgument::Buildfile` is:
-
-```
-{
-    "buildfile": "BUILD"
-}
-```
-
-`DiscoverArgument::Path` is used to find and generate a `rust-project.json`,
-and therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to
-to update an existing workspace. As a reference for implementors,
-buck2's `rust-project` will likely be useful:
-https://github.com/facebook/buck2/tree/main/integrations/rust-project.
---
-[[rust-analyzer.workspace.symbol.search.kind]]rust-analyzer.workspace.symbol.search.kind (default: `"only_types"`)::
-+
---
-Workspace symbol search kind.
---
-[[rust-analyzer.workspace.symbol.search.limit]]rust-analyzer.workspace.symbol.search.limit (default: `128`)::
-+
---
-Limits the number of items returned from a workspace symbol search (Defaults to 128).
-Some clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search.
-Other clients requires all results upfront and might require a higher limit.
---
-[[rust-analyzer.workspace.symbol.search.scope]]rust-analyzer.workspace.symbol.search.scope (default: `"workspace"`)::
-+
---
-Workspace symbol search scope.
---
diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc
deleted file mode 100644
index 4a2a6f2e368..00000000000
--- a/src/tools/rust-analyzer/docs/user/manual.adoc
+++ /dev/null
@@ -1,1121 +0,0 @@
-= User Manual
-:toc: preamble
-:sectanchors:
-:page-layout: post
-:icons: font
-:source-highlighter: rouge
-:experimental:
-
-////
-IMPORTANT: the master copy of this document lives in the https://github.com/rust-lang/rust-analyzer repository
-////
-
-At its core, rust-analyzer is a *library* for semantic analysis of Rust code as it changes over time.
-This manual focuses on a specific usage of the library -- running it as part of a server that implements the
-https://microsoft.github.io/language-server-protocol/[Language Server Protocol] (LSP).
-The LSP allows various code editors, like VS Code, Emacs or Vim, to implement semantic features like completion or goto definition by talking to an external language server process.
-
-[TIP]
-====
-[.lead]
-To improve this document, send a pull request: +
-https://github.com/rust-lang/rust-analyzer/blob/master/docs/user/manual.adoc[https://github.com/rust-analyzer/.../manual.adoc]
-
-The manual is written in https://asciidoc.org[AsciiDoc] and includes some extra files which are generated from the source code. Run `cargo test` and `cargo xtask codegen` to create these and then `asciidoctor manual.adoc` to create an HTML copy.
-====
-
-If you have questions about using rust-analyzer, please ask them in the https://users.rust-lang.org/c/ide/14["`IDEs and Editors`"] topic of Rust users forum.
-
-== Installation
-
-In theory, one should be able to just install the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>> and have it automatically work with any editor.
-We are not there yet, so some editor specific setup is required.
-
-Additionally, rust-analyzer needs the sources of the standard library.
-If the source code is not present, rust-analyzer will attempt to install it automatically.
-
-To add the sources manually, run the following command:
-
-```bash
-$ rustup component add rust-src
-```
-
-=== Toolchain
-
-Only the latest stable standard library source is officially supported for use with rust-analyzer.
-If you are using an older toolchain or have an override set, rust-analyzer may fail to understand the Rust source.
-You will either need to update your toolchain or use an older version of rust-analyzer that is compatible with your toolchain.
-
-If you are using an override in your project, you can still force rust-analyzer to use the stable toolchain via the environment variable `RUSTUP_TOOLCHAIN`.
-For example, with VS Code or coc-rust-analyzer:
-
-[source,json]
-----
-{ "rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "stable" } }
-----
-
-=== VS Code
-
-This is the best supported editor at the moment.
-The rust-analyzer plugin for VS Code is maintained
-https://github.com/rust-lang/rust-analyzer/tree/master/editors/code[in tree].
-
-You can install the latest release of the plugin from
-https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer[the marketplace].
-
-Note that the plugin may cause conflicts with the
-https://marketplace.visualstudio.com/items?itemName=rust-lang.rust[previous official Rust plugin].
-The latter is no longer maintained and should be uninstalled.
-
-The server binary is stored in the extension install directory, which starts with `rust-lang.rust-analyzer-` and is located under:
-
-* Linux: `~/.vscode/extensions`
-* Linux (Remote, such as WSL): `~/.vscode-server/extensions`
-* macOS: `~/.vscode/extensions`
-* Windows: `%USERPROFILE%\.vscode\extensions`
-
-As an exception, on NixOS, the extension makes a copy of the server and stores it under `~/.config/Code/User/globalStorage/rust-lang.rust-analyzer`.
-
-Note that we only support the two most recent versions of VS Code.
-
-==== Updates
-
-The extension will be updated automatically as new versions become available.
-It will ask your permission to download the matching language server version binary if needed.
-
-===== Nightly
-
-We ship nightly releases for VS Code.
-To help us out by testing the newest code, you can enable pre-release versions in the Code extension page.
-
-==== Manual installation
-
-Alternatively, download a VSIX corresponding to your platform from the
-https://github.com/rust-lang/rust-analyzer/releases[releases] page.
-
-Install the extension with the `Extensions: Install from VSIX` command within VS Code, or from the command line via:
-[source]
-----
-$ code --install-extension /path/to/rust-analyzer.vsix
-----
-
-If you are running an unsupported platform, you can install `rust-analyzer-no-server.vsix` and compile or obtain a server binary.
-Copy the server anywhere, then add the path to your settings.json, for example:
-[source,json]
-----
-{ "rust-analyzer.server.path": "~/.local/bin/rust-analyzer-linux" }
-----
-
-==== Building From Source
-
-Both the server and the Code plugin can be installed from source:
-
-[source]
-----
-$ git clone https://github.com/rust-lang/rust-analyzer.git && cd rust-analyzer
-$ cargo xtask install
-----
-
-You'll need Cargo, nodejs (matching a supported version of VS Code) and npm for this.
-
-Note that installing via `xtask install` does not work for VS Code Remote, instead you'll need to install the `.vsix` manually.
-
-If you're not using Code, you can compile and install only the LSP server:
-
-[source]
-----
-$ cargo xtask install --server
-----
-
-Make sure that `.cargo/bin` is in `$PATH` and precedes paths where `rust-analyzer` may also be installed.
-Specifically, `rustup` includes a proxy called `rust-analyzer`, which can cause problems if you're planning to use a source build or even a downloaded binary.
-
-=== rust-analyzer Language Server Binary
-
-Other editors generally require the `rust-analyzer` binary to be in `$PATH`.
-You can download pre-built binaries from the https://github.com/rust-lang/rust-analyzer/releases[releases] page.
-You will need to uncompress and rename the binary for your platform, e.g. from `rust-analyzer-aarch64-apple-darwin.gz` on Mac OS to `rust-analyzer`, make it executable, then move it into a directory in your `$PATH`.
-
-On Linux to install the `rust-analyzer` binary into `~/.local/bin`, these commands should work:
-
-[source,bash]
-----
-$ mkdir -p ~/.local/bin
-$ curl -L https://github.com/rust-lang/rust-analyzer/releases/latest/download/rust-analyzer-x86_64-unknown-linux-gnu.gz | gunzip -c - > ~/.local/bin/rust-analyzer
-$ chmod +x ~/.local/bin/rust-analyzer
-----
-
-Make sure that `~/.local/bin` is listed in the `$PATH` variable and use the appropriate URL if you're not on a `x86-64` system.
-
-You don't have to use `~/.local/bin`, any other path like `~/.cargo/bin` or `/usr/local/bin` will work just as well.
-
-Alternatively, you can install it from source using the command below.
-You'll need the latest stable version of the Rust toolchain.
-
-[source,bash]
-----
-$ git clone https://github.com/rust-lang/rust-analyzer.git && cd rust-analyzer
-$ cargo xtask install --server
-----
-
-If your editor can't find the binary even though the binary is on your `$PATH`, the likely explanation is that it doesn't see the same `$PATH` as the shell, see https://github.com/rust-lang/rust-analyzer/issues/1811[this issue].
-On Unix, running the editor from a shell or changing the `.desktop` file to set the environment should help.
-
-==== rustup
-
-`rust-analyzer` is available in `rustup`:
-
-[source,bash]
-----
-$ rustup component add rust-analyzer
-----
-
-==== Arch Linux
-
-The `rust-analyzer` binary can be installed from the repos or AUR (Arch User Repository):
-
-- https://www.archlinux.org/packages/extra/x86_64/rust-analyzer/[`rust-analyzer`] (built from latest tagged source)
-- https://aur.archlinux.org/packages/rust-analyzer-git[`rust-analyzer-git`] (latest Git version)
-
-Install it with pacman, for example:
-
-[source,bash]
-----
-$ pacman -S rust-analyzer
-----
-
-==== Gentoo Linux
-
-There are two ways to install `rust-analyzer` under Gentoo:
-
-- when installing `dev-lang/rust` or `dev-lang/rust-bin`, enable the `rust-analyzer` and `rust-src` USE flags
-- use the `rust-analyzer` component in `rustup` (see instructions above)
-
-Note that in both cases, the version installed lags for a couple of months behind the official releases on GitHub.
-To obtain a newer one, you can download a binary from GitHub Releases or building from source.
-
-==== macOS
-
-The `rust-analyzer` binary can be installed via https://brew.sh/[Homebrew].
-
-[source,bash]
-----
-$ brew install rust-analyzer
-----
-
-==== Windows
-
-It is recommended to install the latest Microsoft Visual C++ Redistributable prior to installation.
-Download links can be found
-https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist[here].
-
-=== VS Code or VSCodium in Flatpak
-
-Setting up `rust-analyzer` with a Flatpak version of Code is not trivial because of the Flatpak sandbox.
-While the sandbox can be disabled for some directories, `/usr/bin` will always be mounted under `/run/host/usr/bin`.
-This prevents access to the system's C compiler, a system-wide installation of Rust, or any other libraries you might want to link to.
-Some compilers and libraries can be acquired as Flatpak SDKs, such as `org.freedesktop.Sdk.Extension.rust-stable` or `org.freedesktop.Sdk.Extension.llvm15`.
-
-If you use a Flatpak SDK for Rust, it must be in your `PATH`:
-
- * install the SDK extensions with `flatpak install org.freedesktop.Sdk.Extension.{llvm15,rust-stable}//23.08`
- * enable SDK extensions in the editor with the environment variable `FLATPAK_ENABLE_SDK_EXT=llvm15,rust-stable` (this can be done using flatseal or `flatpak override`)
-
-If you want to use Flatpak in combination with `rustup`, the following steps might help:
-
- - both Rust and `rustup` have to be installed using https://rustup.rs. Distro packages _will not_ work.
- - you need to launch Code, open a terminal and run `echo $PATH`
- - using https://flathub.org/apps/details/com.github.tchx84.Flatseal[Flatseal], you must add an environment variable called `PATH`.
-   Set its value to the output from above, appending `:~/.cargo/bin`, where `~` is the path to your home directory.
-   You must replace `~`, as it won't be expanded otherwise.
- - while Flatseal is open, you must enable access to "All user files"
-
-A C compiler should already be available via `org.freedesktop.Sdk`.
-Any other tools or libraries you will need to acquire  from Flatpak.
-
-=== Emacs
-
-Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
-
-To use `rust-analyzer`, you need to install and enable one of the two popular LSP client implementations for Emacs, https://github.com/joaotavora/eglot[Eglot] or https://github.com/emacs-lsp/lsp-mode[LSP Mode]. Both enable `rust-analyzer` by default in rust buffers if it is available.
-
-==== Eglot
-
-Eglot is the more minimalistic and lightweight LSP client for Emacs, integrates well with existing Emacs functionality and is built into Emacs starting from release 29.
-
-After installing Eglot, e.g. via `M-x package-install` (not needed from Emacs 29), you can enable it via the `M-x eglot` command or load it automatically in `rust-mode` via
-
-[source,emacs-lisp]
-----
-(add-hook 'rust-mode-hook 'eglot-ensure)
-----
-
-To enable clippy, you will need to configure the initialization options to pass the `check.command` setting.
-
-[source,emacs-lisp]
-----
-(add-to-list 'eglot-server-programs
-             '((rust-ts-mode rust-mode) .
-               ("rust-analyzer" :initializationOptions (:check (:command "clippy")))))
-----
-
-For more detailed instructions and options see the https://joaotavora.github.io/eglot[Eglot manual] (also available from Emacs via `M-x info`) and the
-https://github.com/joaotavora/eglot/blob/master/README.md[Eglot readme].
-
-Eglot does not support the rust-analyzer extensions to the language-server protocol and does not aim to do so in the future. The https://github.com/nemethf/eglot-x#rust-analyzer-extensions[eglot-x] package adds experimental support for those LSP extensions.
-
-==== LSP Mode
-
-LSP-mode is the original LSP-client for emacs. Compared to Eglot it has a larger codebase and supports more features, like LSP protocol extensions.
-With extension packages like https://github.com/emacs-lsp/lsp-mode[LSP UI] it offers a lot of visual eyecandy.
-Further it integrates well with https://github.com/emacs-lsp/dap-mode[DAP mode] for support of the Debug Adapter Protocol.
-
-You can install LSP-mode via `M-x package-install` and then run it via the `M-x lsp` command or load it automatically in rust buffers with
-
-[source,emacs-lisp]
-----
-(add-hook 'rust-mode-hook 'lsp-deferred)
-----
-
-For more information on how to set up LSP mode and its extension package see the instructions in the https://emacs-lsp.github.io/lsp-mode/page/installation[LSP mode manual].
-Also see the https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/[rust-analyzer section] for `rust-analyzer` specific options and commands, which you can optionally bind to keys.
-
-Note the excellent https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/[guide] from https://github.com/rksm[@rksm] on how to set-up Emacs for Rust development with LSP mode and several other packages.
-
-=== Vim/Neovim
-
-Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
-Not needed if the extension can install/update it on its own, coc-rust-analyzer is one example.
-
-There are several LSP client implementations for Vim or Neovim:
-
-==== coc-rust-analyzer
-
-1. Install coc.nvim by following the instructions at
-   https://github.com/neoclide/coc.nvim[coc.nvim]
-   (Node.js required)
-2. Run `:CocInstall coc-rust-analyzer` to install
-   https://github.com/fannheyward/coc-rust-analyzer[coc-rust-analyzer],
-   this extension implements _most_ of the features supported in the VSCode extension:
-   * automatically install and upgrade stable/nightly releases
-   * same configurations as VSCode extension, `rust-analyzer.server.path`, `rust-analyzer.cargo.features` etc.
-   * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.ssr` etc.
-   * inlay hints for variables and method chaining, _Neovim Only_
-
-Note: for code actions, use `coc-codeaction-cursor` and `coc-codeaction-selected`; `coc-codeaction` and `coc-codeaction-line` are unlikely to be useful.
-
-==== LanguageClient-neovim
-
-1. Install LanguageClient-neovim by following the instructions
-   https://github.com/autozimu/LanguageClient-neovim[here]
-   * The GitHub project wiki has extra tips on configuration
-
-2. Configure by adding this to your Vim/Neovim config file (replacing the existing Rust-specific line if it exists):
-+
-[source,vim]
-----
-let g:LanguageClient_serverCommands = {
-\ 'rust': ['rust-analyzer'],
-\ }
-----
-
-==== YouCompleteMe
-
-Install YouCompleteMe by following the instructions
-  https://github.com/ycm-core/YouCompleteMe#installation[here].
-
-rust-analyzer is the default in ycm, it should work out of the box.
-
-==== ALE
-
-To use the LSP server in https://github.com/dense-analysis/ale[ale]:
-
-[source,vim]
-----
-let g:ale_linters = {'rust': ['analyzer']}
-----
-
-==== nvim-lsp
-
-Neovim 0.5 has built-in language server support.
-For a quick start configuration of rust-analyzer, use https://github.com/neovim/nvim-lspconfig#rust_analyzer[neovim/nvim-lspconfig].
-Once `neovim/nvim-lspconfig` is installed, use `+lua require'lspconfig'.rust_analyzer.setup({})+` in your `init.vim`.
-
-You can also pass LSP settings to the server:
-
-[source,vim]
-----
-lua << EOF
-local lspconfig = require'lspconfig'
-
-local on_attach = function(client)
-    require'completion'.on_attach(client)
-end
-
-lspconfig.rust_analyzer.setup({
-    on_attach = on_attach,
-    settings = {
-        ["rust-analyzer"] = {
-            imports = {
-                granularity = {
-                    group = "module",
-                },
-                prefix = "self",
-            },
-            cargo = {
-                buildScripts = {
-                    enable = true,
-                },
-            },
-            procMacro = {
-                enable = true
-            },
-        }
-    }
-})
-EOF
-----
-
-If you're running Neovim 0.10 or later, you can enable inlay hints via `on_attach`:
-
-[source,vim]
-----
-lspconfig.rust_analyzer.setup({
-    on_attach = function(client, bufnr)
-        vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
-    end
-})
-----
-
-Note that the hints are only visible after `rust-analyzer` has finished loading **and** you have to edit the file to trigger a re-render.
-
-See https://sharksforarms.dev/posts/neovim-rust/ for more tips on getting started.
-
-Check out https://github.com/mrcjkb/rustaceanvim for a batteries included rust-analyzer setup for Neovim.
-
-==== vim-lsp
-
-vim-lsp is installed by following https://github.com/prabirshrestha/vim-lsp[the plugin instructions].
-It can be as simple as adding this line to your `.vimrc`:
-
-[source,vim]
-----
-Plug 'prabirshrestha/vim-lsp'
-----
-
-Next you need to register the `rust-analyzer` binary.
-If it is available in `$PATH`, you may want to add this to your `.vimrc`:
-
-[source,vim]
-----
-if executable('rust-analyzer')
-  au User lsp_setup call lsp#register_server({
-        \   'name': 'Rust Language Server',
-        \   'cmd': {server_info->['rust-analyzer']},
-        \   'whitelist': ['rust'],
-        \ })
-endif
-----
-
-There is no dedicated UI for the server configuration, so you would need to send any options as a value of the `initialization_options` field, as described in the <<configuration,Configuration>> section.
-Here is an example of how to enable the proc-macro support:
-
-[source,vim]
-----
-if executable('rust-analyzer')
-  au User lsp_setup call lsp#register_server({
-        \   'name': 'Rust Language Server',
-        \   'cmd': {server_info->['rust-analyzer']},
-        \   'whitelist': ['rust'],
-        \   'initialization_options': {
-        \     'cargo': {
-        \       'buildScripts': {
-        \         'enable': v:true,
-        \       },
-        \     },
-        \     'procMacro': {
-        \       'enable': v:true,
-        \     },
-        \   },
-        \ })
-endif
-----
-
-=== Sublime Text
-
-==== Sublime Text 4:
-* Follow the instructions in link:https://github.com/sublimelsp/LSP-rust-analyzer[LSP-rust-analyzer].
-
-NOTE: Install link:https://packagecontrol.io/packages/LSP-file-watcher-chokidar[LSP-file-watcher-chokidar] to enable file watching (`workspace/didChangeWatchedFiles`).
-
-==== Sublime Text 3:
-* Install the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
-* Install the link:https://packagecontrol.io/packages/LSP[LSP package].
-* From the command palette, run `LSP: Enable Language Server Globally` and select `rust-analyzer`.
-
-If it worked, you should see "rust-analyzer, Line X, Column Y" on the left side of the status bar, and after waiting a bit, functionalities like tooltips on hovering over variables should become available.
-
-If you get an error saying `No such file or directory: 'rust-analyzer'`, see the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>> section on installing the language server binary.
-
-=== GNOME Builder
-
-GNOME Builder 3.37.1 and newer has native `rust-analyzer` support.
-If the LSP binary is not available, GNOME Builder can install it when opening a Rust file.
-
-
-=== Eclipse IDE
-
-Support for Rust development in the Eclipse IDE is provided by link:https://github.com/eclipse/corrosion[Eclipse Corrosion].
-If available in PATH or in some standard location, `rust-analyzer` is detected and powers editing of Rust files without further configuration.
-If `rust-analyzer` is not detected, Corrosion will prompt you for configuration of your Rust toolchain and language server with a link to the __Window > Preferences > Rust__ preference page; from here a button allows to download and configure `rust-analyzer`, but you can also reference another installation.
-You'll need to close and reopen all .rs and Cargo files, or to restart the IDE, for this change to take effect.
-
-=== Kate Text Editor
-
-Support for the language server protocol is built into Kate through the LSP plugin, which is included by default.
-It is preconfigured to use rust-analyzer for Rust sources since Kate 21.12.
-
-To change rust-analyzer config options, start from the following example and put it into Kate's "User Server Settings" tab (located under the LSP Client settings):
-[source,json]
-----
-{
-    "servers": {
-        "rust": {
-            "initializationOptions": {
-                "cachePriming": {
-                    "enable": false
-                },
-                "check": {
-                    "allTargets": false
-                },
-                "checkOnSave": false
-            }
-        }
-    }
-}
-----
-Then click on apply, and restart the LSP server for your rust project.
-
-=== juCi++
-
-https://gitlab.com/cppit/jucipp[juCi++] has built-in support for the language server protocol, and since version 1.7.0 offers installation of both Rust and rust-analyzer when opening a Rust file.
-
-=== Kakoune
-
-https://kakoune.org/[Kakoune] supports LSP with the help of https://github.com/kak-lsp/kak-lsp[`kak-lsp`].
-Follow the https://github.com/kak-lsp/kak-lsp#installation[instructions] to install `kak-lsp`.
-To configure `kak-lsp`, refer to the https://github.com/kak-lsp/kak-lsp#configuring-kak-lsp[configuration section] which is basically about copying the https://github.com/kak-lsp/kak-lsp/blob/master/kak-lsp.toml[configuration file] in the right place (latest versions should use `rust-analyzer` by default).
-
-Finally, you need to configure Kakoune to talk to `kak-lsp` (see https://github.com/kak-lsp/kak-lsp#usage[Usage section]).
-A basic configuration will only get you LSP but you can also activate inlay diagnostics and auto-formatting on save.
-The following might help you get all of this.
-
-[source,txt]
-----
-eval %sh{kak-lsp --kakoune -s $kak_session}  # Not needed if you load it with plug.kak.
-hook global WinSetOption filetype=rust %{
-    # Enable LSP
-    lsp-enable-window
-
-    # Auto-formatting on save
-    hook window BufWritePre .* lsp-formatting-sync
-
-    # Configure inlay hints (only on save)
-    hook window -group rust-inlay-hints BufWritePost .* rust-analyzer-inlay-hints
-    hook -once -always window WinSetOption filetype=.* %{
-        remove-hooks window rust-inlay-hints
-    }
-}
-----
-
-=== Helix
-
-https://docs.helix-editor.com/[Helix] supports LSP by default.
-However, it won't install `rust-analyzer` automatically.
-You can follow instructions for installing <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
-
-[#visual-studio]
-=== [[visual-studio-2022]]Visual Studio 2022
-
-There are multiple rust-analyzer extensions for Visual Studio 2022 on Windows:
-
-==== rust-analyzer.vs
-
-(License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International)
-
-https://marketplace.visualstudio.com/items?itemName=kitamstudios.RustAnalyzer[Visual Studio Marketplace]
-
-https://github.com/kitamstudios/rust-analyzer/[GitHub]
-
-Support for Rust development in the Visual Studio IDE is enabled by the link:https://marketplace.visualstudio.com/items?itemName=kitamstudios.RustAnalyzer[rust-analyzer] package. Either click on the download link or install from IDE's extension manager.
-For now link:https://visualstudio.microsoft.com/downloads/[Visual Studio 2022] is required. All editions are supported viz. Community, Professional & Enterprise.
-The package aims to provide 0-friction installation and therefore comes loaded with most things required including rust-analyzer binary. If anything it needs is missing, appropriate errors / warnings will guide the user. E.g. cargo.exe needs to be in path and the package will tell you as much.
-This package is under rapid active development. So if you encounter any issues please file it at link:https://github.com/kitamstudios/rust-analyzer/[rust-analyzer.vs].
-
-==== VS_RustAnalyzer
-
-(License: GPL)
-
-https://marketplace.visualstudio.com/items?itemName=cchharris.vsrustanalyzer[Visual Studio Marketplace]
-
-https://github.com/cchharris/VS-RustAnalyzer[GitHub]
-
-==== SourceGear Rust
-
-(License: closed source)
-
-https://marketplace.visualstudio.com/items?itemName=SourceGear.SourceGearRust[Visual Studio Marketplace]
-
-https://github.com/sourcegear/rust-vs-extension[GitHub (docs, issues, discussions)]
-
-* Free (no-cost)
-* Supports all editions of Visual Studio 2022 on Windows: Community, Professional, or Enterprise
-
-=== Lapce
-
-https://lapce.dev/[Lapce] has a Rust plugin which you can install directly.
-Unfortunately, it downloads an old version of `rust-analyzer`, but you can set the server path under Settings.
-
-=== Crates
-
-There is a package named `ra_ap_rust_analyzer` available on https://crates.io/crates/ra_ap_rust-analyzer[crates.io], for someone who wants to use it programmatically.
-
-For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/autopublish.yaml[the publish workflow].
-
-=== Zed
-
-https://zed.dev[Zed] has native `rust-analyzer` support.
-If the LSP binary is not available, Zed can install it when opening a Rust file.
-
-== Troubleshooting
-
-Start with looking at the rust-analyzer version.
-Try **rust-analyzer: Show RA Version** in VS Code (using **Command Palette** feature typically activated by Ctrl+Shift+P) or `rust-analyzer --version` in the command line.
-If the date is more than a week ago, it's better to update rust-analyzer version.
-
-The next thing to check would be panic messages in rust-analyzer's log.
-Log messages are printed to stderr, in VS Code you can see them in the `Output > Rust Analyzer Language Server` tab of the panel.
-To see more logs, set the `RA_LOG=info` environment variable, this can be done either by setting the environment variable manually or by using `rust-analyzer.server.extraEnv`, note that both of these approaches require the server to be restarted.
-
-To fully capture LSP messages between the editor and the server, run the `rust-analyzer: Toggle LSP Logs` command and check
-`Output > Rust Analyzer Language Server Trace`.
-
-The root cause for many "`nothing works`" problems is that rust-analyzer fails to understand the project structure.
-To debug that, first note the `rust-analyzer` section in the status bar.
-If it has an error icon and red, that's the problem (hover will have somewhat helpful error message).
-**rust-analyzer: Status** prints dependency information for the current file.
-Finally, `RA_LOG=project_model=debug` enables verbose logs during project loading.
-
-If rust-analyzer outright crashes, try running `rust-analyzer analysis-stats /path/to/project/directory/` on the command line.
-This command type checks the whole project in batch mode bypassing LSP machinery.
-
-When filing issues, it is useful (but not necessary) to try to minimize examples.
-An ideal bug reproduction looks like this:
-
-```bash
-$ git clone https://github.com/username/repo.git && cd repo && git switch --detach commit-hash
-$ rust-analyzer --version
-rust-analyzer dd12184e4 2021-05-08 dev
-$ rust-analyzer analysis-stats .
-💀 💀 💀
-```
-
-It is especially useful when the `repo` doesn't use external crates or the standard library.
-
-If you want to go as far as to modify the source code to debug the problem, be sure to take a look at the
-https://github.com/rust-lang/rust-analyzer/tree/master/docs/dev[dev docs]!
-
-== Configuration
-
-**Source:** https://github.com/rust-lang/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs[config.rs]
-
-The <<installation,Installation>> section contains details on configuration for some of the editors.
-In general `rust-analyzer` is configured via LSP messages, which means that it's up to the editor to decide on the exact format and location of configuration files.
-
-Some clients, such as <<vs-code,VS Code>> or <<coc-rust-analyzer,COC plugin in Vim>> provide `rust-analyzer` specific configuration UIs. Others may require you to know a bit more about the interaction with `rust-analyzer`.
-
-For the later category, it might help to know that the initial configuration is specified as a value of the `initializationOptions` field of the https://microsoft.github.io/language-server-protocol/specifications/specification-current/#initialize[`InitializeParams` message, in the LSP protocol].
-The spec says that the field type is `any?`, but `rust-analyzer` is looking for a JSON object that is constructed using settings from the list below.
-Name of the setting, ignoring the `rust-analyzer.` prefix, is used as a path, and value of the setting becomes the JSON property value.
-
-For example, a very common configuration is to enable proc-macro support, can be achieved by sending this JSON:
-
-[source,json]
-----
-{
-  "cargo": {
-    "buildScripts": {
-      "enable": true,
-    },
-  },
-  "procMacro": {
-    "enable": true,
-  }
-}
-----
-
-Please consult your editor's documentation to learn more about how to configure https://microsoft.github.io/language-server-protocol/[LSP servers].
-
-To verify which configuration is actually used by `rust-analyzer`, set `RA_LOG` environment variable to `rust_analyzer=info` and look for config-related messages.
-Logs should show both the JSON that `rust-analyzer` sees as well as the updated config.
-
-This is the list of config options `rust-analyzer` supports:
-
-include::./generated_config.adoc[]
-
-== Non-Cargo Based Projects
-
-rust-analyzer does not require Cargo.
-However, if you use some other build system, you'll have to describe the structure of your project for rust-analyzer in the `rust-project.json` format:
-
-[source,TypeScript]
-----
-interface JsonProject {
-    /// Path to the sysroot directory.
-    ///
-    /// The sysroot is where rustc looks for the
-    /// crates that are built-in to rust, such as
-    /// std.
-    ///
-    /// https://doc.rust-lang.org/rustc/command-line-arguments.html#--sysroot-override-the-system-root
-    ///
-    /// To see the current value of sysroot, you
-    /// can query rustc:
-    ///
-    /// ```
-    /// $ rustc --print sysroot
-    /// /Users/yourname/.rustup/toolchains/stable-x86_64-apple-darwin
-    /// ```
-    sysroot?: string;
-    /// Path to the directory with *source code* of
-    /// sysroot crates.
-    ///
-    /// By default, this is `lib/rustlib/src/rust/library`
-    /// relative to the sysroot.
-    ///
-    /// It should point to the directory where std,
-    /// core, and friends can be found:
-    ///
-    /// https://github.com/rust-lang/rust/tree/master/library.
-    ///
-    /// If provided, rust-analyzer automatically adds
-    /// dependencies on sysroot crates. Conversely,
-    /// if you omit this path, you can specify sysroot
-    /// dependencies yourself and, for example, have
-    /// several different "sysroots" in one graph of
-    /// crates.
-    sysroot_src?: string;
-    /// List of groups of common cfg values, to allow
-    /// sharing them between crates.
-    ///
-    /// Maps from group name to its cfgs. Cfg follow
-    /// the same format as `Crate.cfg`.
-    cfg_groups?: { [key: string]: string[]; };
-    /// The set of crates comprising the current
-    /// project. Must include all transitive
-    /// dependencies as well as sysroot crate (libstd,
-    /// libcore and such).
-    crates: Crate[];
-    /// Configuration for CLI commands.
-    ///
-    /// These are used for running and debugging binaries
-    /// and tests without encoding build system-specific
-    /// knowledge into rust-analyzer.
-    ///
-    /// # Example
-    ///
-    /// Below is an example of a test runnable. `{label}` and `{test_id}`
-    /// are explained in `Runnable::args`'s documentation below.
-    ///
-    /// ```json
-    /// {
-    ///     "program": "buck",
-    ///     "args": [
-    ///         "test",
-    ///          "{label}",
-    ///          "--",
-    ///          "{test_id}",
-    ///          "--print-passing-details"
-    ///     ],
-    ///     "cwd": "/home/user/repo-root/",
-    ///     "kind": "testOne"
-    /// }
-    /// ```
-    runnables?: Runnable[];
-}
-
-interface Crate {
-    /// Optional crate name used for display purposes,
-    /// without affecting semantics. See the `deps`
-    /// key for semantically-significant crate names.
-    display_name?: string;
-    /// Path to the root module of the crate.
-    root_module: string;
-    /// Edition of the crate.
-    edition: '2015' | '2018' | '2021' | '2024';
-    /// The version of the crate. Used for calculating
-    /// the correct docs.rs URL.
-    version?: string;
-    /// Dependencies
-    deps: Dep[];
-    /// Should this crate be treated as a member of
-    /// current "workspace".
-    ///
-    /// By default, inferred from the `root_module`
-    /// (members are the crates which reside inside
-    /// the directory opened in the editor).
-    ///
-    /// Set this to `false` for things like standard
-    /// library and 3rd party crates to enable
-    /// performance optimizations (rust-analyzer
-    /// assumes that non-member crates don't change).
-    is_workspace_member?: boolean;
-    /// Optionally specify the (super)set of `.rs`
-    /// files comprising this crate.
-    ///
-    /// By default, rust-analyzer assumes that only
-    /// files under `root_module.parent` can belong
-    /// to a crate. `include_dirs` are included
-    /// recursively, unless a subdirectory is in
-    /// `exclude_dirs`.
-    ///
-    /// Different crates can share the same `source`.
-    ///
-    /// If two crates share an `.rs` file in common,
-    /// they *must* have the same `source`.
-    /// rust-analyzer assumes that files from one
-    /// source can't refer to files in another source.
-    source?: {
-        include_dirs: string[];
-        exclude_dirs: string[];
-    };
-    /// List of cfg groups this crate inherits.
-    ///
-    /// All cfg in these groups will be concatenated to
-    /// `cfg`. It is impossible to replace a value from
-    /// the groups.
-    cfg_groups?: string[];
-    /// The set of cfgs activated for a given crate, like
-    /// `["unix", "feature=\"foo\"", "feature=\"bar\""]`.
-    cfg: string[];
-    /// Target tuple for this Crate.
-    ///
-    /// Used when running `rustc --print cfg`
-    /// to get target-specific cfgs.
-    target?: string;
-    /// Environment variables, used for
-    /// the `env!` macro
-    env: { [key: string]: string; };
-
-    /// Whether the crate is a proc-macro crate.
-    is_proc_macro: boolean;
-    /// For proc-macro crates, path to compiled
-    /// proc-macro (.so file).
-    proc_macro_dylib_path?: string;
-
-    /// Repository, matching the URL that would be used
-    /// in Cargo.toml.
-    repository?: string;
-
-    /// Build-specific data about this crate.
-    build?: BuildInfo;
-}
-
-interface Dep {
-    /// Index of a crate in the `crates` array.
-    crate: number;
-    /// Name as should appear in the (implicit)
-    /// `extern crate name` declaration.
-    name: string;
-}
-
-interface BuildInfo {
-    /// The name associated with this crate.
-    ///
-    /// This is determined by the build system that produced
-    /// the `rust-project.json` in question. For instance, if buck were used,
-    /// the label might be something like `//ide/rust/rust-analyzer:rust-analyzer`.
-    ///
-    /// Do not attempt to parse the contents of this string; it is a build system-specific
-    /// identifier similar to `Crate::display_name`.
-    label: string;
-    /// Path corresponding to the build system-specific file defining the crate.
-    build_file: string;
-    /// The kind of target.
-    ///
-    /// This information is used to determine what sort
-    /// of runnable codelens to provide, if any.
-    target_kind: 'bin' | 'lib' | 'test';
-}
-
-interface Runnable {
-    /// The program invoked by the runnable.
-    ///
-    /// For example, this might be `cargo`, `buck`, or `bazel`.
-    program: string;
-    /// The arguments passed to `program`.
-    args: string[];
-    /// The current working directory of the runnable.
-    cwd: string;
-    /// Used to decide what code lens to offer.
-    ///
-    /// `testOne`: This runnable will be used when the user clicks the 'Run Test'
-    /// CodeLens above a test.
-    ///
-    /// The args for testOne can contain two template strings:
-    /// `{label}` and `{test_id}`. `{label}` will be replaced
-    /// with the `Build::label` and `{test_id}` will be replaced
-    /// with the test name.
-    kind: 'testOne' | string;
-}
-----
-
-This format is provisional and subject to change.
-Specifically, the `roots` setup will be different eventually.
-
-There are three ways to feed `rust-project.json` to rust-analyzer:
-
-* Place `rust-project.json` file at the root of the project, and rust-analyzer will discover it.
-* Specify `"rust-analyzer.linkedProjects": [ "path/to/rust-project.json" ]` in the settings (and make sure that your LSP client sends settings as a part of initialize request).
-* Specify `"rust-analyzer.linkedProjects": [ { "roots": [...], "crates": [...] }]` inline.
-
-Relative paths are interpreted relative to `rust-project.json` file location or (for inline JSON) relative to `rootUri`.
-
-You can set the `RA_LOG` environment variable to `rust_analyzer=info` to inspect how rust-analyzer handles config and project loading.
-
-Note that calls to `cargo check` are disabled when using `rust-project.json` by default, so compilation errors and warnings will no longer be sent to your LSP client.
-To enable these compilation errors you will need to specify explicitly what command rust-analyzer should run to perform the checks using the `rust-analyzer.check.overrideCommand` configuration.
-As an example, the following configuration explicitly sets `cargo check` as the `check` command.
-
-[source,json]
-----
-{ "rust-analyzer.check.overrideCommand": ["cargo", "check", "--message-format=json"] }
-----
-
-`check.overrideCommand` requires the command specified to output json error messages for rust-analyzer to consume.
-The `--message-format=json` flag does this for `cargo check` so whichever command you use must also output errors in this format.
-See the <<Configuration>> section for more information.
-
-== Security
-
-At the moment, rust-analyzer assumes that all code is trusted.
-Here is a **non-exhaustive** list of ways to make rust-analyzer execute arbitrary code:
-
-* proc macros and build scripts are executed by default
-* `.cargo/config` can override `rustc` with an arbitrary executable
-* `rust-toolchain.toml` can override `rustc` with an arbitrary executable
-* VS Code plugin reads configuration from project directory, and that can be used to override paths to various executables, like `rustfmt` or `rust-analyzer` itself.
-* rust-analyzer's syntax trees library uses a lot of `unsafe` and hasn't been properly audited for memory safety.
-
-== Privacy
-
-The LSP server performs no network access in itself, but runs `cargo metadata` which will update or download the crate registry and the source code of the project dependencies.
-If enabled (the default), build scripts and procedural macros can do anything.
-
-The Code extension does not access the network.
-
-Any other editor plugins are not under the control of the `rust-analyzer` developers. For any privacy concerns, you should check with their respective developers.
-
-For `rust-analyzer` developers, `cargo xtask release` uses the GitHub API to put together the release notes.
-
-== Features
-
-include::./generated_features.adoc[]
-
-== Assists (Code Actions)
-
-Assists, or code actions, are small local refactorings, available in a particular context.
-They are usually triggered by a shortcut or by clicking a light bulb icon in the editor.
-Cursor position or selection is signified by `┃` character.
-
-include::./generated_assists.adoc[]
-
-== Diagnostics
-
-While most errors and warnings provided by rust-analyzer come from the `cargo check` integration, there's a growing number of diagnostics implemented using rust-analyzer's own analysis.
-Some of these diagnostics don't respect `\#[allow]` or `\#[deny]` attributes yet, but can be turned off using the `rust-analyzer.diagnostics.enable`, `rust-analyzer.diagnostics.experimental.enable` or `rust-analyzer.diagnostics.disabled` settings.
-
-=== Clippy
-
-To run `cargo clippy` instead of `cargo check`, you can set `"rust-analyzer.check.command": "clippy"`.
-
-include::./generated_diagnostic.adoc[]
-
-== Editor Features
-=== VS Code
-
-==== Color configurations
-
-It is possible to change the foreground/background color and font family/size of inlay hints.
-Just add this to your `settings.json`:
-
-[source,jsonc]
-----
-{
-  "editor.inlayHints.fontFamily": "Courier New",
-  "editor.inlayHints.fontSize": 11,
-
-  "workbench.colorCustomizations": {
-    // Name of the theme you are currently using
-    "[Default Dark+]": {
-      "editorInlayHint.foreground": "#868686f0",
-      "editorInlayHint.background": "#3d3d3d48",
-
-      // Overrides for specific kinds of inlay hints
-      "editorInlayHint.typeForeground": "#fdb6fdf0",
-      "editorInlayHint.parameterForeground": "#fdb6fdf0",
-    }
-  }
-}
-----
-
-==== Semantic style customizations
-
-You can customize the look of different semantic elements in the source code.
-For example, mutable bindings are underlined by default and you can override this behavior by adding the following section to your `settings.json`:
-
-[source,jsonc]
-----
-{
-  "editor.semanticTokenColorCustomizations": {
-    "rules": {
-      "*.mutable": {
-        "fontStyle": "", // underline is the default
-      },
-    }
-  },
-}
-----
-
-Most themes doesn't support styling unsafe operations differently yet. You can fix this by adding overrides for the rules `operator.unsafe`, `function.unsafe`, and `method.unsafe`:
-
-[source,jsonc]
-----
-{
-   "editor.semanticTokenColorCustomizations": {
-         "rules": {
-             "operator.unsafe": "#ff6600",
-             "function.unsafe": "#ff6600",
-             "method.unsafe": "#ff6600"
-         }
-    },
-}
-----
-
-In addition to the top-level rules you can specify overrides for specific themes. For example, if you wanted to use a darker text color on a specific light theme, you might write:
-
-[source,jsonc]
-----
-{
-   "editor.semanticTokenColorCustomizations": {
-         "rules": {
-             "operator.unsafe": "#ff6600"
-         },
-         "[Ayu Light]": {
-            "rules": {
-               "operator.unsafe": "#572300"
-            }
-         }
-    },
-}
-----
-
-Make sure you include the brackets around the theme name. For example, use `"[Ayu Light]"` to customize the theme Ayu Light.
-
-==== Special `when` clause context for keybindings.
-You may use `inRustProject` context to configure keybindings for rust projects only.
-For example:
-
-[source,json]
-----
-{
-  "key": "ctrl+alt+d",
-  "command": "rust-analyzer.openDocs",
-  "when": "inRustProject"
-}
-----
-More about `when` clause contexts https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts[here].
-
-==== Setting runnable environment variables
-You can use "rust-analyzer.runnables.extraEnv" setting to define runnable environment-specific substitution variables.
-The simplest way for all runnables in a bunch:
-```jsonc
-"rust-analyzer.runnables.extraEnv": {
-    "RUN_SLOW_TESTS": "1"
-}
-```
-
-Or it is possible to specify vars more granularly:
-```jsonc
-"rust-analyzer.runnables.extraEnv": [
-    {
-        // "mask": null, // null mask means that this rule will be applied for all runnables
-        "env": {
-             "APP_ID": "1",
-             "APP_DATA": "asdf"
-        }
-    },
-    {
-        "mask": "test_name",
-        "env": {
-             "APP_ID": "2", // overwrites only APP_ID
-        }
-    }
-]
-```
-
-You can use any valid regular expression as a mask.
-Also note that a full runnable name is something like *run bin_or_example_name*, *test some::mod::test_name* or *test-mod some::mod*, so it is possible to distinguish binaries, single tests, and test modules with this masks: `"^run"`, `"^test "` (the trailing space matters!), and `"^test-mod"` respectively.
-
-If needed, you can set different values for different platforms:
-```jsonc
-"rust-analyzer.runnables.extraEnv": [
-    {
-        "platform": "win32", // windows only
-        "env": {
-             "APP_DATA": "windows specific data"
-        }
-    },
-    {
-        "platform": ["linux"],
-        "env": {
-             "APP_DATA": "linux data",
-        }
-    },
-    { // for all platforms
-        "env": {
-             "APP_COMMON_DATA": "xxx",
-        }
-    }
-]
-```
-
-==== Compiler feedback from external commands
-
-Instead of relying on the built-in `cargo check`, you can configure Code to run a command in the background and use the `$rustc-watch` problem matcher to generate inline error markers from its output.
-
-To do this you need to create a new https://code.visualstudio.com/docs/editor/tasks[VS Code Task] and set `"rust-analyzer.checkOnSave": false` in preferences.
-
-For example, if you want to run https://crates.io/crates/cargo-watch[`cargo watch`] instead, you might add the following to `.vscode/tasks.json`:
-
-```json
-{
-    "label": "Watch",
-    "group": "build",
-    "type": "shell",
-    "command": "cargo watch",
-    "problemMatcher": "$rustc-watch",
-    "isBackground": true
-}
-```
-
-==== Live Share
-
-VS Code Live Share has partial support for rust-analyzer.
-
-Live Share _requires_ the official Microsoft build of VS Code, OSS builds will not work correctly.
-
-The host's rust-analyzer instance will be shared with all guests joining the session.
-The guests do not have to have the rust-analyzer extension installed for this to work.
-
-If you are joining a Live Share session and _do_ have rust-analyzer installed locally, commands from the command palette will not work correctly since they will attempt to communicate with the local server.
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index f148041ac3e..0a603767705 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -501,6 +501,10 @@
                                 },
                                 {
                                     "pattern": "**/Cargo.lock"
+                                },
+                                {
+                                    "scheme": "output",
+                                    "pattern": "extension-output-rust-lang.rust-analyzer*"
                                 }
                             ]
                         }
@@ -2252,6 +2256,16 @@
             {
                 "title": "inlayHints",
                 "properties": {
+                    "rust-analyzer.inlayHints.typeHints.hideClosureParameter": {
+                        "markdownDescription": "Whether to hide inlay parameter type hints for closures.",
+                        "default": false,
+                        "type": "boolean"
+                    }
+                }
+            },
+            {
+                "title": "inlayHints",
+                "properties": {
                     "rust-analyzer.inlayHints.typeHints.hideNamedConstructor": {
                         "markdownDescription": "Whether to hide inlay type hints for constructors.",
                         "default": false,
diff --git a/src/tools/rust-analyzer/editors/code/src/commands.ts b/src/tools/rust-analyzer/editors/code/src/commands.ts
index b3aa04af7ed..eee623ecae9 100644
--- a/src/tools/rust-analyzer/editors/code/src/commands.ts
+++ b/src/tools/rust-analyzer/editors/code/src/commands.ts
@@ -361,10 +361,7 @@ export function syntaxTreeReveal(): Cmd {
         const activeEditor = vscode.window.activeTextEditor;
 
         if (activeEditor !== undefined) {
-            const start = activeEditor.document.positionAt(element.start);
-            const end = activeEditor.document.positionAt(element.end);
-
-            const newSelection = new vscode.Selection(start, end);
+            const newSelection = new vscode.Selection(element.range.start, element.range.end);
 
             activeEditor.selection = newSelection;
             activeEditor.revealRange(newSelection);
@@ -378,15 +375,12 @@ function elementToString(
     depth: number = 0,
 ): string {
     let result = "  ".repeat(depth);
-    const start = element.istart ?? element.start;
-    const end = element.iend ?? element.end;
+    const offsets = element.inner?.offsets ?? element.offsets;
 
-    result += `${element.kind}@${start}..${end}`;
+    result += `${element.kind}@${offsets.start}..${offsets.end}`;
 
     if (element.type === "Token") {
-        const startPosition = activeDocument.positionAt(element.start);
-        const endPosition = activeDocument.positionAt(element.end);
-        const text = activeDocument.getText(new vscode.Range(startPosition, endPosition));
+        const text = activeDocument.getText(element.range).replaceAll("\r\n", "\n");
         // JSON.stringify quotes and escapes the string for us.
         result += ` ${JSON.stringify(text)}\n`;
     } else {
diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts
index 96dc4f19b82..4248305d5cc 100644
--- a/src/tools/rust-analyzer/editors/code/src/ctx.ts
+++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts
@@ -384,9 +384,7 @@ export class Ctx implements RustAnalyzerExtensionApi {
                 return;
             }
 
-            const start = e.textEditor.document.offsetAt(selection.start);
-            const end = e.textEditor.document.offsetAt(selection.end);
-            const result = this.syntaxTreeProvider?.getElementByRange(start, end);
+            const result = this.syntaxTreeProvider?.getElementByRange(selection);
             if (result !== undefined) {
                 await this.syntaxTreeView?.reveal(result);
             }
diff --git a/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts b/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts
index c7e8007e838..3f7e30f13a3 100644
--- a/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts
+++ b/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts
@@ -37,11 +37,7 @@ export class SyntaxTreeProvider implements vscode.TreeDataProvider<SyntaxElement
         const editor = vscode.window.activeTextEditor;
 
         if (editor !== undefined) {
-            const start = editor.document.positionAt(element.start);
-            const end = editor.document.positionAt(element.end);
-            const range = new vscode.Range(start, end);
-
-            const text = editor.document.getText(range);
+            const text = editor.document.getText(element.range);
             item.tooltip = new vscode.MarkdownString().appendCodeblock(text, "rust");
         }
 
@@ -74,14 +70,61 @@ export class SyntaxTreeProvider implements vscode.TreeDataProvider<SyntaxElement
         if (editor && isRustEditor(editor)) {
             const params = { textDocument: { uri: editor.document.uri.toString() }, range: null };
             const fileText = await this.ctx.client.sendRequest(ra.viewSyntaxTree, params);
-            this.root = JSON.parse(fileText, (_key, value: SyntaxElement) => {
+            this.root = JSON.parse(fileText, (_key, value: RawElement): SyntaxElement => {
+                if (value.type !== "Node" && value.type !== "Token") {
+                    // This is something other than a RawElement.
+                    return value;
+                }
+                const [startOffset, startLine, startCol] = value.start;
+                const [endOffset, endLine, endCol] = value.end;
+                const range = new vscode.Range(startLine, startCol, endLine, endCol);
+                const offsets = {
+                    start: startOffset,
+                    end: endOffset,
+                };
+
+                let inner;
+                if (value.istart && value.iend) {
+                    const [istartOffset, istartLine, istartCol] = value.istart;
+                    const [iendOffset, iendLine, iendCol] = value.iend;
+
+                    inner = {
+                        offsets: {
+                            start: istartOffset,
+                            end: iendOffset,
+                        },
+                        range: new vscode.Range(istartLine, istartCol, iendLine, iendCol),
+                    };
+                }
+
                 if (value.type === "Node") {
-                    for (const child of value.children) {
-                        child.parent = value;
+                    const result = {
+                        type: value.type,
+                        kind: value.kind,
+                        offsets,
+                        range,
+                        inner,
+                        children: value.children,
+                        parent: undefined,
+                        document: editor.document,
+                    };
+
+                    for (const child of result.children) {
+                        child.parent = result;
                     }
-                }
 
-                return value;
+                    return result;
+                } else {
+                    return {
+                        type: value.type,
+                        kind: value.kind,
+                        offsets,
+                        range,
+                        inner,
+                        parent: undefined,
+                        document: editor.document,
+                    };
+                }
             });
         } else {
             this.root = undefined;
@@ -90,14 +133,14 @@ export class SyntaxTreeProvider implements vscode.TreeDataProvider<SyntaxElement
         this._onDidChangeTreeData.fire();
     }
 
-    getElementByRange(start: number, end: number): SyntaxElement | undefined {
+    getElementByRange(target: vscode.Range): SyntaxElement | undefined {
         if (this.root === undefined) {
             return undefined;
         }
 
         let result: SyntaxElement = this.root;
 
-        if (this.root.start === start && this.root.end === end) {
+        if (this.root.range.isEqual(target)) {
             return result;
         }
 
@@ -105,9 +148,9 @@ export class SyntaxTreeProvider implements vscode.TreeDataProvider<SyntaxElement
 
         outer: while (true) {
             for (const child of children) {
-                if (child.start <= start && child.end >= end) {
+                if (child.range.contains(target)) {
                     result = child;
-                    if (start === end && start === child.end) {
+                    if (target.isEmpty && target.start === child.range.end) {
                         // When the cursor is on the very end of a token,
                         // we assume the user wants the next token instead.
                         continue;
@@ -136,31 +179,72 @@ export class SyntaxTreeProvider implements vscode.TreeDataProvider<SyntaxElement
 export type SyntaxNode = {
     type: "Node";
     kind: string;
-    start: number;
-    end: number;
-    istart?: number;
-    iend?: number;
+    range: vscode.Range;
+    offsets: {
+        start: number;
+        end: number;
+    };
+    /** This element's position within a Rust string literal, if it's inside of one. */
+    inner?: {
+        range: vscode.Range;
+        offsets: {
+            start: number;
+            end: number;
+        };
+    };
     children: SyntaxElement[];
     parent?: SyntaxElement;
+    document: vscode.TextDocument;
 };
 
 type SyntaxToken = {
     type: "Token";
     kind: string;
-    start: number;
-    end: number;
-    istart?: number;
-    iend?: number;
+    range: vscode.Range;
+    offsets: {
+        start: number;
+        end: number;
+    };
+    /** This element's position within a Rust string literal, if it's inside of one. */
+    inner?: {
+        range: vscode.Range;
+        offsets: {
+            start: number;
+            end: number;
+        };
+    };
     parent?: SyntaxElement;
+    document: vscode.TextDocument;
 };
 
 export type SyntaxElement = SyntaxNode | SyntaxToken;
 
+type RawNode = {
+    type: "Node";
+    kind: string;
+    start: [number, number, number];
+    end: [number, number, number];
+    istart?: [number, number, number];
+    iend?: [number, number, number];
+    children: SyntaxElement[];
+};
+
+type RawToken = {
+    type: "Token";
+    kind: string;
+    start: [number, number, number];
+    end: [number, number, number];
+    istart?: [number, number, number];
+    iend?: [number, number, number];
+};
+
+type RawElement = RawNode | RawToken;
+
 export class SyntaxTreeItem extends vscode.TreeItem {
     constructor(private readonly element: SyntaxElement) {
         super(element.kind);
-        const icon = getIcon(element.kind);
-        if (element.type === "Node") {
+        const icon = getIcon(this.element.kind);
+        if (this.element.type === "Node") {
             this.contextValue = "syntaxNode";
             this.iconPath = icon ?? new vscode.ThemeIcon("list-tree");
             this.collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
@@ -170,11 +254,9 @@ export class SyntaxTreeItem extends vscode.TreeItem {
             this.collapsibleState = vscode.TreeItemCollapsibleState.None;
         }
 
-        if (element.istart !== undefined && element.iend !== undefined) {
-            this.description = `${this.element.istart}..${this.element.iend}`;
-        } else {
-            this.description = `${this.element.start}..${this.element.end}`;
-        }
+        const offsets = this.element.inner?.offsets ?? this.element.offsets;
+
+        this.description = `${offsets.start}..${offsets.end}`;
     }
 }
 
diff --git a/src/tools/rust-analyzer/lib/line-index/src/lib.rs b/src/tools/rust-analyzer/lib/line-index/src/lib.rs
index 6f0455ee98b..bc87ada3eb5 100644
--- a/src/tools/rust-analyzer/lib/line-index/src/lib.rs
+++ b/src/tools/rust-analyzer/lib/line-index/src/lib.rs
@@ -235,7 +235,7 @@ fn analyze_source_file_dispatch(
     }
 }
 
-#[cfg(target_arch = "aarch64")]
+#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
 fn analyze_source_file_dispatch(
     src: &str,
     lines: &mut Vec<TextSize>,
@@ -347,7 +347,7 @@ unsafe fn analyze_source_file_sse2(
 }
 
 #[target_feature(enable = "neon")]
-#[cfg(target_arch = "aarch64")]
+#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
 #[inline]
 // See https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon
 //
@@ -362,7 +362,7 @@ unsafe fn move_mask(v: std::arch::aarch64::uint8x16_t) -> u64 {
 }
 
 #[target_feature(enable = "neon")]
-#[cfg(target_arch = "aarch64")]
+#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
 unsafe fn analyze_source_file_neon(
     src: &str,
     lines: &mut Vec<TextSize>,
@@ -441,7 +441,11 @@ unsafe fn analyze_source_file_neon(
     }
 }
 
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")))]
+#[cfg(not(any(
+    target_arch = "x86",
+    target_arch = "x86_64",
+    all(target_arch = "aarch64", target_endian = "little")
+)))]
 // The target (or compiler version) does not support SSE2 ...
 fn analyze_source_file_dispatch(
     src: &str,
diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version
index 2d9a927c638..f414893b6cd 100644
--- a/src/tools/rust-analyzer/rust-version
+++ b/src/tools/rust-analyzer/rust-version
@@ -1 +1 @@
-9a1d156f38c51441ee51e5a068f1d0caf4bb0f27
+d9a4a47b8b3dc0bdff83360cea2013200d60d49c
diff --git a/src/tools/rust-analyzer/xtask/Cargo.toml b/src/tools/rust-analyzer/xtask/Cargo.toml
index b505ee835b2..ebd8903ad8a 100644
--- a/src/tools/rust-analyzer/xtask/Cargo.toml
+++ b/src/tools/rust-analyzer/xtask/Cargo.toml
@@ -16,8 +16,7 @@ xflags = "0.3.0"
 time = { version = "0.3", default-features = false }
 zip = { version = "0.6", default-features = false, features = ["deflate", "time"] }
 stdx.workspace = true
-# https://github.com/dtolnay/proc-macro2/issues/475
-proc-macro2 = "=1.0.86"
+proc-macro2 = "1.0.93"
 quote = "1.0.20"
 ungrammar = "1.16.1"
 either.workspace = true
diff --git a/src/tools/rust-analyzer/xtask/src/codegen.rs b/src/tools/rust-analyzer/xtask/src/codegen.rs
index bc04b9474f2..18f49643dc7 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen.rs
@@ -24,6 +24,7 @@ impl flags::Codegen {
                 diagnostics_docs::generate(self.check);
                 assists_doc_tests::generate(self.check);
                 parser_inline_tests::generate(self.check);
+                feature_docs::generate(self.check)
                 // diagnostics_docs::generate(self.check) doesn't generate any tests
                 // lints::generate(self.check) Updating clones the rust repo, so don't run it unless
                 // explicitly asked for
@@ -116,13 +117,7 @@ impl fmt::Display for Location {
         let path = self.file.strip_prefix(project_root()).unwrap().display().to_string();
         let path = path.replace('\\', "/");
         let name = self.file.file_name().unwrap();
-        write!(
-            f,
-            "https://github.com/rust-lang/rust-analyzer/blob/master/{}#L{}[{}]",
-            path,
-            self.line,
-            name.to_str().unwrap()
-        )
+        write!(f, " [{}]({}#{}) ", name.to_str().unwrap(), path, self.line)
     }
 }
 
@@ -162,7 +157,7 @@ fn reformat(text: String) -> String {
 }
 
 fn add_preamble(cg: CodegenType, mut text: String) -> String {
-    let preamble = format!("//! Generated by `cargo codegen {cg}`, do not edit by hand.\n\n");
+    let preamble = format!("//! Generated by `cargo xtask codegen {cg}`, do not edit by hand.\n\n");
     text.insert_str(0, &preamble);
     text
 }
@@ -186,7 +181,7 @@ fn ensure_file_contents(cg: CodegenType, file: &Path, contents: &str, check: boo
             file.display(),
             if std::env::var("CI").is_ok() {
                 format!(
-                    "\n    NOTE: run `cargo codegen {cg}` locally and commit the updated files\n"
+                    "\n    NOTE: run `cargo xtask codegen {cg}` locally and commit the updated files\n"
                 )
             } else {
                 "".to_owned()
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/assists_doc_tests.rs b/src/tools/rust-analyzer/xtask/src/codegen/assists_doc_tests.rs
index d06c9d65df3..0bb18c73cfc 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/assists_doc_tests.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/assists_doc_tests.rs
@@ -1,4 +1,4 @@
-//! Generates `assists.md` documentation.
+//! Generates `assists_generated.md` documentation.
 
 use std::{fmt, fs, path::Path};
 
@@ -62,7 +62,7 @@ r#####"
             crate::flags::CodegenType::AssistsDocTests,
             assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"),
         );
-        let dst = project_root().join("docs/user/generated_assists.adoc");
+        let dst = project_root().join("docs/book/src/assists_generated.md");
         fs::write(dst, contents).unwrap();
     }
 }
@@ -146,7 +146,7 @@ impl fmt::Display for Assist {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let _ = writeln!(
             f,
-            "[discrete]\n=== `{}`
+            "### `{}`
 **Source:** {}",
             self.id, self.location,
         );
@@ -159,11 +159,11 @@ impl fmt::Display for Assist {
                 "
 {}
 
-.Before
+#### Before
 ```rust
 {}```
 
-.After
+#### After
 ```rust
 {}```",
                 section.doc,
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/diagnostics_docs.rs b/src/tools/rust-analyzer/xtask/src/codegen/diagnostics_docs.rs
index 4cb8f3f259d..cf8f97be009 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/diagnostics_docs.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/diagnostics_docs.rs
@@ -1,4 +1,4 @@
-//! Generates `assists.md` documentation.
+//! Generates `diagnostics_generated.md` documentation.
 
 use std::{fmt, fs, io, path::PathBuf};
 
@@ -14,7 +14,7 @@ pub(crate) fn generate(check: bool) {
         let contents =
             diagnostics.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
         let contents = add_preamble(crate::flags::CodegenType::DiagnosticsDocs, contents);
-        let dst = project_root().join("docs/user/generated_diagnostic.adoc");
+        let dst = project_root().join("docs/book/src/diagnostics_generated.md");
         fs::write(dst, contents).unwrap();
     }
 }
@@ -73,6 +73,6 @@ fn is_valid_diagnostic_name(diagnostic: &str) -> Result<(), String> {
 
 impl fmt::Display for Diagnostic {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        writeln!(f, "=== {}\n**Source:** {}\n{}", self.id, self.location, self.doc)
+        writeln!(f, "#### {}\n\nSource: {}\n\n{}\n\n", self.id, self.location, self.doc)
     }
 }
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/feature_docs.rs b/src/tools/rust-analyzer/xtask/src/codegen/feature_docs.rs
index c6451d888b0..51ff13aba81 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/feature_docs.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/feature_docs.rs
@@ -1,9 +1,9 @@
-//! Generates `assists.md` documentation.
+//! Generates `features_generated.md` documentation.
 
 use std::{fmt, fs, io, path::PathBuf};
 
 use crate::{
-    codegen::{CommentBlock, Location},
+    codegen::{add_preamble, CommentBlock, Location},
     project_root,
     util::list_rust_files,
 };
@@ -11,14 +11,8 @@ use crate::{
 pub(crate) fn generate(_check: bool) {
     let features = Feature::collect().unwrap();
     let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
-    let contents = format!(
-        "
-// Generated file, do not edit by hand, see `sourcegen_feature_docs`.
-{}
-",
-        contents.trim()
-    );
-    let dst = project_root().join("docs/user/generated_features.adoc");
+    let contents = add_preamble(crate::flags::CodegenType::FeatureDocs, contents);
+    let dst = project_root().join("docs/book/src/features_generated.md");
     fs::write(dst, contents).unwrap();
 }
 
@@ -80,6 +74,6 @@ fn is_valid_feature_name(feature: &str) -> Result<(), String> {
 
 impl fmt::Display for Feature {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        writeln!(f, "=== {}\n**Source:** {}\n{}", self.id, self.location, self.doc)
+        writeln!(f, "### {}\n**Source:** {}\n{}", self.id, self.location, self.doc)
     }
 }
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
index d5fe3236789..e20dda7fec3 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
@@ -397,6 +397,9 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
         if "{}[]()".contains(token) {
             let c = token.chars().next().unwrap();
             quote! { #c }
+            // underscore is an identifier in the proc-macro api
+        } else if *token == "_" {
+            quote! { _ }
         } else {
             let cs = token.chars().map(|c| Punct::new(c, Spacing::Joint));
             quote! { #(#cs)* }
diff --git a/src/tools/rust-analyzer/xtask/src/publish/notes.rs b/src/tools/rust-analyzer/xtask/src/publish/notes.rs
index c30267295bf..7245ce24311 100644
--- a/src/tools/rust-analyzer/xtask/src/publish/notes.rs
+++ b/src/tools/rust-analyzer/xtask/src/publish/notes.rs
@@ -549,18 +549,18 @@ impl Macro {
             }
             "pr" => {
                 let pr = &self.target;
-                let url = format!("https://github.com/rust-analyzer/rust-analyzer/pull/{pr}");
+                let url = format!("https://github.com/rust-lang/rust-analyzer/pull/{pr}");
                 format!("[`#{pr}`]({url})")
             }
             "commit" => {
                 let hash = &self.target;
                 let short = &hash[0..7];
-                let url = format!("https://github.com/rust-analyzer/rust-analyzer/commit/{hash}");
+                let url = format!("https://github.com/rust-lang/rust-analyzer/commit/{hash}");
                 format!("[`{short}`]({url})")
             }
             "release" => {
                 let date = &self.target;
-                let url = format!("https://github.com/rust-analyzer/rust-analyzer/releases/{date}");
+                let url = format!("https://github.com/rust-lang/rust-analyzer/releases/{date}");
                 format!("[`{date}`]({url})")
             }
             _ => bail!("macro not supported: {name}"),
diff --git a/src/tools/rust-analyzer/xtask/src/release.rs b/src/tools/rust-analyzer/xtask/src/release.rs
index 1a1364c7d10..8e56ce439c5 100644
--- a/src/tools/rust-analyzer/xtask/src/release.rs
+++ b/src/tools/rust-analyzer/xtask/src/release.rs
@@ -9,7 +9,7 @@ use directories::ProjectDirs;
 use stdx::JodChild;
 use xshell::{cmd, Shell};
 
-use crate::{codegen, date_iso, flags, is_release_tag, project_root};
+use crate::{date_iso, flags, is_release_tag, project_root};
 
 impl flags::Release {
     pub(crate) fn run(self, sh: &Shell) -> anyhow::Result<()> {
@@ -29,11 +29,6 @@ impl flags::Release {
             cmd!(sh, "git push --force").run()?;
         }
 
-        // Generates bits of manual.adoc.
-        codegen::diagnostics_docs::generate(false);
-        codegen::assists_doc_tests::generate(false);
-        codegen::feature_docs::generate(false);
-
         let website_root = project_root().join("../rust-analyzer.github.io");
         {
             let _dir = sh.push_dir(&website_root);
@@ -54,20 +49,6 @@ impl flags::Release {
             .max()
             .unwrap_or_default();
 
-        for adoc in [
-            "manual.adoc",
-            "generated_assists.adoc",
-            "generated_config.adoc",
-            "generated_diagnostic.adoc",
-            "generated_features.adoc",
-        ] {
-            let src = project_root().join("./docs/user/").join(adoc);
-            let dst = website_root.join(adoc);
-
-            let contents = sh.read_file(src)?;
-            sh.write_file(dst, contents)?;
-        }
-
         let tags = cmd!(sh, "git tag --list").read()?;
         let prev_tag = tags.lines().filter(|line| is_release_tag(line)).last().unwrap();
 
diff --git a/src/tools/rust-analyzer/xtask/test_data/expected.md b/src/tools/rust-analyzer/xtask/test_data/expected.md
index 19c940c67bd..301837b5c21 100644
--- a/src/tools/rust-analyzer/xtask/test_data/expected.md
+++ b/src/tools/rust-analyzer/xtask/test_data/expected.md
@@ -2,12 +2,12 @@
 
 Hello!
 
-Commit: [`0123456`](https://github.com/rust-analyzer/rust-analyzer/commit/0123456789abcdef0123456789abcdef01234567) \
-Release: [`2022-01-01`](https://github.com/rust-analyzer/rust-analyzer/releases/2022-01-01)
+Commit: [`0123456`](https://github.com/rust-lang/rust-analyzer/commit/0123456789abcdef0123456789abcdef01234567) \
+Release: [`2022-01-01`](https://github.com/rust-lang/rust-analyzer/releases/2022-01-01)
 
 ## New Features
 
-- **BREAKING** [`#1111`](https://github.com/rust-analyzer/rust-analyzer/pull/1111) shortcut <kbd>ctrl</kbd>+<kbd>r</kbd>
+- **BREAKING** [`#1111`](https://github.com/rust-lang/rust-analyzer/pull/1111) shortcut <kbd>ctrl</kbd>+<kbd>r</kbd>
   - hyphen-prefixed list item
 - nested list item
   - `foo` -> `foofoo`
@@ -65,7 +65,7 @@ Release: [`2022-01-01`](https://github.com/rust-analyzer/rust-analyzer/releases/
 - list item with an inline image
   ![](https://example.com/animation.gif)
 
-The highlight of the month is probably [`#1111`](https://github.com/rust-analyzer/rust-analyzer/pull/1111).
+The highlight of the month is probably [`#1111`](https://github.com/rust-lang/rust-analyzer/pull/1111).
 See [online manual](https://example.com/manual) for more information.
 
 ```bash
diff --git a/src/tools/rust-installer/src/compression.rs b/src/tools/rust-installer/src/compression.rs
index 96c48657c46..df3a98ae789 100644
--- a/src/tools/rust-installer/src/compression.rs
+++ b/src/tools/rust-installer/src/compression.rs
@@ -81,14 +81,17 @@ impl CompressionFormat {
         let file = crate::util::create_new_file(path)?;
 
         Ok(match self {
-            CompressionFormat::Gz => Box::new(GzEncoder::new(file, match profile {
-                CompressionProfile::Fast => flate2::Compression::fast(),
-                CompressionProfile::Balanced => flate2::Compression::new(6),
-                CompressionProfile::Best => flate2::Compression::best(),
-                CompressionProfile::NoOp => panic!(
-                    "compression profile 'no-op' should not call `CompressionFormat::encode`."
-                ),
-            })),
+            CompressionFormat::Gz => Box::new(GzEncoder::new(
+                file,
+                match profile {
+                    CompressionProfile::Fast => flate2::Compression::fast(),
+                    CompressionProfile::Balanced => flate2::Compression::new(6),
+                    CompressionProfile::Best => flate2::Compression::best(),
+                    CompressionProfile::NoOp => panic!(
+                        "compression profile 'no-op' should not call `CompressionFormat::encode`."
+                    ),
+                },
+            )),
             CompressionFormat::Xz => {
                 let encoder = match profile {
                     CompressionProfile::NoOp => panic!(
diff --git a/src/tools/rustc-perf-wrapper/Cargo.toml b/src/tools/rustc-perf-wrapper/Cargo.toml
deleted file mode 100644
index 416bfef41d7..00000000000
--- a/src/tools/rustc-perf-wrapper/Cargo.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-[package]
-name = "rustc-perf-wrapper"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-clap = { version = "4.5.7", features = ["derive", "env"] }
diff --git a/src/tools/rustc-perf-wrapper/README.md b/src/tools/rustc-perf-wrapper/README.md
deleted file mode 100644
index d7655459a2f..00000000000
--- a/src/tools/rustc-perf-wrapper/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# rustc-perf wrapper
-Utility tool for invoking [`rustc-perf`](https://github.com/rust-lang/rustc-perf) for benchmarking/profiling
-a stage1/2 compiler built by bootstrap using `x perf -- <command>`.
diff --git a/src/tools/rustc-perf-wrapper/src/config.rs b/src/tools/rustc-perf-wrapper/src/config.rs
deleted file mode 100644
index a88abfe4723..00000000000
--- a/src/tools/rustc-perf-wrapper/src/config.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use std::fmt::{Display, Formatter};
-
-#[derive(Clone, Copy, Debug, clap::ValueEnum)]
-#[value(rename_all = "PascalCase")]
-pub enum Profile {
-    Check,
-    Debug,
-    Doc,
-    Opt,
-    Clippy,
-}
-
-impl Display for Profile {
-    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
-        let name = match self {
-            Profile::Check => "Check",
-            Profile::Debug => "Debug",
-            Profile::Doc => "Doc",
-            Profile::Opt => "Opt",
-            Profile::Clippy => "Clippy",
-        };
-        f.write_str(name)
-    }
-}
-
-#[derive(Clone, Copy, Debug, clap::ValueEnum)]
-#[value(rename_all = "PascalCase")]
-pub enum Scenario {
-    Full,
-    IncrFull,
-    IncrUnchanged,
-    IncrPatched,
-}
-
-impl Display for Scenario {
-    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
-        let name = match self {
-            Scenario::Full => "Full",
-            Scenario::IncrFull => "IncrFull",
-            Scenario::IncrUnchanged => "IncrUnchanged",
-            Scenario::IncrPatched => "IncrPatched",
-        };
-        f.write_str(name)
-    }
-}
diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs
deleted file mode 100644
index e6c885e23de..00000000000
--- a/src/tools/rustc-perf-wrapper/src/main.rs
+++ /dev/null
@@ -1,178 +0,0 @@
-use std::fs::create_dir_all;
-use std::path::{Path, PathBuf};
-use std::process::Command;
-
-use clap::Parser;
-
-use crate::config::{Profile, Scenario};
-
-mod config;
-
-/// Performs profiling or benchmarking with [`rustc-perf`](https://github.com/rust-lang/rustc-perf)
-/// using a locally built compiler.
-#[derive(Debug, clap::Parser)]
-// Hide arguments from BuildContext in the default usage string.
-// Clap does not seem to have a way of disabling the usage of these arguments.
-#[clap(override_usage = "rustc-perf-wrapper [OPTIONS] <COMMAND>")]
-pub struct Args {
-    #[clap(subcommand)]
-    cmd: PerfCommand,
-
-    #[clap(flatten)]
-    ctx: BuildContext,
-}
-
-#[derive(Debug, clap::Parser)]
-enum PerfCommand {
-    /// Run `profile_local eprintln`.
-    /// This executes the compiler on the given benchmarks and stores its stderr output.
-    Eprintln {
-        #[clap(flatten)]
-        opts: SharedOpts,
-    },
-    /// Run `profile_local samply`
-    /// This executes the compiler on the given benchmarks and profiles it with `samply`.
-    /// You need to install `samply`, e.g. using `cargo install samply`.
-    Samply {
-        #[clap(flatten)]
-        opts: SharedOpts,
-    },
-    /// Run `profile_local cachegrind`.
-    /// This executes the compiler on the given benchmarks under `Cachegrind`.
-    Cachegrind {
-        #[clap(flatten)]
-        opts: SharedOpts,
-    },
-    Benchmark {
-        /// Identifier to associate benchmark results with
-        id: String,
-
-        #[clap(flatten)]
-        opts: SharedOpts,
-    },
-    Compare {
-        /// The name of the base artifact to be compared.
-        base: String,
-
-        /// The name of the modified artifact to be compared.
-        modified: String,
-    },
-}
-
-#[derive(Debug, clap::Parser)]
-struct SharedOpts {
-    /// Select the benchmarks that you want to run (separated by commas).
-    /// If unspecified, all benchmarks will be executed.
-    #[clap(long, global = true, value_delimiter = ',')]
-    include: Vec<String>,
-
-    /// Select the benchmarks matching a prefix in this comma-separated list that you don't want to run.
-    #[clap(long, global = true, value_delimiter = ',')]
-    exclude: Vec<String>,
-
-    /// Select the scenarios that should be benchmarked.
-    #[clap(
-        long,
-        global = true,
-        value_delimiter = ',',
-        default_value = "Full,IncrFull,IncrUnchanged,IncrPatched"
-    )]
-    scenarios: Vec<Scenario>,
-    /// Select the profiles that should be benchmarked.
-    #[clap(long, global = true, value_delimiter = ',', default_value = "Check,Debug,Opt")]
-    profiles: Vec<Profile>,
-}
-
-/// These arguments are mostly designed to be passed from bootstrap, not by users
-/// directly.
-#[derive(Debug, clap::Parser)]
-struct BuildContext {
-    /// Compiler binary that will be benchmarked/profiled.
-    #[clap(long, hide = true, env = "RUSTC_REAL")]
-    compiler: PathBuf,
-    /// rustc-perf collector binary that will be used for running benchmarks/profilers.
-    #[clap(long, hide = true, env = "PERF_COLLECTOR")]
-    collector: PathBuf,
-    /// Directory where to store results.
-    #[clap(long, hide = true, env = "PERF_RESULT_DIR")]
-    results_dir: PathBuf,
-}
-
-fn main() {
-    let args = Args::parse();
-    run(args);
-}
-
-fn run(args: Args) {
-    let mut cmd = Command::new(args.ctx.collector);
-    let db_path = args.ctx.results_dir.join("results.db");
-
-    match &args.cmd {
-        PerfCommand::Eprintln { opts }
-        | PerfCommand::Samply { opts }
-        | PerfCommand::Cachegrind { opts } => {
-            cmd.arg("profile_local");
-            cmd.arg(match &args.cmd {
-                PerfCommand::Eprintln { .. } => "eprintln",
-                PerfCommand::Samply { .. } => "samply",
-                PerfCommand::Cachegrind { .. } => "cachegrind",
-                _ => unreachable!(),
-            });
-
-            cmd.arg("--out-dir").arg(&args.ctx.results_dir);
-
-            apply_shared_opts(&mut cmd, opts);
-            execute_benchmark(&mut cmd, &args.ctx.compiler);
-
-            println!("You can find the results at `{}`", args.ctx.results_dir.display());
-        }
-        PerfCommand::Benchmark { id, opts } => {
-            cmd.arg("bench_local");
-            cmd.arg("--db").arg(&db_path);
-            cmd.arg("--id").arg(id);
-
-            apply_shared_opts(&mut cmd, opts);
-            create_dir_all(&args.ctx.results_dir).unwrap();
-            execute_benchmark(&mut cmd, &args.ctx.compiler);
-        }
-        PerfCommand::Compare { base, modified } => {
-            cmd.arg("bench_cmp");
-            cmd.arg("--db").arg(&db_path);
-            cmd.arg(base).arg(modified);
-
-            create_dir_all(&args.ctx.results_dir).unwrap();
-            cmd.status().expect("error while running rustc-perf bench_cmp");
-        }
-    }
-}
-
-fn apply_shared_opts(cmd: &mut Command, opts: &SharedOpts) {
-    if !opts.include.is_empty() {
-        cmd.arg("--include").arg(opts.include.join(","));
-    }
-    if !opts.exclude.is_empty() {
-        cmd.arg("--exclude").arg(opts.exclude.join(","));
-    }
-    if !opts.profiles.is_empty() {
-        cmd.arg("--profiles")
-            .arg(opts.profiles.iter().map(|p| p.to_string()).collect::<Vec<_>>().join(","));
-    }
-    if !opts.scenarios.is_empty() {
-        cmd.arg("--scenarios")
-            .arg(opts.scenarios.iter().map(|p| p.to_string()).collect::<Vec<_>>().join(","));
-    }
-}
-
-fn execute_benchmark(cmd: &mut Command, compiler: &Path) {
-    cmd.arg(compiler);
-    println!("Running `rustc-perf` using `{}`", compiler.display());
-
-    const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR");
-
-    let rustc_perf_dir = Path::new(MANIFEST_DIR).join("../rustc-perf");
-
-    // We need to set the working directory to `src/tools/perf`, so that it can find the directory
-    // with compile-time benchmarks.
-    let cmd = cmd.current_dir(rustc_perf_dir);
-    cmd.status().expect("error while running rustc-perf collector");
-}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index faa0db27b2b..5478ff4a6c6 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -285,7 +285,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "expect-test",
     "fallible-iterator", // dependency of `thorin`
     "fastrand",
-    "field-offset",
     "flate2",
     "fluent-bundle",
     "fluent-langneg",
@@ -327,7 +326,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "measureme",
     "memchr",
     "memmap2",
-    "memoffset",
     "miniz_oxide",
     "nix",
     "nu-ansi-term",
@@ -367,14 +365,12 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "rustc-rayon-core",
     "rustc-stable-hash",
     "rustc_apfloat",
-    "rustc_version",
     "rustix",
     "ruzstd", // via object in thorin-dwp
     "ryu",
     "scoped-tls",
     "scopeguard",
     "self_cell",
-    "semver",
     "serde",
     "serde_derive",
     "serde_json",
diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs
index 2a4cff1d12e..4f9a20fa9e2 100644
--- a/src/tools/tidy/src/ext_tool_checks.rs
+++ b/src/tools/tidy/src/ext_tool_checks.rs
@@ -95,10 +95,14 @@ fn check_impl(
         if res.is_err() && show_diff {
             eprintln!("\npython linting failed! Printing diff suggestions:");
 
-            let _ = run_ruff(root_path, outdir, py_path, &cfg_args, &file_args, &[
-                "check".as_ref(),
-                "--diff".as_ref(),
-            ]);
+            let _ = run_ruff(
+                root_path,
+                outdir,
+                py_path,
+                &cfg_args,
+                &file_args,
+                &["check".as_ref(), "--diff".as_ref()],
+            );
         }
         // Rethrow error
         let _ = res?;
@@ -120,10 +124,14 @@ fn check_impl(
             if show_diff {
                 eprintln!("\npython formatting does not match! Printing diff:");
 
-                let _ = run_ruff(root_path, outdir, py_path, &cfg_args, &file_args, &[
-                    "format".as_ref(),
-                    "--diff".as_ref(),
-                ]);
+                let _ = run_ruff(
+                    root_path,
+                    outdir,
+                    py_path,
+                    &cfg_args,
+                    &file_args,
+                    &["format".as_ref(), "--diff".as_ref()],
+                );
             }
             eprintln!("rerun tidy with `--extra-checks=py:fmt --bless` to reformat Python code");
         }
@@ -148,10 +156,11 @@ fn check_impl(
         let files;
         if file_args_clang_format.is_empty() {
             let llvm_wrapper = root_path.join("compiler/rustc_llvm/llvm-wrapper");
-            files = find_with_extension(root_path, Some(llvm_wrapper.as_path()), &[
-                OsStr::new("h"),
-                OsStr::new("cpp"),
-            ])?;
+            files = find_with_extension(
+                root_path,
+                Some(llvm_wrapper.as_path()),
+                &[OsStr::new("h"), OsStr::new("cpp")],
+            )?;
             file_args_clang_format.extend(files.iter().map(|p| p.as_os_str()));
         }
         let args = merge_args(&cfg_args_clang_format, &file_args_clang_format);
diff --git a/src/tools/tidy/src/known_bug.rs b/src/tools/tidy/src/known_bug.rs
index a8771654144..e1921715ab9 100644
--- a/src/tools/tidy/src/known_bug.rs
+++ b/src/tools/tidy/src/known_bug.rs
@@ -14,13 +14,10 @@ pub fn check(filepath: &Path, bad: &mut bool) {
         let test_path_segments_str =
             test_path_segments.iter().map(|s| s.as_str()).collect::<Vec<&str>>();
 
-        if !matches!(test_path_segments_str[..], [
-            ..,
-            "tests",
-            "crashes",
-            "auxiliary",
-            _aux_file_rs
-        ]) && !contents.lines().any(|line| line.starts_with("//@ known-bug: "))
+        if !matches!(
+            test_path_segments_str[..],
+            [.., "tests", "crashes", "auxiliary", _aux_file_rs]
+        ) && !contents.lines().any(|line| line.starts_with("//@ known-bug: "))
         {
             tidy_error!(
                 bad,
diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs
index 46010692fe5..ee94d3c93a6 100644
--- a/src/tools/unicode-table-generator/src/raw_emitter.rs
+++ b/src/tools/unicode-table-generator/src/raw_emitter.rs
@@ -355,12 +355,15 @@ impl Canonicalized {
         let unique_mapping = unique_mapping
             .into_iter()
             .map(|(key, value)| {
-                (key, match value {
-                    UniqueMapping::Canonicalized(idx) => {
-                        u8::try_from(canonical_words.len() + idx).unwrap()
-                    }
-                    UniqueMapping::Canonical(idx) => u8::try_from(idx).unwrap(),
-                })
+                (
+                    key,
+                    match value {
+                        UniqueMapping::Canonicalized(idx) => {
+                            u8::try_from(canonical_words.len() + idx).unwrap()
+                        }
+                        UniqueMapping::Canonical(idx) => u8::try_from(idx).unwrap(),
+                    },
+                )
             })
             .collect::<HashMap<_, _>>();
 
@@ -375,21 +378,24 @@ impl Canonicalized {
         let canonicalized_words = canonicalized_words
             .into_iter()
             .map(|v| {
-                (u8::try_from(v.0).unwrap(), match v.1 {
-                    Mapping::RotateAndInvert(amount) => {
-                        assert_eq!(amount, amount & LOWER_6);
-                        1 << 6 | (amount as u8)
-                    }
-                    Mapping::Rotate(amount) => {
-                        assert_eq!(amount, amount & LOWER_6);
-                        amount as u8
-                    }
-                    Mapping::Invert => 1 << 6,
-                    Mapping::ShiftRight(shift_by) => {
-                        assert_eq!(shift_by, shift_by & LOWER_6);
-                        1 << 7 | (shift_by as u8)
-                    }
-                })
+                (
+                    u8::try_from(v.0).unwrap(),
+                    match v.1 {
+                        Mapping::RotateAndInvert(amount) => {
+                            assert_eq!(amount, amount & LOWER_6);
+                            1 << 6 | (amount as u8)
+                        }
+                        Mapping::Rotate(amount) => {
+                            assert_eq!(amount, amount & LOWER_6);
+                            amount as u8
+                        }
+                        Mapping::Invert => 1 << 6,
+                        Mapping::ShiftRight(shift_by) => {
+                            assert_eq!(shift_by, shift_by & LOWER_6);
+                            1 << 7 | (shift_by as u8)
+                        }
+                    },
+                )
             })
             .collect::<Vec<(u8, u8)>>();
         Canonicalized { unique_mapping, canonical_words, canonicalized_words }
diff --git a/tests/assembly/targets/targets-amdgpu.rs b/tests/assembly/targets/targets-amdgpu.rs
new file mode 100644
index 00000000000..501eed2e247
--- /dev/null
+++ b/tests/assembly/targets/targets-amdgpu.rs
@@ -0,0 +1,21 @@
+//@ assembly-output: emit-asm
+// ignore-tidy-linelength
+//@ revisions: amdgcn_amd_amdhsa
+//@ [amdgcn_amd_amdhsa] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900
+//@ [amdgcn_amd_amdhsa] needs-llvm-components: amdgpu
+
+// Sanity-check that each target can produce assembly code.
+
+#![feature(no_core, lang_items)]
+#![no_std]
+#![no_core]
+#![crate_type = "lib"]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub fn test() -> u8 {
+    42
+}
+
+// CHECK: .version
diff --git a/tests/codegen/autodiff.rs b/tests/codegen/autodiff.rs
new file mode 100644
index 00000000000..abf7fcf3e4b
--- /dev/null
+++ b/tests/codegen/autodiff.rs
@@ -0,0 +1,33 @@
+//@ compile-flags: -C opt-level=3  -Clto=fat
+//@ no-prefer-dynamic
+//@ needs-enzyme
+#![feature(autodiff)]
+
+use std::autodiff::autodiff;
+
+#[autodiff(d_square, Reverse, Duplicated, Active)]
+#[no_mangle]
+fn square(x: &f64) -> f64 {
+    x * x
+}
+
+// CHECK:define internal fastcc double @diffesquare(double %x.0.val, ptr nocapture align 8 %"x'"
+// CHECK-NEXT:invertstart:
+// CHECK-NEXT:  %_0 = fmul double %x.0.val, %x.0.val
+// CHECK-NEXT:  %0 = fadd fast double %x.0.val, %x.0.val
+// CHECK-NEXT:  %1 = load double, ptr %"x'", align 8
+// CHECK-NEXT:  %2 = fadd fast double %1, %0
+// CHECK-NEXT:  store double %2, ptr %"x'", align 8
+// CHECK-NEXT:  ret double %_0
+// CHECK-NEXT:}
+
+fn main() {
+    let x = 3.0;
+    let output = square(&x);
+    assert_eq!(9.0, output);
+
+    let mut df_dx = 0.0;
+    let output_ = d_square(&x, &mut df_dx, 1.0);
+    assert_eq!(output, output_);
+    assert_eq!(6.0, df_dx);
+}
diff --git a/tests/codegen/debug-fndef-size.rs b/tests/codegen/debug-fndef-size.rs
index 27bf00adf0e..c58a8228967 100644
--- a/tests/codegen/debug-fndef-size.rs
+++ b/tests/codegen/debug-fndef-size.rs
@@ -1,4 +1,6 @@
-// Verify that `i32::cmp` FnDef type is declared with size 0 and align 1 in LLVM debuginfo.
+// Verify that `i32::cmp` FnDef type is declared with a size of 0 and an
+// alignment of 8 bits (1 byte) in LLVM debuginfo.
+
 //@ compile-flags: -O -g -Cno-prepopulate-passes
 //@ ignore-msvc the types are mangled differently
 
@@ -14,5 +16,5 @@ pub fn main() {
 
 // CHECK: %compare.dbg.spill = alloca [0 x i8], align 1
 // CHECK: dbg{{.}}declare({{(metadata )?}}ptr %compare.dbg.spill, {{(metadata )?}}![[VAR:.*]], {{(metadata )?}}!DIExpression()
-// CHECK: ![[TYPE:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "fn(&i32, &i32) -> core::cmp::Ordering", baseType: !{{.*}}, align: 1, dwarfAddressSpace: {{.*}})
-// CHECK: ![[VAR]] = !DILocalVariable(name: "compare", scope: !{{.*}}, file: !{{.*}}, line: {{.*}}, type: ![[TYPE]], align: 1)
+// CHECK: ![[TYPE:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "fn(&i32, &i32) -> core::cmp::Ordering", baseType: !{{.*}}, align: 8, dwarfAddressSpace: {{.*}})
+// CHECK: ![[VAR]] = !DILocalVariable(name: "compare", scope: !{{.*}}, file: !{{.*}}, line: {{.*}}, type: ![[TYPE]], align: 8)
diff --git a/tests/codegen/terminating-catchpad.rs b/tests/codegen/terminating-catchpad.rs
new file mode 100644
index 00000000000..17d88796300
--- /dev/null
+++ b/tests/codegen/terminating-catchpad.rs
@@ -0,0 +1,37 @@
+//@ revisions: emscripten wasi seh
+//@[emscripten] compile-flags: --target wasm32-unknown-emscripten -Z emscripten-wasm-eh
+//@[wasi] compile-flags: --target wasm32-wasip1 -C panic=unwind
+//@[seh] compile-flags: --target x86_64-pc-windows-msvc
+//@[emscripten] needs-llvm-components: webassembly
+//@[wasi] needs-llvm-components: webassembly
+//@[seh] needs-llvm-components: x86
+
+// Ensure a catch-all generates:
+// - `catchpad ... [ptr null]` on Wasm (otherwise LLVM gets confused)
+// - `catchpad ... [ptr null, i32 64, ptr null]` on Windows (otherwise we catch SEH exceptions)
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+unsafe extern "C-unwind" {
+    safe fn unwinds();
+}
+
+#[lang = "panic_cannot_unwind"]
+fn panic_cannot_unwind() -> ! {
+    loop {}
+}
+
+#[no_mangle]
+#[rustc_nounwind]
+pub fn doesnt_unwind() {
+    // emscripten: %catchpad = catchpad within %catchswitch [ptr null]
+    // wasi: %catchpad = catchpad within %catchswitch [ptr null]
+    // seh: %catchpad = catchpad within %catchswitch [ptr null, i32 64, ptr null]
+    unwinds();
+}
diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map
index 397eaa17caf..35568a98af4 100644
--- a/tests/coverage/assert_not.cov-map
+++ b/tests/coverage/assert_not.cov-map
@@ -1,15 +1,13 @@
 Function name: assert_not::main
-Raw bytes (31): 0x[01, 01, 01, 0d, 00, 05, 01, 06, 01, 01, 12, 05, 02, 05, 00, 14, 09, 01, 05, 00, 14, 0d, 01, 05, 00, 16, 02, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 12, 05, 02, 05, 00, 14, 09, 01, 05, 00, 14, 0d, 01, 05, 00, 16, 0d, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(3), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 6, 1) to (start + 1, 18)
 - Code(Counter(1)) at (prev + 2, 5) to (start + 0, 20)
 - Code(Counter(2)) at (prev + 1, 5) to (start + 0, 20)
 - Code(Counter(3)) at (prev + 1, 5) to (start + 0, 22)
-- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
-    = (c3 - Zero)
+- Code(Counter(3)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
diff --git a/tests/coverage/bad_counter_ids.cov-map b/tests/coverage/bad_counter_ids.cov-map
index 2b5399f33bb..ba306278449 100644
--- a/tests/coverage/bad_counter_ids.cov-map
+++ b/tests/coverage/bad_counter_ids.cov-map
@@ -9,15 +9,13 @@ Number of file 0 mappings: 2
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::eq_bad_message
-Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 29, 01, 02, 0f, 02, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 29, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 41, 1) to (start + 2, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 32) to (start + 0, 43)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
@@ -64,27 +62,23 @@ Number of file 0 mappings: 3
 Highest counter ID seen: c1
 
 Function name: bad_counter_ids::ne_good
-Raw bytes (16): 0x[01, 01, 01, 01, 00, 02, 01, 1a, 01, 02, 1f, 02, 03, 01, 00, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 1f, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 26, 1) to (start + 2, 31)
-- Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::ne_good_message
-Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 1f, 01, 02, 0f, 00, 02, 20, 00, 2b, 02, 01, 01, 00, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 1f, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 31, 1) to (start + 2, 15)
 - Code(Zero) at (prev + 2, 32) to (start + 0, 43)
-- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/fn_sig_into_try.cov-map b/tests/coverage/fn_sig_into_try.cov-map
index 374811dba9e..6d6034928c9 100644
--- a/tests/coverage/fn_sig_into_try.cov-map
+++ b/tests/coverage/fn_sig_into_try.cov-map
@@ -8,44 +8,38 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: fn_sig_into_try::b
-Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 11, 01, 03, 0f, 00, 03, 0f, 00, 10, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 01, 03, 0f, 00, 03, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 17, 1) to (start + 3, 15)
 - Code(Zero) at (prev + 3, 15) to (start + 0, 16)
-- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 12)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: fn_sig_into_try::c
-Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 18, 01, 03, 17, 00, 03, 17, 00, 18, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 01, 03, 17, 00, 03, 17, 00, 18, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 24, 1) to (start + 3, 23)
 - Code(Zero) at (prev + 3, 23) to (start + 0, 24)
-- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 12)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: fn_sig_into_try::d
-Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 1f, 01, 04, 0f, 00, 04, 0f, 00, 10, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 04, 0f, 00, 04, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 31, 1) to (start + 4, 15)
 - Code(Zero) at (prev + 4, 15) to (start + 0, 16)
-- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 12)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/inline-dead.cov-map b/tests/coverage/inline-dead.cov-map
index 3e2ca2bc992..49cdc514fed 100644
--- a/tests/coverage/inline-dead.cov-map
+++ b/tests/coverage/inline-dead.cov-map
@@ -32,16 +32,13 @@ Number of file 0 mappings: 2
 Highest counter ID seen: c0
 
 Function name: inline_dead::main::{closure#0}
-Raw bytes (23): 0x[01, 01, 02, 07, 00, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 02, 01, 05, 00, 06]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 2
-- expression 0 operands: lhs = Expression(1, Add), rhs = Zero
-- expression 1 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 7, 23) to (start + 1, 22)
 - Code(Zero) at (prev + 1, 23) to (start + 0, 24)
-- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
-    = ((c0 + Zero) - Zero)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map
index efb9d43bf5b..c8f75cddcb5 100644
--- a/tests/coverage/issue-84561.cov-map
+++ b/tests/coverage/issue-84561.cov-map
@@ -59,10 +59,10 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: issue_84561::test3
-Raw bytes (317): 0x[01, 01, 1c, 1d, 21, 25, 29, 21, 25, 2d, 31, 21, 17, 25, 2d, 41, 45, 49, 4d, 51, 55, 33, 51, 49, 4d, 33, 37, 49, 4d, 51, 59, 55, 59, 55, 59, 47, 5d, 55, 59, 61, 65, 71, 75, 69, 6d, 69, 6d, 69, 5f, 6d, 00, 67, 79, 71, 75, 79, 7d, 7d, 81, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 09, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 11, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 19, 02, 05, 00, 1f, 1d, 01, 05, 00, 0f, 02, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 29, 00, 33, 00, 41, 06, 00, 4b, 00, 5a, 0a, 01, 05, 00, 0f, 2d, 05, 09, 03, 10, 31, 05, 0d, 00, 1b, 0e, 02, 0d, 00, 1c, 12, 04, 09, 05, 06, 35, 06, 05, 03, 06, 39, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 41, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 1a, 05, 09, 03, 0a, 33, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 22, 03, 0d, 00, 1d, 26, 03, 09, 00, 13, 2e, 03, 0d, 00, 1d, 47, 03, 05, 00, 0f, 47, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 42, 02, 0d, 00, 13, 61, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 4a, 02, 0d, 00, 13, 67, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 71, 04, 0d, 00, 13, 56, 02, 0d, 00, 17, 56, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 5a, 02, 15, 00, 1b, 75, 04, 0d, 00, 13, 62, 03, 09, 00, 19, 79, 02, 05, 00, 0f, 6a, 03, 09, 00, 22, 7d, 02, 05, 00, 0f, 6e, 03, 09, 00, 2c, 81, 01, 02, 01, 00, 02]
+Raw bytes (315): 0x[01, 01, 1b, 1d, 21, 25, 29, 21, 25, 2d, 31, 21, 17, 25, 2d, 41, 45, 49, 4d, 51, 55, 33, 51, 49, 4d, 33, 37, 49, 4d, 51, 59, 55, 59, 55, 59, 47, 5d, 55, 59, 61, 65, 71, 75, 69, 6d, 69, 6d, 69, 6d, 63, 79, 71, 75, 79, 7d, 7d, 81, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 09, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 11, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 19, 02, 05, 00, 1f, 1d, 01, 05, 00, 0f, 02, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 29, 00, 33, 00, 41, 06, 00, 4b, 00, 5a, 0a, 01, 05, 00, 0f, 2d, 05, 09, 03, 10, 31, 05, 0d, 00, 1b, 0e, 02, 0d, 00, 1c, 12, 04, 09, 05, 06, 35, 06, 05, 03, 06, 39, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 41, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 1a, 05, 09, 03, 0a, 33, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 22, 03, 0d, 00, 1d, 26, 03, 09, 00, 13, 2e, 03, 0d, 00, 1d, 47, 03, 05, 00, 0f, 47, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 42, 02, 0d, 00, 13, 61, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 4a, 02, 0d, 00, 13, 63, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 71, 04, 0d, 00, 13, 5a, 02, 0d, 00, 17, 5a, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 5a, 02, 15, 00, 1b, 75, 04, 0d, 00, 13, 5e, 03, 09, 00, 19, 79, 02, 05, 00, 0f, 66, 03, 09, 00, 22, 7d, 02, 05, 00, 0f, 6a, 03, 09, 00, 2c, 81, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 28
+Number of expressions: 27
 - expression 0 operands: lhs = Counter(7), rhs = Counter(8)
 - expression 1 operands: lhs = Counter(9), rhs = Counter(10)
 - expression 2 operands: lhs = Counter(8), rhs = Counter(9)
@@ -85,12 +85,11 @@ Number of expressions: 28
 - expression 19 operands: lhs = Counter(28), rhs = Counter(29)
 - expression 20 operands: lhs = Counter(26), rhs = Counter(27)
 - expression 21 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 22 operands: lhs = Counter(26), rhs = Expression(23, Add)
-- expression 23 operands: lhs = Counter(27), rhs = Zero
-- expression 24 operands: lhs = Expression(25, Add), rhs = Counter(30)
-- expression 25 operands: lhs = Counter(28), rhs = Counter(29)
-- expression 26 operands: lhs = Counter(30), rhs = Counter(31)
-- expression 27 operands: lhs = Counter(31), rhs = Counter(32)
+- expression 22 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(30)
+- expression 24 operands: lhs = Counter(28), rhs = Counter(29)
+- expression 25 operands: lhs = Counter(30), rhs = Counter(31)
+- expression 26 operands: lhs = Counter(31), rhs = Counter(32)
 Number of file 0 mappings: 51
 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28)
 - Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28)
@@ -142,26 +141,26 @@ Number of file 0 mappings: 51
 - Code(Counter(25)) at (prev + 3, 13) to (start + 0, 19)
 - Code(Expression(18, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = (c24 - c25)
-- Code(Expression(25, Add)) at (prev + 3, 5) to (start + 0, 15)
+- Code(Expression(24, Add)) at (prev + 3, 5) to (start + 0, 15)
     = (c28 + c29)
 - Code(Counter(26)) at (prev + 1, 12) to (start + 0, 19)
 - Code(Counter(27)) at (prev + 1, 13) to (start + 3, 14)
 - Code(Counter(28)) at (prev + 4, 13) to (start + 0, 19)
-- Code(Expression(21, Sub)) at (prev + 2, 13) to (start + 0, 23)
+- Code(Expression(22, Sub)) at (prev + 2, 13) to (start + 0, 23)
     = (c26 - c27)
-- Code(Expression(21, Sub)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Expression(22, Sub)) at (prev + 1, 20) to (start + 0, 27)
     = (c26 - c27)
 - Code(Zero) at (prev + 1, 21) to (start + 0, 27)
 - Code(Expression(22, Sub)) at (prev + 2, 21) to (start + 0, 27)
-    = (c26 - (c27 + Zero))
+    = (c26 - c27)
 - Code(Counter(29)) at (prev + 4, 13) to (start + 0, 19)
-- Code(Expression(24, Sub)) at (prev + 3, 9) to (start + 0, 25)
+- Code(Expression(23, Sub)) at (prev + 3, 9) to (start + 0, 25)
     = ((c28 + c29) - c30)
 - Code(Counter(30)) at (prev + 2, 5) to (start + 0, 15)
-- Code(Expression(26, Sub)) at (prev + 3, 9) to (start + 0, 34)
+- Code(Expression(25, Sub)) at (prev + 3, 9) to (start + 0, 34)
     = (c30 - c31)
 - Code(Counter(31)) at (prev + 2, 5) to (start + 0, 15)
-- Code(Expression(27, Sub)) at (prev + 3, 9) to (start + 0, 44)
+- Code(Expression(26, Sub)) at (prev + 3, 9) to (start + 0, 44)
     = (c31 - c32)
 - Code(Counter(32)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c32
diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map
index 912141b6d5f..640d5f15be0 100644
--- a/tests/coverage/loops_branches.cov-map
+++ b/tests/coverage/loops_branches.cov-map
@@ -1,85 +1,70 @@
 Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
-Raw bytes (116): 0x[01, 01, 06, 05, 00, 1d, 00, 0f, 13, 01, 19, 11, 15, 15, 19, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0d, 00, 0e, 05, 01, 0d, 00, 1e, 11, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 19, 03, 0d, 00, 0e, 15, 00, 12, 00, 17, 19, 01, 10, 00, 14, 1d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 06, 01, 11, 00, 12, 1d, 01, 11, 00, 22, 0a, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 16, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 11, 09, 0d, 0d, 11, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 05, 01, 0d, 00, 0e, 05, 01, 0d, 00, 1e, 09, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 11, 03, 0d, 00, 0e, 0d, 00, 12, 00, 17, 11, 01, 10, 00, 14, 15, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 15, 01, 11, 00, 12, 15, 01, 11, 00, 22, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 6
-- expression 0 operands: lhs = Counter(1), rhs = Zero
-- expression 1 operands: lhs = Counter(7), rhs = Zero
-- expression 2 operands: lhs = Expression(3, Add), rhs = Expression(4, Add)
-- expression 3 operands: lhs = Counter(0), rhs = Counter(6)
-- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 5 operands: lhs = Counter(5), rhs = Counter(6)
+Number of expressions: 4
+- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add)
+- expression 1 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(3), rhs = Counter(4)
 Number of file 0 mappings: 20
 - Code(Counter(0)) at (prev + 9, 5) to (start + 1, 16)
 - Code(Counter(1)) at (prev + 2, 16) to (start + 0, 21)
 - Code(Zero) at (prev + 1, 23) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 28) to (start + 0, 30)
-- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 14)
-    = (c1 - Zero)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 14)
 - Code(Counter(1)) at (prev + 1, 13) to (start + 0, 30)
-- Code(Counter(4)) at (prev + 0, 30) to (start + 0, 31)
+- Code(Counter(2)) at (prev + 0, 30) to (start + 0, 31)
 - Code(Zero) at (prev + 1, 16) to (start + 1, 10)
-- Code(Counter(6)) at (prev + 3, 13) to (start + 0, 14)
-- Code(Counter(5)) at (prev + 0, 18) to (start + 0, 23)
-- Code(Counter(6)) at (prev + 1, 16) to (start + 0, 20)
-- Code(Counter(7)) at (prev + 1, 20) to (start + 0, 25)
+- Code(Counter(4)) at (prev + 3, 13) to (start + 0, 14)
+- Code(Counter(3)) at (prev + 0, 18) to (start + 0, 23)
+- Code(Counter(4)) at (prev + 1, 16) to (start + 0, 20)
+- Code(Counter(5)) at (prev + 1, 20) to (start + 0, 25)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(1, Sub)) at (prev + 1, 17) to (start + 0, 18)
-    = (c7 - Zero)
-- Code(Counter(7)) at (prev + 1, 17) to (start + 0, 34)
-- Code(Expression(2, Sub)) at (prev + 0, 34) to (start + 0, 35)
-    = ((c0 + c6) - (c4 + c5))
+- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 34)
+- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35)
+    = ((c0 + c4) - (c2 + c3))
 - Code(Zero) at (prev + 1, 20) to (start + 1, 14)
-- Code(Expression(5, Sub)) at (prev + 3, 9) to (start + 0, 15)
-    = (c5 - c6)
+- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15)
+    = (c3 - c4)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
-Highest counter ID seen: c7
+Highest counter ID seen: c5
 
 Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
-Raw bytes (122): 0x[01, 01, 09, 01, 00, 01, 00, 0d, 00, 0d, 00, 0d, 00, 1b, 1f, 01, 0d, 09, 1d, 09, 0d, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 06, 01, 0d, 00, 0e, 02, 01, 0d, 00, 1e, 1d, 00, 1e, 00, 1f, 0d, 02, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 12, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0e, 01, 11, 00, 12, 12, 01, 11, 00, 22, 16, 00, 22, 00, 23, 22, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1e, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 22, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 9
-- expression 0 operands: lhs = Counter(0), rhs = Zero
-- expression 1 operands: lhs = Counter(0), rhs = Zero
-- expression 2 operands: lhs = Counter(3), rhs = Zero
-- expression 3 operands: lhs = Counter(3), rhs = Zero
-- expression 4 operands: lhs = Counter(3), rhs = Zero
-- expression 5 operands: lhs = Expression(6, Add), rhs = Expression(7, Add)
-- expression 6 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 7 operands: lhs = Counter(2), rhs = Counter(7)
-- expression 8 operands: lhs = Counter(2), rhs = Counter(3)
+Number of expressions: 4
+- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add)
+- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 20
 - Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17)
 - Code(Zero) at (prev + 1, 18) to (start + 1, 10)
-- Code(Expression(0, Sub)) at (prev + 2, 16) to (start + 0, 21)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 2, 16) to (start + 0, 21)
 - Code(Zero) at (prev + 1, 23) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 28) to (start + 0, 30)
-- Code(Expression(1, Sub)) at (prev + 1, 13) to (start + 0, 14)
-    = (c0 - Zero)
-- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 30)
-    = (c0 - Zero)
-- Code(Counter(7)) at (prev + 0, 30) to (start + 0, 31)
-- Code(Counter(3)) at (prev + 2, 13) to (start + 0, 14)
-- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 23)
-- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31)
+- Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 23)
+- Code(Counter(2)) at (prev + 1, 16) to (start + 0, 21)
 - Code(Zero) at (prev + 0, 22) to (start + 1, 14)
-- Code(Expression(4, Sub)) at (prev + 2, 20) to (start + 0, 25)
-    = (c3 - Zero)
+- Code(Counter(2)) at (prev + 2, 20) to (start + 0, 25)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(3, Sub)) at (prev + 1, 17) to (start + 0, 18)
-    = (c3 - Zero)
-- Code(Expression(4, Sub)) at (prev + 1, 17) to (start + 0, 34)
-    = (c3 - Zero)
-- Code(Expression(5, Sub)) at (prev + 0, 34) to (start + 0, 35)
-    = ((c0 + c3) - (c2 + c7))
-- Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 15)
-    = (c2 - c3)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 34)
+- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35)
+    = ((c0 + c2) - (c1 + c3))
+- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15)
+    = (c1 - c2)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
-Highest counter ID seen: c7
+Highest counter ID seen: c3
 
 Function name: loops_branches::main
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02]
diff --git a/tests/coverage/no_spans_if_not.cov-map b/tests/coverage/no_spans_if_not.cov-map
index 9cb7e6a6cff..6c389a24317 100644
--- a/tests/coverage/no_spans_if_not.cov-map
+++ b/tests/coverage/no_spans_if_not.cov-map
@@ -1,13 +1,11 @@
 Function name: no_spans_if_not::affected_function
-Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 16, 1c, 01, 12, 02, 02, 0d, 00, 0f, 00, 02, 0d, 00, 0f]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 16, 1c, 01, 12, 01, 02, 0d, 00, 0f, 00, 02, 0d, 00, 0f]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 22, 28) to (start + 1, 18)
-- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 15)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 15)
 - Code(Zero) at (prev + 2, 13) to (start + 0, 15)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/tight_inf_loop.cov-map b/tests/coverage/tight_inf_loop.cov-map
index 2d2d59bf013..77a8ffb8358 100644
--- a/tests/coverage/tight_inf_loop.cov-map
+++ b/tests/coverage/tight_inf_loop.cov-map
@@ -1,13 +1,11 @@
 Function name: tight_inf_loop::main
-Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 01, 01, 01, 0d, 00, 02, 09, 00, 10, 02, 01, 06, 01, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 01, 01, 01, 0d, 00, 02, 09, 00, 10, 01, 01, 06, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 1, 1) to (start + 1, 13)
 - Code(Zero) at (prev + 2, 9) to (start + 0, 16)
-- Code(Expression(0, Sub)) at (prev + 1, 6) to (start + 1, 2)
-    = (c0 - Zero)
+- Code(Counter(0)) at (prev + 1, 6) to (start + 1, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/crashes/135470.rs b/tests/crashes/135470.rs
new file mode 100644
index 00000000000..7d357a9317f
--- /dev/null
+++ b/tests/crashes/135470.rs
@@ -0,0 +1,40 @@
+//@ known-bug: #135470
+//@ compile-flags: --edition=2021 -Copt-level=0
+
+use std::future::Future;
+trait Access {
+    type Lister;
+
+    fn list() -> impl Future<Output = Self::Lister> {
+        async { todo!() }
+    }
+}
+
+trait Foo {}
+impl Access for dyn Foo {
+    type Lister = ();
+}
+
+fn main() {
+    let svc = async {
+        async { <dyn Foo>::list() }.await;
+    };
+    &svc as &dyn Service;
+}
+
+trait UnaryService {
+    fn call2() {}
+}
+trait Unimplemented {}
+impl<T: Unimplemented> UnaryService for T {}
+struct Wrap<T>(T);
+impl<T: Send> UnaryService for Wrap<T> {}
+
+trait Service {
+    fn call(&self);
+}
+impl<T: Send> Service for T {
+    fn call(&self) {
+        Wrap::<T>::call2();
+    }
+}
diff --git a/tests/crashes/135528.rs b/tests/crashes/135528.rs
new file mode 100644
index 00000000000..a1418f40be6
--- /dev/null
+++ b/tests/crashes/135528.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #135528
+//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
+#![feature(type_alias_impl_trait)]
+type Tait = impl Copy;
+
+fn set(x: &isize) -> isize {
+    *x
+}
+
+fn d(x: Tait) {
+    set(x);
+}
+
+fn other_define() -> Tait {
+    ()
+}
+
+fn main() {}
diff --git a/tests/crashes/135570.rs b/tests/crashes/135570.rs
new file mode 100644
index 00000000000..a9eda97ef9d
--- /dev/null
+++ b/tests/crashes/135570.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #135570
+//@compile-flags: -Zvalidate-mir -Zmir-enable-passes=+Inline -Copt-level=0 -Zmir-enable-passes=+GVN
+//@ only-x86_64
+
+fn function_with_bytes<const BYTES: &'static [u8; 0xc7b889180b67b07d_bc1a3c88783d35b5_u128]>(
+) -> &'static [u8] {
+    BYTES
+}
+
+fn main() {
+    function_with_bytes::<b"aa">() == &[];
+}
diff --git a/tests/crashes/135617.rs b/tests/crashes/135617.rs
new file mode 100644
index 00000000000..ac524b823a0
--- /dev/null
+++ b/tests/crashes/135617.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #135617
+trait Project {
+    const ASSOC: usize;
+}
+
+fn foo()
+where
+    for<'a> (): Project,
+{
+    [(); <() as Project>::ASSOC];
+}
+
+pub fn main() {}
diff --git a/tests/crashes/135646.rs b/tests/crashes/135646.rs
new file mode 100644
index 00000000000..67b0ad93db4
--- /dev/null
+++ b/tests/crashes/135646.rs
@@ -0,0 +1,5 @@
+//@ known-bug: #135646
+//@ compile-flags: --edition=2024 -Zpolonius=next
+fn main() {
+    &{ [1, 2, 3][4] };
+}
diff --git a/tests/crashes/135668.rs b/tests/crashes/135668.rs
new file mode 100644
index 00000000000..8126a65606b
--- /dev/null
+++ b/tests/crashes/135668.rs
@@ -0,0 +1,38 @@
+//@ known-bug: #135668
+//@ compile-flags: --edition=2021
+use std::future::Future;
+
+pub async fn foo() {
+    let _ = create_task().await;
+}
+
+async fn create_task() -> impl Sized {
+    bind(documentation)
+}
+
+async fn documentation() {
+    include_str!("nonexistent");
+}
+
+fn bind<F>(_filter: F) -> impl Sized
+where
+    F: FilterBase,
+{
+    || -> <F as FilterBase>::Assoc { panic!() }
+}
+
+trait FilterBase {
+    type Assoc;
+}
+
+impl<F, R> FilterBase for F
+where
+    F: Fn() -> R,
+    // Removing the below line makes it correctly error on both stable and beta
+    R: Future,
+    // Removing the below line makes it ICE on both stable and beta
+    R: Send,
+    // Removing the above two bounds makes it ICE on stable but correctly error on beta
+{
+    type Assoc = F;
+}
diff --git a/tests/crashes/135718.rs b/tests/crashes/135718.rs
new file mode 100644
index 00000000000..c0e628f4c46
--- /dev/null
+++ b/tests/crashes/135718.rs
@@ -0,0 +1,50 @@
+//@ known-bug: #135718
+
+struct Equal;
+
+struct Bar;
+
+trait TwiceNested {}
+impl<M> TwiceNested for Bar where Bar: NestMakeEqual<NestEq = M> {}
+
+struct Sum;
+
+trait Not {
+    fn not();
+}
+
+impl<P> Not for Sum
+where
+    Bar: NestMakeEqual<NestEq = P>,
+    Self: Problem<P>,
+{
+    fn not() {}
+}
+
+trait NestMakeEqual {
+    type NestEq;
+}
+
+trait MakeEqual {
+    type Eq;
+}
+
+struct Foo;
+impl MakeEqual for Foo {
+    type Eq = Equal;
+}
+
+impl<O> NestMakeEqual for Bar
+where
+    Foo: MakeEqual<Eq = O>,
+{
+    type NestEq = O;
+}
+
+trait Problem<M> {}
+impl Problem<()> for Sum where Bar: TwiceNested {}
+impl Problem<Equal> for Sum where Bar: TwiceNested {}
+
+fn main() {
+    Sum::not();
+}
diff --git a/tests/crashes/135720.rs b/tests/crashes/135720.rs
new file mode 100644
index 00000000000..ee85bc4b66a
--- /dev/null
+++ b/tests/crashes/135720.rs
@@ -0,0 +1,4 @@
+//@ known-bug: #135720
+#![feature(generic_const_exprs)]
+type S<'l> = [i32; A];
+fn lint_me(x: S<()>) {}
diff --git a/tests/crashes/135845.rs b/tests/crashes/135845.rs
new file mode 100644
index 00000000000..ed038d8a1f1
--- /dev/null
+++ b/tests/crashes/135845.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #135845
+struct S<'a, T: ?Sized>(&'a T);
+
+fn b<'a>() -> S<'static, _> {
+    S::<'a>(&0)
+}
diff --git a/tests/crashes/135863.rs b/tests/crashes/135863.rs
new file mode 100644
index 00000000000..a0ff5988a0d
--- /dev/null
+++ b/tests/crashes/135863.rs
@@ -0,0 +1,10 @@
+//@ known-bug: #135863
+struct A;
+
+impl A {
+    fn len(self: &&B) {}
+}
+
+fn main() {
+    A.len()
+}
diff --git a/tests/crashes/136063.rs b/tests/crashes/136063.rs
new file mode 100644
index 00000000000..078cc59dfa2
--- /dev/null
+++ b/tests/crashes/136063.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #136063
+#![feature(generic_const_exprs)]
+trait A<const B: u8 = X> {}
+impl A<1> for bool {}
+fn bar(arg : &dyn A<x>) { bar(true) }
+pub fn main() {}
diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
index 138586300ce..e9f48a85f9c 100644
--- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
@@ -27,18 +27,15 @@
       }
   
 +     coverage body span: $DIR/branch_match_arms.rs:14:11: 21:2 (#0)
-+     coverage ExpressionId(0) => Expression { lhs: Counter(1), op: Add, rhs: Counter(2) };
-+     coverage ExpressionId(1) => Expression { lhs: Expression(0), op: Add, rhs: Counter(3) };
-+     coverage ExpressionId(2) => Expression { lhs: Counter(0), op: Subtract, rhs: Expression(1) };
-+     coverage Code(Counter(0)) => $DIR/branch_match_arms.rs:14:1: 15:21 (#0);
-+     coverage Code(Counter(1)) => $DIR/branch_match_arms.rs:16:17: 16:33 (#0);
-+     coverage Code(Counter(2)) => $DIR/branch_match_arms.rs:17:17: 17:33 (#0);
-+     coverage Code(Counter(3)) => $DIR/branch_match_arms.rs:18:17: 18:33 (#0);
-+     coverage Code(Expression(2)) => $DIR/branch_match_arms.rs:19:17: 19:33 (#0);
-+     coverage Code(Counter(0)) => $DIR/branch_match_arms.rs:21:2: 21:2 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 15:21 (#0);
++     coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:33 (#0);
++     coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:33 (#0);
++     coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:33 (#0);
++     coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:33 (#0);
++     coverage Code { bcb: bcb2 } => $DIR/branch_match_arms.rs:21:2: 21:2 (#0);
 + 
       bb0: {
-+         Coverage::CounterIncrement(0);
++         Coverage::VirtualCounter(bcb0);
           StorageLive(_1);
           _1 = Enum::A(const 0_u32);
           PlaceMention(_1);
@@ -52,22 +49,22 @@
       }
   
       bb2: {
-+         Coverage::CounterIncrement(1);
++         Coverage::VirtualCounter(bcb1);
           falseEdge -> [real: bb8, imaginary: bb3];
       }
   
       bb3: {
-+         Coverage::CounterIncrement(2);
++         Coverage::VirtualCounter(bcb3);
           falseEdge -> [real: bb7, imaginary: bb4];
       }
   
       bb4: {
-+         Coverage::CounterIncrement(3);
++         Coverage::VirtualCounter(bcb4);
           falseEdge -> [real: bb6, imaginary: bb5];
       }
   
       bb5: {
-+         Coverage::ExpressionUsed(2);
++         Coverage::VirtualCounter(bcb5);
           StorageLive(_9);
           _9 = copy ((_1 as A).0: u32);
           StorageLive(_10);
@@ -124,6 +121,7 @@
       }
   
       bb13: {
++         Coverage::VirtualCounter(bcb2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
index a91d88984a8..cbef6de917d 100644
--- a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
@@ -5,10 +5,10 @@
       let mut _0: bool;
   
 +     coverage body span: $DIR/instrument_coverage.rs:29:18: 31:2 (#0)
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:29:1: 31:2 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:29:1: 31:2 (#0);
 + 
       bb0: {
-+         Coverage::CounterIncrement(0);
++         Coverage::VirtualCounter(bcb0);
           _0 = const true;
           return;
       }
diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
index d7ea442518e..b166d79a412 100644
--- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
@@ -8,20 +8,19 @@
       let mut _3: !;
   
 +     coverage body span: $DIR/instrument_coverage.rs:14:11: 20:2 (#0)
-+     coverage ExpressionId(0) => Expression { lhs: Counter(1), op: Subtract, rhs: Counter(0) };
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:14:1: 14:11 (#0);
-+     coverage Code(Counter(1)) => $DIR/instrument_coverage.rs:16:12: 16:17 (#0);
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:17:13: 17:18 (#0);
-+     coverage Code(Expression(0)) => $DIR/instrument_coverage.rs:18:10: 18:10 (#0);
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:20:2: 20:2 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:14:1: 14:11 (#0);
++     coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:16:12: 16:17 (#0);
++     coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:17:13: 17:18 (#0);
++     coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:18:10: 18:10 (#0);
++     coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:20:2: 20:2 (#0);
 + 
       bb0: {
-+         Coverage::CounterIncrement(0);
++         Coverage::VirtualCounter(bcb0);
           goto -> bb1;
       }
   
       bb1: {
-+         Coverage::CounterIncrement(1);
++         Coverage::VirtualCounter(bcb1);
           falseUnwind -> [real: bb2, unwind: bb6];
       }
   
@@ -35,13 +34,14 @@
       }
   
       bb4: {
++         Coverage::VirtualCounter(bcb2);
           _0 = const ();
           StorageDead(_2);
           return;
       }
   
       bb5: {
-+         Coverage::ExpressionUsed(0);
++         Coverage::VirtualCounter(bcb3);
           _1 = const ();
           StorageDead(_2);
           goto -> bb1;
diff --git a/tests/mir-opt/coverage/instrument_coverage.rs b/tests/mir-opt/coverage/instrument_coverage.rs
index c49786f9615..48647402d0f 100644
--- a/tests/mir-opt/coverage/instrument_coverage.rs
+++ b/tests/mir-opt/coverage/instrument_coverage.rs
@@ -8,9 +8,9 @@
 // EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff
 // CHECK-LABEL: fn main()
 // CHECK: coverage body span:
-// CHECK: coverage Code(Counter({{[0-9]+}})) =>
+// CHECK: coverage Code { bcb: bcb{{[0-9]+}} } =>
 // CHECK: bb0:
-// CHECK: Coverage::CounterIncrement
+// CHECK: Coverage::VirtualCounter
 fn main() {
     loop {
         if bar() {
@@ -22,9 +22,9 @@ fn main() {
 // EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff
 // CHECK-LABEL: fn bar()
 // CHECK: coverage body span:
-// CHECK: coverage Code(Counter({{[0-9]+}})) =>
+// CHECK: coverage Code { bcb: bcb{{[0-9]+}} } =>
 // CHECK: bb0:
-// CHECK: Coverage::CounterIncrement
+// CHECK: Coverage::VirtualCounter
 #[inline(never)]
 fn bar() -> bool {
     true
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
index 2c7ec6e85eb..855f806aae1 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
@@ -8,15 +8,14 @@
       coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
   
       coverage body span: $DIR/instrument_coverage_cleanup.rs:13:11: 15:2 (#0)
-      coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
-      coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
-      coverage Code(Expression(0)) => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
-      coverage Code(Counter(1)) => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
-      coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
-      coverage Branch { true_term: Expression(0), false_term: Counter(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
+      coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
+      coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
+      coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
+      coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
+      coverage Branch { true_bcb: bcb3, false_bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
   
       bb0: {
-          Coverage::CounterIncrement(0);
+          Coverage::VirtualCounter(bcb0);
 -         Coverage::SpanMarker;
 +         nop;
           StorageLive(_1);
@@ -28,7 +27,7 @@
       }
   
       bb2: {
-          Coverage::CounterIncrement(1);
+          Coverage::VirtualCounter(bcb1);
 -         Coverage::BlockMarker(1);
 +         nop;
           _0 = const ();
@@ -36,7 +35,7 @@
       }
   
       bb3: {
-          Coverage::ExpressionUsed(0);
+          Coverage::VirtualCounter(bcb3);
 -         Coverage::BlockMarker(0);
 +         nop;
           _0 = const ();
@@ -44,6 +43,7 @@
       }
   
       bb4: {
+          Coverage::VirtualCounter(bcb2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
index c08265eb0e9..df1f1e8bc50 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
@@ -8,15 +8,14 @@
       coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
   
 +     coverage body span: $DIR/instrument_coverage_cleanup.rs:13:11: 15:2 (#0)
-+     coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
-+     coverage Code(Expression(0)) => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
-+     coverage Code(Counter(1)) => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
-+     coverage Branch { true_term: Expression(0), false_term: Counter(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
++     coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
++     coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
++     coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
++     coverage Branch { true_bcb: bcb3, false_bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
 + 
       bb0: {
-+         Coverage::CounterIncrement(0);
++         Coverage::VirtualCounter(bcb0);
           Coverage::SpanMarker;
           StorageLive(_1);
           _1 = std::hint::black_box::<bool>(const true) -> [return: bb1, unwind: bb5];
@@ -27,20 +26,21 @@
       }
   
       bb2: {
-+         Coverage::CounterIncrement(1);
++         Coverage::VirtualCounter(bcb1);
           Coverage::BlockMarker(1);
           _0 = const ();
           goto -> bb4;
       }
   
       bb3: {
-+         Coverage::ExpressionUsed(0);
++         Coverage::VirtualCounter(bcb3);
           Coverage::BlockMarker(0);
           _0 = const ();
           goto -> bb4;
       }
   
       bb4: {
++         Coverage::VirtualCounter(bcb2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.rs b/tests/mir-opt/coverage/instrument_coverage_cleanup.rs
index acc544a28af..e8af4d6174f 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.rs
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.rs
@@ -3,7 +3,7 @@
 // but leaves the statements that were added by InstrumentCoverage.
 //
 // Removed statement kinds: BlockMarker, SpanMarker
-// Retained statement kinds: CounterIncrement, ExpressionUsed
+// Retained statement kinds: VirtualCounter
 
 //@ test-mir-pass: InstrumentCoverage
 //@ compile-flags: -Cinstrument-coverage -Zcoverage-options=branch -Zno-profiler-runtime
@@ -16,6 +16,6 @@ fn main() {
 
 // CHECK-NOT: Coverage::BlockMarker
 // CHECK-NOT: Coverage::SpanMarker
-// CHECK:     Coverage::CounterIncrement
+// CHECK:     Coverage::VirtualCounter
 // CHECK-NOT: Coverage::BlockMarker
 // CHECK-NOT: Coverage::SpanMarker
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
index 5a830254f61..2c89670dcf7 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -26,7 +26,7 @@
                           }
                           scope 11 (inlined NonZero::<usize>::get) {
                           }
-                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                          scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) {
                               scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
index c11368a347c..8fecfe224cc 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -26,7 +26,7 @@
                           }
                           scope 11 (inlined NonZero::<usize>::get) {
                           }
-                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                          scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) {
                               scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
index 037ed02ce65..976ea252c2f 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -26,7 +26,7 @@
                           }
                           scope 11 (inlined NonZero::<usize>::get) {
                           }
-                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                          scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) {
                               scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
index 86351c78759..6c59f5e3e2e 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -26,7 +26,7 @@
                           }
                           scope 11 (inlined NonZero::<usize>::get) {
                           }
-                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                          scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) {
                               scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
index 20a3897a934..1f9cf6d6aca 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
@@ -26,7 +26,7 @@
                           }
                           scope 11 (inlined NonZero::<usize>::get) {
                           }
-                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                          scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) {
                               scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
index 2e396301fd0..a8760285fac 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
@@ -26,7 +26,7 @@
                           }
                           scope 11 (inlined NonZero::<usize>::get) {
                           }
-                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                          scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) {
                               scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
index 319691174cf..c398ae70a1a 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
@@ -26,7 +26,7 @@
                           }
                           scope 11 (inlined NonZero::<usize>::get) {
                           }
-                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                          scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) {
                               scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
index 5dafc89d53f..02934c02587 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
@@ -26,7 +26,7 @@
                           }
                           scope 11 (inlined NonZero::<usize>::get) {
                           }
-                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                          scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) {
                               scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff
index 8e7964297d0..f56af33ea60 100644
--- a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff
+++ b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff
@@ -16,7 +16,7 @@
                       }
                       scope 8 (inlined NonZero::<usize>::get) {
                       }
-                      scope 9 (inlined without_provenance::<u8>) {
+                      scope 9 (inlined std::ptr::without_provenance::<u8>) {
                           scope 10 (inlined without_provenance_mut::<u8>) {
                           }
                       }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index 496ec78fd8d..b7a9b4a1fe0 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -59,7 +59,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined without_provenance::<T>) {
+                    scope 12 (inlined std::ptr::without_provenance::<T>) {
                         scope 13 (inlined without_provenance_mut::<T>) {
                         }
                     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index c4547cb888f..33dbf04d028 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -34,7 +34,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined without_provenance::<T>) {
+                    scope 12 (inlined std::ptr::without_provenance::<T>) {
                         scope 13 (inlined without_provenance_mut::<T>) {
                         }
                     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 7d011ea3347..dc13bb23c31 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -31,7 +31,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined without_provenance::<T>) {
+                    scope 12 (inlined std::ptr::without_provenance::<T>) {
                         scope 13 (inlined without_provenance_mut::<T>) {
                         }
                     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index 75e6542a3a4..3f1e0e0f746 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -31,7 +31,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined without_provenance::<T>) {
+                    scope 12 (inlined std::ptr::without_provenance::<T>) {
                         scope 13 (inlined without_provenance_mut::<T>) {
                         }
                     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index 41bc91ab028..4b7ab4516d2 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -34,7 +34,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined without_provenance::<T>) {
+                    scope 12 (inlined std::ptr::without_provenance::<T>) {
                         scope 13 (inlined without_provenance_mut::<T>) {
                         }
                     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index 6ed8ef9715b..b2c15247cd7 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -34,7 +34,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined without_provenance::<T>) {
+                    scope 12 (inlined std::ptr::without_provenance::<T>) {
                         scope 13 (inlined without_provenance_mut::<T>) {
                         }
                     }
diff --git a/tests/run-make/apple-deployment-target/rmake.rs b/tests/run-make/apple-deployment-target/rmake.rs
index 0ae95cb1f4b..839e21b7496 100644
--- a/tests/run-make/apple-deployment-target/rmake.rs
+++ b/tests/run-make/apple-deployment-target/rmake.rs
@@ -7,7 +7,11 @@
 
 //@ only-apple
 
-use run_make_support::{apple_os, cmd, run_in_tmpdir, rustc, target};
+use std::collections::HashSet;
+
+use run_make_support::{
+    apple_os, cmd, has_extension, path, regex, run_in_tmpdir, rustc, shallow_find_files, target,
+};
 
 /// Run vtool to check the `minos` field in LC_BUILD_VERSION.
 ///
@@ -166,4 +170,21 @@ fn main() {
         rustc().env_remove(env_var).run();
         minos("foo.o", default_version);
     });
+
+    // Test that all binaries in rlibs produced by `rustc` have the same version.
+    // Regression test for https://github.com/rust-lang/rust/issues/128419.
+    let sysroot = rustc().print("sysroot").run().stdout_utf8();
+    let target_sysroot = path(sysroot.trim()).join("lib/rustlib").join(target()).join("lib");
+    let rlibs = shallow_find_files(&target_sysroot, |path| has_extension(path, "rlib"));
+
+    let output = cmd("otool").arg("-l").args(rlibs).run().stdout_utf8();
+    let re = regex::Regex::new(r"(minos|version) ([0-9.]*)").unwrap();
+    let mut versions = HashSet::new();
+    for (_, [_, version]) in re.captures_iter(&output).map(|c| c.extract()) {
+        versions.insert(version);
+    }
+    // FIXME(madsmtm): See above for aarch64-apple-watchos.
+    if versions.len() != 1 && target() != "aarch64-apple-watchos" {
+        panic!("std rlibs contained multiple different deployment target versions: {versions:?}");
+    }
 }
diff --git a/tests/run-make/libs-through-symlinks/rmake.rs b/tests/run-make/libs-through-symlinks/rmake.rs
index 4bb3d05abb7..894d6246445 100644
--- a/tests/run-make/libs-through-symlinks/rmake.rs
+++ b/tests/run-make/libs-through-symlinks/rmake.rs
@@ -21,6 +21,7 @@
 //! <https://github.com/rust-lang/rust/pull/13903>.
 
 //@ ignore-cross-compile
+//@ needs-symlink
 
 use run_make_support::{bare_rustc, cwd, path, rfs, rust_lib_name};
 
diff --git a/tests/run-make/wasm-export-all-symbols/rmake.rs b/tests/run-make/wasm-export-all-symbols/rmake.rs
index 0c0a785c67c..4148cc29ec2 100644
--- a/tests/run-make/wasm-export-all-symbols/rmake.rs
+++ b/tests/run-make/wasm-export-all-symbols/rmake.rs
@@ -20,13 +20,16 @@ fn test(args: &[&str]) {
     rustc().input("main.rs").target("wasm32-wasip1").args(args).run();
 
     verify_exports(Path::new("foo.wasm"), &[("foo", Func), ("FOO", Global), ("memory", Memory)]);
-    verify_exports(Path::new("main.wasm"), &[
-        ("foo", Func),
-        ("FOO", Global),
-        ("_start", Func),
-        ("__main_void", Func),
-        ("memory", Memory),
-    ]);
+    verify_exports(
+        Path::new("main.wasm"),
+        &[
+            ("foo", Func),
+            ("FOO", Global),
+            ("_start", Func),
+            ("__main_void", Func),
+            ("memory", Memory),
+        ],
+    );
 }
 
 fn verify_exports(path: &Path, exports: &[(&str, wasmparser::ExternalKind)]) {
diff --git a/tests/ui/amdgpu-require-explicit-cpu.nocpu.stderr b/tests/ui/amdgpu-require-explicit-cpu.nocpu.stderr
new file mode 100644
index 00000000000..7480a8ed38f
--- /dev/null
+++ b/tests/ui/amdgpu-require-explicit-cpu.nocpu.stderr
@@ -0,0 +1,4 @@
+error: target requires explicitly specifying a cpu with `-C target-cpu`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/amdgpu-require-explicit-cpu.rs b/tests/ui/amdgpu-require-explicit-cpu.rs
new file mode 100644
index 00000000000..46778a1094f
--- /dev/null
+++ b/tests/ui/amdgpu-require-explicit-cpu.rs
@@ -0,0 +1,17 @@
+//@ revisions: nocpu cpu
+//@ no-prefer-dynamic
+//@ compile-flags: --crate-type=cdylib --target=amdgcn-amd-amdhsa
+//@ needs-llvm-components: amdgpu
+//@ needs-rust-lld
+//@[nocpu] error-pattern: target requires explicitly specifying a cpu
+//@[nocpu] build-fail
+//@[cpu] compile-flags: -Ctarget-cpu=gfx900
+//@[cpu] build-pass
+
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized {}
+
+pub fn foo() {}
diff --git a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr
index 47fbfc98c67..2aa4983624c 100644
--- a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr
+++ b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr
@@ -14,7 +14,7 @@ note: function defined here
   --> $DIR/extern-fn-arg-names.rs:2:8
    |
 LL |     fn dstfn(src: i32, dst: err);
-   |        ^^^^^
+   |        ^^^^^           ---
 help: provide the argument
    |
 LL |     dstfn(1, /* dst */);
diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr
index 7a54d043356..7eca4cb61bc 100644
--- a/tests/ui/c-variadic/variadic-ffi-1.stderr
+++ b/tests/ui/c-variadic/variadic-ffi-1.stderr
@@ -14,7 +14,7 @@ note: function defined here
   --> $DIR/variadic-ffi-1.rs:15:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
-   |        ^^^
+   |        ^^^ -         -
 help: provide the arguments
    |
 LL |         foo(/* isize */, /* u8 */);
@@ -30,7 +30,7 @@ note: function defined here
   --> $DIR/variadic-ffi-1.rs:15:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
-   |        ^^^
+   |        ^^^           -
 help: provide the argument
    |
 LL |         foo(1, /* u8 */);
diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr
index 7e77ba63a12..e7b8f355057 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr
@@ -14,7 +14,7 @@ warning: unexpected `cfg` condition value: `value`
 LL | #[cfg(target_vendor = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
+   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `feature`
diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
index af66cbd8189..95af0a90929 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
@@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value`
 LL | #[cfg(target_vendor = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
+   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `unk`
diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr
index af66cbd8189..95af0a90929 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr
@@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value`
 LL | #[cfg(target_vendor = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
+   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `unk`
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index ffebd7e5531..6421cb8f2c2 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -138,7 +138,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_arch = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
+   = note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_os = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
+   = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -230,7 +230,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_vendor = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
+   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
    |                   |
    |                   help: there is a expected value with a similar name: `"linux"`
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
+   = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: 28 warnings emitted
diff --git a/tests/ui/debuginfo/dwarf-versions.one.stderr b/tests/ui/debuginfo/dwarf-versions.one.stderr
new file mode 100644
index 00000000000..bfc3a0152c6
--- /dev/null
+++ b/tests/ui/debuginfo/dwarf-versions.one.stderr
@@ -0,0 +1,6 @@
+error: requested DWARF version 1 is not supported
+   |
+   = help: supported DWARF versions are 2, 3, 4 and 5
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/dwarf-versions.rs b/tests/ui/debuginfo/dwarf-versions.rs
new file mode 100644
index 00000000000..806ade51a99
--- /dev/null
+++ b/tests/ui/debuginfo/dwarf-versions.rs
@@ -0,0 +1,38 @@
+// This test verifies the expected behavior of various options passed to
+// `-Zdwarf-version`: 2 - 5 (valid) with all other options being invalid.
+
+//@ revisions: zero one two three four five six
+
+//@[zero] compile-flags: -Zdwarf-version=0
+//@[zero] error-pattern: requested DWARF version 0 is not supported
+
+//@[one] compile-flags: -Zdwarf-version=1
+//@[one] error-pattern: requested DWARF version 1 is not supported
+
+//@[two] compile-flags: -Zdwarf-version=2
+//@[two] check-pass
+
+//@[three] compile-flags: -Zdwarf-version=3
+//@[three] check-pass
+
+//@[four] compile-flags: -Zdwarf-version=4
+//@[four] check-pass
+
+//@[five] compile-flags: -Zdwarf-version=5
+//@[five] check-pass
+
+//@[six] compile-flags: -Zdwarf-version=6
+//@[six] error-pattern: requested DWARF version 6 is not supported
+
+//@ compile-flags: -g --target x86_64-unknown-linux-gnu --crate-type cdylib
+//@ needs-llvm-components: x86
+
+#![feature(no_core, lang_items)]
+
+#![no_core]
+#![no_std]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+pub fn foo() {}
diff --git a/tests/ui/debuginfo/dwarf-versions.six.stderr b/tests/ui/debuginfo/dwarf-versions.six.stderr
new file mode 100644
index 00000000000..32ab4e1471d
--- /dev/null
+++ b/tests/ui/debuginfo/dwarf-versions.six.stderr
@@ -0,0 +1,6 @@
+error: requested DWARF version 6 is not supported
+   |
+   = help: supported DWARF versions are 2, 3, 4 and 5
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/dwarf-versions.zero.stderr b/tests/ui/debuginfo/dwarf-versions.zero.stderr
new file mode 100644
index 00000000000..d58d7d3ed1c
--- /dev/null
+++ b/tests/ui/debuginfo/dwarf-versions.zero.stderr
@@ -0,0 +1,6 @@
+error: requested DWARF version 0 is not supported
+   |
+   = help: supported DWARF versions are 2, 3, 4 and 5
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/error-codes/E0060.stderr b/tests/ui/error-codes/E0060.stderr
index 8387b15b970..aadf1ea93cb 100644
--- a/tests/ui/error-codes/E0060.stderr
+++ b/tests/ui/error-codes/E0060.stderr
@@ -8,7 +8,7 @@ note: function defined here
   --> $DIR/E0060.rs:2:8
    |
 LL |     fn printf(_: *const u8, ...) -> u32;
-   |        ^^^^^^
+   |        ^^^^^^ -
 help: provide the argument
    |
 LL |     unsafe { printf(/* *const u8 */); }
diff --git a/tests/ui/fn/param-mismatch-foreign.rs b/tests/ui/fn/param-mismatch-foreign.rs
new file mode 100644
index 00000000000..2ab2bf95448
--- /dev/null
+++ b/tests/ui/fn/param-mismatch-foreign.rs
@@ -0,0 +1,11 @@
+extern "C" {
+    fn foo(x: i32, y: u32, z: i32);
+    //~^ NOTE function defined here
+}
+
+fn main() {
+    foo(1i32, 2i32);
+    //~^ ERROR this function takes 3 arguments but 2 arguments were supplied
+    //~| NOTE argument #2 of type `u32` is missing
+    //~| HELP provide the argument
+}
diff --git a/tests/ui/fn/param-mismatch-foreign.stderr b/tests/ui/fn/param-mismatch-foreign.stderr
new file mode 100644
index 00000000000..1182908891c
--- /dev/null
+++ b/tests/ui/fn/param-mismatch-foreign.stderr
@@ -0,0 +1,19 @@
+error[E0061]: this function takes 3 arguments but 2 arguments were supplied
+  --> $DIR/param-mismatch-foreign.rs:7:5
+   |
+LL |     foo(1i32, 2i32);
+   |     ^^^       ---- argument #2 of type `u32` is missing
+   |
+note: function defined here
+  --> $DIR/param-mismatch-foreign.rs:2:8
+   |
+LL |     fn foo(x: i32, y: u32, z: i32);
+   |        ^^^         -
+help: provide the argument
+   |
+LL |     foo(1i32, /* u32 */, 2i32);
+   |        ~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0061`.
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-outlives-2.rs b/tests/ui/impl-trait/precise-capturing/rpitit-outlives-2.rs
new file mode 100644
index 00000000000..6f7e1a0eaef
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/rpitit-outlives-2.rs
@@ -0,0 +1,19 @@
+//@ check-pass
+
+// Ensure that we skip uncaptured args from RPITITs when comptuing outlives.
+
+#![feature(precise_capturing_in_traits)]
+
+struct Invariant<T>(*mut T);
+
+trait Foo {
+    fn hello<'s: 's>(&'s self) -> Invariant<impl Sized + use<Self>>;
+}
+
+fn outlives_static(_: impl Sized + 'static) {}
+
+fn hello<'s, T: Foo + 'static>(x: &'s T) {
+    outlives_static(x.hello());
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-outlives.rs b/tests/ui/impl-trait/precise-capturing/rpitit-outlives.rs
new file mode 100644
index 00000000000..94d81d766f7
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/rpitit-outlives.rs
@@ -0,0 +1,18 @@
+//@ check-pass
+
+// Ensure that we skip uncaptured args from RPITITs when collecting the regions
+// to enforce member constraints in opaque type inference.
+
+#![feature(precise_capturing_in_traits)]
+
+struct Invariant<T>(*mut T);
+
+trait Foo {
+    fn hello<'s: 's>(&'s self) -> Invariant<impl Sized + use<Self>>;
+}
+
+fn hello<'s, T: Foo>(x: &'s T) -> Invariant<impl Sized> {
+    x.hello()
+}
+
+fn main() {}
diff --git a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs
index df73eddd8d5..0717a2d5a6c 100644
--- a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs
+++ b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs
@@ -18,9 +18,6 @@ pub static TEST4: bool = true;
 #[linkage = "linkonce_odr"]
 pub static TEST5: bool = true;
 
-#[linkage = "private"]
-pub static TEST6: bool = true;
-
 #[linkage = "weak"]
 pub static TEST7: bool = true;
 
diff --git a/tests/ui/lint/lint-overflowing-int-136675.rs b/tests/ui/lint/lint-overflowing-int-136675.rs
new file mode 100644
index 00000000000..616531519a6
--- /dev/null
+++ b/tests/ui/lint/lint-overflowing-int-136675.rs
@@ -0,0 +1,4 @@
+fn main() {
+    if let -129 = 0i8 {} //~ ERROR literal out of range for `i8`
+    let x: i8 = -129; //~ ERROR literal out of range for `i8`
+}
diff --git a/tests/ui/lint/lint-overflowing-int-136675.stderr b/tests/ui/lint/lint-overflowing-int-136675.stderr
new file mode 100644
index 00000000000..3b67c663ac2
--- /dev/null
+++ b/tests/ui/lint/lint-overflowing-int-136675.stderr
@@ -0,0 +1,21 @@
+error: literal out of range for `i8`
+  --> $DIR/lint-overflowing-int-136675.rs:2:12
+   |
+LL |     if let -129 = 0i8 {}
+   |            ^^^^
+   |
+   = note: the literal `-129` does not fit into the type `i8` whose range is `-128..=127`
+   = help: consider using the type `i16` instead
+   = note: `#[deny(overflowing_literals)]` on by default
+
+error: literal out of range for `i8`
+  --> $DIR/lint-overflowing-int-136675.rs:3:17
+   |
+LL |     let x: i8 = -129;
+   |                 ^^^^
+   |
+   = note: the literal `-129` does not fit into the type `i8` whose range is `-128..=127`
+   = help: consider using the type `i16` instead
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/mir/null/borrowed_mut_null.rs b/tests/ui/mir/null/borrowed_mut_null.rs
index 437955c452b..d26452b9dac 100644
--- a/tests/ui/mir/null/borrowed_mut_null.rs
+++ b/tests/ui/mir/null/borrowed_mut_null.rs
@@ -1,6 +1,6 @@
 //@ run-fail
 //@ compile-flags: -C debug-assertions
-//@ error-pattern: null pointer dereference occured
+//@ error-pattern: null pointer dereference occurred
 
 fn main() {
     let ptr: *mut u32 = std::ptr::null_mut();
diff --git a/tests/ui/mir/null/borrowed_null.rs b/tests/ui/mir/null/borrowed_null.rs
index eb0794efaa5..fefac3a7212 100644
--- a/tests/ui/mir/null/borrowed_null.rs
+++ b/tests/ui/mir/null/borrowed_null.rs
@@ -1,6 +1,6 @@
 //@ run-fail
 //@ compile-flags: -C debug-assertions
-//@ error-pattern: null pointer dereference occured
+//@ error-pattern: null pointer dereference occurred
 
 fn main() {
     let ptr: *const u32 = std::ptr::null();
diff --git a/tests/ui/mir/null/borrowed_null_zst.rs b/tests/ui/mir/null/borrowed_null_zst.rs
new file mode 100644
index 00000000000..835727c068b
--- /dev/null
+++ b/tests/ui/mir/null/borrowed_null_zst.rs
@@ -0,0 +1,8 @@
+//@ run-fail
+//@ compile-flags: -C debug-assertions
+//@ error-pattern: null pointer dereference occurred
+
+fn main() {
+    let ptr: *const () = std::ptr::null();
+    let _ptr: &() = unsafe { &*ptr };
+}
diff --git a/tests/ui/mir/null/null_lhs.rs b/tests/ui/mir/null/null_lhs.rs
index fd3bc3a78b8..238d350d1bd 100644
--- a/tests/ui/mir/null/null_lhs.rs
+++ b/tests/ui/mir/null/null_lhs.rs
@@ -1,6 +1,6 @@
 //@ run-fail
 //@ compile-flags: -C debug-assertions
-//@ error-pattern: null pointer dereference occured
+//@ error-pattern: null pointer dereference occurred
 
 fn main() {
     let ptr: *mut u32 = std::ptr::null_mut();
diff --git a/tests/ui/mir/null/null_rhs.rs b/tests/ui/mir/null/null_rhs.rs
index 45c8beb3fe8..18eafb61869 100644
--- a/tests/ui/mir/null/null_rhs.rs
+++ b/tests/ui/mir/null/null_rhs.rs
@@ -1,6 +1,6 @@
 //@ run-fail
 //@ compile-flags: -C debug-assertions
-//@ error-pattern: null pointer dereference occured
+//@ error-pattern: null pointer dereference occurred
 
 fn main() {
     let ptr: *mut u32 = std::ptr::null_mut();
diff --git a/tests/ui/mir/null/place_without_read.rs b/tests/ui/mir/null/place_without_read.rs
index d6bfb089b01..a259053d22b 100644
--- a/tests/ui/mir/null/place_without_read.rs
+++ b/tests/ui/mir/null/place_without_read.rs
@@ -6,5 +6,6 @@ fn main() {
     let ptr: *const u16 = std::ptr::null();
     unsafe {
         let _ = *ptr;
+        let _ = &raw const *ptr;
     }
 }
diff --git a/tests/ui/mir/null/place_without_read_zst.rs b/tests/ui/mir/null/place_without_read_zst.rs
new file mode 100644
index 00000000000..c923ccea9a8
--- /dev/null
+++ b/tests/ui/mir/null/place_without_read_zst.rs
@@ -0,0 +1,11 @@
+// Make sure that we don't insert a check for places that do not read.
+//@ run-pass
+//@ compile-flags: -C debug-assertions
+
+fn main() {
+    let ptr: *const () = std::ptr::null();
+    unsafe {
+        let _ = *ptr;
+        let _ = &raw const *ptr;
+    }
+}
diff --git a/tests/ui/mir/null/two_pointers.rs b/tests/ui/mir/null/two_pointers.rs
index d9f0687fe0d..52b9510be12 100644
--- a/tests/ui/mir/null/two_pointers.rs
+++ b/tests/ui/mir/null/two_pointers.rs
@@ -1,6 +1,6 @@
 //@ run-fail
 //@ compile-flags: -C debug-assertions
-//@ error-pattern: null pointer dereference occured
+//@ error-pattern: null pointer dereference occurred
 
 fn main() {
     let ptr = std::ptr::null();
diff --git a/tests/ui/mismatched_types/issue-26480.stderr b/tests/ui/mismatched_types/issue-26480.stderr
index ae10a00671e..da8d73225f3 100644
--- a/tests/ui/mismatched_types/issue-26480.stderr
+++ b/tests/ui/mismatched_types/issue-26480.stderr
@@ -13,7 +13,7 @@ note: function defined here
   --> $DIR/issue-26480.rs:2:8
    |
 LL |     fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
-   |        ^^^^^
+   |        ^^^^^                              -----
    = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit
    |
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr
index 331b86736a0..1c446178308 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr
@@ -48,19 +48,19 @@ LL |     let &ref mut x = &0;
    |          ^^^^^^^^^ cannot borrow as mutable
 
 error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/borrowck-errors.rs:35:23
+  --> $DIR/borrowck-errors.rs:37:23
    |
 LL |     if let &Some(Some(x)) = &Some(&mut Some(0)) {
    |                       ^ cannot borrow as mutable
 
 error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/borrowck-errors.rs:40:11
+  --> $DIR/borrowck-errors.rs:42:11
    |
 LL |     let &[x] = &&mut [0];
    |           ^ cannot borrow as mutable
 
 error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array
-  --> $DIR/borrowck-errors.rs:44:20
+  --> $DIR/borrowck-errors.rs:46:20
    |
 LL |     let [&mut x] = &mut [&mut 0];
    |               -    ^^^^^^^^^^^^^ cannot move out of here
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs
index 3f5d9c8db5d..59cafc50d86 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs
@@ -32,6 +32,8 @@ pub fn main() {
     let &ref mut x = &0;
     //~^ cannot borrow data in a `&` reference as mutable [E0596]
 
+    // For 2021 edition, this is also a regression test for #136223
+    // since the maximum mutability is downgraded during the pattern check process.
     if let &Some(Some(x)) = &Some(&mut Some(0)) {
         //[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable
         let _: &u32 = x;
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr
index 65c98e2da9c..deefe21ca7d 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr
@@ -52,13 +52,13 @@ LL |     let &ref mut x = &0;
    |          ^^^^^^^^^ cannot borrow as mutable
 
 error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/borrowck-errors.rs:35:23
+  --> $DIR/borrowck-errors.rs:37:23
    |
 LL |     if let &Some(Some(x)) = &Some(&mut Some(0)) {
    |                       ^ cannot borrow as mutable
 
 error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/borrowck-errors.rs:40:11
+  --> $DIR/borrowck-errors.rs:42:11
    |
 LL |     let &[x] = &&mut [0];
    |           ^ cannot borrow as mutable
diff --git a/tests/ui/process/win-creation-flags.rs b/tests/ui/process/win-creation-flags.rs
new file mode 100644
index 00000000000..0c7c6883d68
--- /dev/null
+++ b/tests/ui/process/win-creation-flags.rs
@@ -0,0 +1,51 @@
+// Test that windows `creation_flags` extension to `Command` works.
+
+//@ run-pass
+//@ only-windows
+//@ needs-subprocess
+
+use std::env;
+use std::os::windows::process::CommandExt;
+use std::process::{Command, exit};
+
+fn main() {
+    if env::args().skip(1).any(|s| s == "--child") {
+        child();
+    } else {
+        parent();
+    }
+}
+
+fn parent() {
+    let exe = env::current_exe().unwrap();
+
+    // Use the DETACH_PROCESS to create a subprocess that isn't attached to the console.
+    // The subprocess's exit status will be 0 if it's detached.
+    let status = Command::new(&exe)
+        .arg("--child")
+        .creation_flags(DETACH_PROCESS)
+        .spawn()
+        .unwrap()
+        .wait()
+        .unwrap();
+    assert_eq!(status.code(), Some(0));
+
+    // Try without DETACH_PROCESS to ensure this test works.
+    let status = Command::new(&exe).arg("--child").spawn().unwrap().wait().unwrap();
+    assert_eq!(status.code(), Some(1));
+}
+
+// exits with 1 if the console is attached or 0 otherwise
+fn child() {
+    // Get the attached console's code page.
+    // This will fail (return 0) if no console is attached.
+    let has_console = GetConsoleCP() != 0;
+    exit(has_console as i32);
+}
+
+// Windows API definitions.
+const DETACH_PROCESS: u32 = 0x00000008;
+#[link(name = "kernel32")]
+unsafe extern "system" {
+    safe fn GetConsoleCP() -> u32;
+}
diff --git a/tests/ui/process/win-proc-thread-attributes.rs b/tests/ui/process/win-proc-thread-attributes.rs
new file mode 100644
index 00000000000..91bb0b17e95
--- /dev/null
+++ b/tests/ui/process/win-proc-thread-attributes.rs
@@ -0,0 +1,118 @@
+// Tests proc thread attributes by spawning a process with a custom parent process,
+// then comparing the parent process ID with the expected parent process ID.
+
+//@ run-pass
+//@ only-windows
+//@ needs-subprocess
+//@ edition: 2021
+
+#![feature(windows_process_extensions_raw_attribute)]
+
+use std::os::windows::io::AsRawHandle;
+use std::os::windows::process::{CommandExt, ProcThreadAttributeList};
+use std::process::{Child, Command};
+use std::{env, mem, ptr, thread, time};
+
+// Make a best effort to ensure child processes always exit.
+struct ProcessDropGuard(Child);
+impl Drop for ProcessDropGuard {
+    fn drop(&mut self) {
+        let _ = self.0.kill();
+    }
+}
+
+fn main() {
+    if env::args().skip(1).any(|s| s == "--child") {
+        child();
+    } else {
+        parent();
+    }
+}
+
+fn parent() {
+    let exe = env::current_exe().unwrap();
+
+    let (fake_parent_id, child_parent_id) = {
+        // Create a process to be our fake parent process.
+        let fake_parent = Command::new(&exe).arg("--child").spawn().unwrap();
+        let fake_parent = ProcessDropGuard(fake_parent);
+        let parent_handle = fake_parent.0.as_raw_handle();
+
+        // Create another process with the parent process set to the fake.
+        let mut attribute_list = ProcThreadAttributeList::build()
+            .attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parent_handle)
+            .finish()
+            .unwrap();
+        let child =
+            Command::new(&exe).arg("--child").spawn_with_attributes(&mut attribute_list).unwrap();
+        let child = ProcessDropGuard(child);
+
+        // Return the fake's process id and the child's parent's id.
+        (process_info(&fake_parent.0).process_id(), process_info(&child.0).parent_id())
+    };
+
+    assert_eq!(fake_parent_id, child_parent_id);
+}
+
+// A process that stays running until killed.
+fn child() {
+    // Don't wait forever if something goes wrong.
+    thread::sleep(time::Duration::from_secs(60));
+}
+
+fn process_info(child: &Child) -> PROCESS_BASIC_INFORMATION {
+    unsafe {
+        let mut info: PROCESS_BASIC_INFORMATION = mem::zeroed();
+        let result = NtQueryInformationProcess(
+            child.as_raw_handle(),
+            ProcessBasicInformation,
+            ptr::from_mut(&mut info).cast(),
+            mem::size_of_val(&info).try_into().unwrap(),
+            ptr::null_mut(),
+        );
+        assert_eq!(result, 0);
+        info
+    }
+}
+
+// Windows API
+mod winapi {
+    #![allow(nonstandard_style)]
+    use std::ffi::c_void;
+
+    pub type HANDLE = *mut c_void;
+    type NTSTATUS = i32;
+    type PROCESSINFOCLASS = i32;
+
+    pub const ProcessBasicInformation: i32 = 0;
+    pub const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: usize = 0x00020000;
+    #[repr(C)]
+    pub struct PROCESS_BASIC_INFORMATION {
+        pub ExitStatus: NTSTATUS,
+        pub PebBaseAddress: *mut (),
+        pub AffinityMask: usize,
+        pub BasePriority: i32,
+        pub UniqueProcessId: usize,
+        pub InheritedFromUniqueProcessId: usize,
+    }
+    impl PROCESS_BASIC_INFORMATION {
+        pub fn parent_id(&self) -> usize {
+            self.InheritedFromUniqueProcessId
+        }
+        pub fn process_id(&self) -> usize {
+            self.UniqueProcessId
+        }
+    }
+
+    #[link(name = "ntdll")]
+    extern "system" {
+        pub fn NtQueryInformationProcess(
+            ProcessHandle: HANDLE,
+            ProcessInformationClass: PROCESSINFOCLASS,
+            ProcessInformation: *mut c_void,
+            ProcessInformationLength: u32,
+            ReturnLength: *mut u32,
+        ) -> NTSTATUS;
+    }
+}
+use winapi::*;
diff --git a/tests/ui/self/arbitrary_self_types_dispatch_to_vtable.rs b/tests/ui/self/arbitrary_self_types_dispatch_to_vtable.rs
new file mode 100644
index 00000000000..f9e346ea11e
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_dispatch_to_vtable.rs
@@ -0,0 +1,33 @@
+//@ check-pass
+
+#![feature(derive_coerce_pointee)]
+#![feature(arbitrary_self_types)]
+
+use std::marker::CoercePointee;
+use std::ops::Receiver;
+
+// `CoercePointee` isn't needed here, it's just a simpler
+// (and more conceptual) way of deriving `DispatchFromDyn`.
+// You could think of `MyDispatcher` as a smart pointer
+// that just doesn't deref to its target type.
+#[derive(CoercePointee)]
+#[repr(transparent)]
+struct MyDispatcher<T: ?Sized>(*const T);
+
+impl<T: ?Sized> Receiver for MyDispatcher<T> {
+    type Target = T;
+}
+struct Test;
+
+trait Trait {
+    fn test(self: MyDispatcher<Self>);
+}
+
+impl Trait for Test {
+    fn test(self: MyDispatcher<Self>) {
+        todo!()
+    }
+}
+fn main() {
+    MyDispatcher::<dyn Trait>(core::ptr::null_mut::<Test>()).test();
+}
diff --git a/tests/ui/suggestions/suggest-null-ptr.stderr b/tests/ui/suggestions/suggest-null-ptr.stderr
index 66a79d0749e..a811d6d19c7 100644
--- a/tests/ui/suggestions/suggest-null-ptr.stderr
+++ b/tests/ui/suggestions/suggest-null-ptr.stderr
@@ -12,7 +12,7 @@ note: function defined here
   --> $DIR/suggest-null-ptr.rs:7:8
    |
 LL |     fn foo(ptr: *const u8);
-   |        ^^^
+   |        ^^^ ---
 help: if you meant to create a null pointer, use `std::ptr::null()`
    |
 LL |         foo(std::ptr::null());
@@ -32,7 +32,7 @@ note: function defined here
   --> $DIR/suggest-null-ptr.rs:9:8
    |
 LL |     fn foo_mut(ptr: *mut u8);
-   |        ^^^^^^^
+   |        ^^^^^^^ ---
 help: if you meant to create a null pointer, use `std::ptr::null_mut()`
    |
 LL |         foo_mut(std::ptr::null_mut());
@@ -52,7 +52,7 @@ note: function defined here
   --> $DIR/suggest-null-ptr.rs:11:8
    |
 LL |     fn usize(ptr: *const usize);
-   |        ^^^^^
+   |        ^^^^^ ---
 help: if you meant to create a null pointer, use `std::ptr::null()`
    |
 LL |         usize(std::ptr::null());
@@ -72,7 +72,7 @@ note: function defined here
   --> $DIR/suggest-null-ptr.rs:13:8
    |
 LL |     fn usize_mut(ptr: *mut usize);
-   |        ^^^^^^^^^
+   |        ^^^^^^^^^ ---
 help: if you meant to create a null pointer, use `std::ptr::null_mut()`
    |
 LL |         usize_mut(std::ptr::null_mut());
diff --git a/tests/ui/wait-forked-but-failed-child.rs b/tests/ui/wait-forked-but-failed-child.rs
index 04f1c1a65d5..4a7f2bee9d9 100644
--- a/tests/ui/wait-forked-but-failed-child.rs
+++ b/tests/ui/wait-forked-but-failed-child.rs
@@ -31,8 +31,17 @@ fn find_zombies() {
     // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
     let ps_cmd_output = Command::new("ps").args(&["-A", "-o", "pid,ppid,args"]).output().unwrap();
     let ps_output = String::from_utf8_lossy(&ps_cmd_output.stdout);
+    // On AIX, the PPID is not always present, such as when a process is blocked
+    // (marked as <exiting>), or if a process is idle. In these situations,
+    // the PPID column contains a "-" for the respective process.
+    // Filter out any lines that have a "-" as the PPID as the PPID is
+    // expected to be an integer.
+    let filtered_ps: Vec<_> = ps_output
+        .lines()
+        .filter(|line| line.split_whitespace().nth(1) != Some("-"))
+        .collect();
 
-    for (line_no, line) in ps_output.split('\n').enumerate() {
+    for (line_no, line) in filtered_ps.into_iter().enumerate() {
         if 0 < line_no && 0 < line.len() &&
            my_pid == line.split(' ').filter(|w| 0 < w.len()).nth(1)
                          .expect("1st column should be PPID")
diff --git a/triagebot.toml b/triagebot.toml
index 3caf4e9fb1e..efd694994f9 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -394,7 +394,6 @@ trigger_files = [
     "src/tools/tidy",
     "src/tools/rustdoc-gui-test",
     "src/tools/libcxx-version",
-    "src/tools/rustc-perf-wrapper",
     "x.py",
     "x",
     "x.ps1"
@@ -1058,7 +1057,6 @@ branch = "stable"
 [assign.adhoc_groups]
 compiler = [
     "@BoxyUwU",
-    "@chenyukang",
     "@cjgillot",
     "@compiler-errors",
     "@davidtwco",