about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.mailmap1
-rw-r--r--Cargo.lock78
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_passes/messages.ftl4
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs47
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs20
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs8
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs82
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs16
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs4
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/abi_test.rs2
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/fuzz.rs8
-rw-r--r--compiler/rustc_codegen_gcc/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch23
-rw-r--r--compiler/rustc_codegen_gcc/rust-toolchain2
-rw-r--r--compiler/rustc_codegen_gcc/src/allocator.rs14
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs26
-rw-r--r--compiler/rustc_codegen_gcc/src/int.rs76
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/archs.rs60
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs9
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs81
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs5
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt2
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt1
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt8
-rw-r--r--compiler/rustc_codegen_gcc/tools/cspell_dicts/rustc_codegen_gcc.txt3
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs47
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs29
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs25
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs22
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs35
-rw-r--r--compiler/rustc_const_eval/src/interpret/visitor.rs15
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_const_eval/src/util/caller_location.rs10
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs24
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0562.md9
-rw-r--r--compiler/rustc_errors/src/emitter.rs135
-rw-r--r--compiler/rustc_errors/src/lib.rs11
-rw-r--r--compiler/rustc_expand/src/expand.rs3
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs5
-rw-r--r--compiler/rustc_feature/src/removed.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/attrs/data_structures.rs3
-rw-r--r--compiler/rustc_hir/src/attrs/encode_cross_crate.rs1
-rw-r--r--compiler/rustc_hir/src/def.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs25
-rw-r--r--compiler/rustc_hir/src/intravisit.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/loops.rs50
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs30
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs21
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs4
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs6
-rw-r--r--compiler/rustc_infer/src/infer/canonical/instantiate.rs4
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs6
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/higher_ranked.rs4
-rw-r--r--compiler/rustc_interface/src/passes.rs4
-rw-r--r--compiler/rustc_interface/src/tests.rs4
-rw-r--r--compiler/rustc_lint/messages.ftl6
-rw-r--r--compiler/rustc_lint/src/context.rs23
-rw-r--r--compiler/rustc_lint/src/dangling.rs150
-rw-r--r--compiler/rustc_lint/src/lints.rs16
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map.rs12
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs68
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs41
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs3
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs40
-rw-r--r--compiler/rustc_middle/src/query/mod.rs12
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs14
-rw-r--r--compiler/rustc_middle/src/ty/context.rs4
-rw-r--r--compiler/rustc_middle/src/ty/error.rs24
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs24
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs29
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs6
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs23
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs44
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs912
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs60
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs8
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs6
-rw-r--r--compiler/rustc_mir_build/messages.ftl2
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_operand.rs4
-rw-r--r--compiler/rustc_mir_build/src/check_tail_calls.rs71
-rw-r--r--compiler/rustc_mir_build/src/errors.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/initialized.rs3
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mappings.rs20
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs14
-rw-r--r--compiler/rustc_mir_transform/src/ctfe_limit.rs2
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drop.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs33
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs20
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs19
-rw-r--r--compiler/rustc_passes/src/check_attr.rs3
-rw-r--r--compiler/rustc_passes/src/dead.rs467
-rw-r--r--compiler/rustc_passes/src/lib.rs1
-rw-r--r--compiler/rustc_privacy/src/lib.rs244
-rw-r--r--compiler/rustc_resolve/Cargo.toml1
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs42
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs29
-rw-r--r--compiler/rustc_resolve/src/errors.rs52
-rw-r--r--compiler/rustc_resolve/src/late.rs10
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs22
-rw-r--r--compiler/rustc_resolve/src/lib.rs72
-rw-r--r--compiler/rustc_session/src/config.rs9
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_session/src/session.rs17
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs65
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs86
-rw-r--r--compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_thread_pool/src/scope/mod.rs6
-rw-r--r--compiler/rustc_thread_pool/src/sleep/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs51
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs6
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs6
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs9
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs64
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs4
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs43
-rw-r--r--compiler/rustc_type_ir/src/binder.rs25
-rw-r--r--compiler/rustc_type_ir/src/flags.rs11
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs2
-rw-r--r--compiler/rustc_type_ir/src/lib.rs10
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs26
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs2
-rw-r--r--compiler/rustc_type_ir/src/ty_kind/closure.rs27
-rw-r--r--library/Cargo.lock23
-rw-r--r--library/alloc/src/string.rs4
-rw-r--r--library/alloc/src/vec/mod.rs10
-rw-r--r--library/core/src/array/equality.rs28
-rw-r--r--library/core/src/cell.rs6
-rw-r--r--library/core/src/cell/lazy.rs61
-rw-r--r--library/core/src/hint.rs2
-rw-r--r--library/core/src/iter/mod.rs6
-rw-r--r--library/core/src/iter/traits/iterator.rs2
-rw-r--r--library/core/src/macros/mod.rs10
-rw-r--r--library/core/src/marker.rs3
-rw-r--r--library/core/src/mem/maybe_uninit.rs21
-rw-r--r--library/core/src/num/niche_types.rs6
-rw-r--r--library/core/src/primitive_docs.rs2
-rw-r--r--library/core/src/ptr/alignment.rs8
-rw-r--r--library/core/src/result.rs139
-rw-r--r--library/core/src/slice/mod.rs3
-rw-r--r--library/coretests/tests/lib.rs2
-rw-r--r--library/coretests/tests/result.rs83
-rw-r--r--library/panic_abort/Cargo.toml3
-rw-r--r--library/panic_unwind/Cargo.toml5
-rw-r--r--library/rustc-std-workspace-core/README.md6
-rw-r--r--library/std/Cargo.toml1
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/macros.rs74
-rw-r--r--library/std/src/panic.rs2
-rw-r--r--library/std/src/panicking.rs14
-rw-r--r--library/std/src/path.rs5
-rw-r--r--library/std/src/sync/lazy_lock.rs60
-rw-r--r--library/std/src/sync/once_lock.rs2
-rw-r--r--library/std/src/sync/poison.rs24
-rw-r--r--library/std/src/sync/poison/mutex.rs70
-rw-r--r--library/std/src/sync/poison/once.rs6
-rw-r--r--library/std/src/sync/poison/rwlock.rs10
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs22
-rw-r--r--library/std/src/thread/mod.rs3
-rw-r--r--library/unwind/Cargo.toml3
-rw-r--r--src/bootstrap/src/bin/main.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs19
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs81
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs129
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs16
-rw-r--r--src/bootstrap/src/core/build_steps/install.rs14
-rw-r--r--src/bootstrap/src/core/build_steps/perf.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs14
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs268
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs399
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs6
-rw-r--r--src/bootstrap/src/core/builder/mod.rs79
-rw-r--r--src/bootstrap/src/core/builder/tests.rs334
-rw-r--r--src/bootstrap/src/core/config/config.rs12
-rw-r--r--src/bootstrap/src/core/config/toml/rust.rs27
-rw-r--r--src/bootstrap/src/core/config/toml/target.rs8
-rw-r--r--src/bootstrap/src/lib.rs72
-rw-r--r--src/bootstrap/src/utils/build_stamp.rs6
-rw-r--r--src/bootstrap/src/utils/mod.rs3
-rw-r--r--src/bootstrap/src/utils/step_graph.rs182
-rw-r--r--src/doc/rustc-dev-guide/.github/workflows/ci.yml4
-rw-r--r--src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml3
-rw-r--r--src/doc/rustc-dev-guide/README.md6
-rw-r--r--src/doc/rustc-dev-guide/book.toml11
-rw-r--r--src/doc/rustc-dev-guide/pagetoc.css84
-rw-r--r--src/doc/rustc-dev-guide/pagetoc.js104
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md1
-rw-r--r--src/doc/rustc-dev-guide/src/appendix/humorust.md2
-rw-r--r--src/doc/rustc-dev-guide/src/asm.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/backend-agnostic.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/monomorph.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/updating-llvm.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md2
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md2
-rw-r--r--src/doc/rustc-dev-guide/src/bug-fix-procedure.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md6
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/new-target.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/optimized-build.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md2
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-debugging.md2
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-src.md2
-rw-r--r--src/doc/rustc-dev-guide/src/const-eval/interpret.md2
-rw-r--r--src/doc/rustc-dev-guide/src/contributing.md2
-rw-r--r--src/doc/rustc-dev-guide/src/coroutine-closures.md2
-rw-r--r--src/doc/rustc-dev-guide/src/crates-io.md2
-rw-r--r--src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md2
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics.md2
-rw-r--r--src/doc/rustc-dev-guide/src/early_late_parameters.md2
-rw-r--r--src/doc/rustc-dev-guide/src/getting-started.md2
-rw-r--r--src/doc/rustc-dev-guide/src/git.md2
-rw-r--r--src/doc/rustc-dev-guide/src/guides/editions.md2
-rw-r--r--src/doc/rustc-dev-guide/src/hir.md2
-rw-r--r--src/doc/rustc-dev-guide/src/implementing_new_features.md2
-rw-r--r--src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/macro-expansion.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/construction.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/dataflow.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/drop-elaboration.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/index.md2
-rw-r--r--src/doc/rustc-dev-guide/src/name-resolution.md2
-rw-r--r--src/doc/rustc-dev-guide/src/normalization.md2
-rw-r--r--src/doc/rustc-dev-guide/src/overview.md2
-rw-r--r--src/doc/rustc-dev-guide/src/panic-implementation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/profile-guided-optimization.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/incremental-compilation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/salsa.md2
-rw-r--r--src/doc/rustc-dev-guide/src/query.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals/search.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc.md2
-rw-r--r--src/doc/rustc-dev-guide/src/solve/candidate-preference.md427
-rw-r--r--src/doc/rustc-dev-guide/src/stability.md2
-rw-r--r--src/doc/rustc-dev-guide/src/stabilization_guide.md2
-rw-r--r--src/doc/rustc-dev-guide/src/test-implementation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/adding.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/directives.md10
-rw-r--r--src/doc/rustc-dev-guide/src/tests/docker.md15
-rw-r--r--src/doc/rustc-dev-guide/src/tests/intro.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/running.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md10
-rw-r--r--src/doc/rustc-dev-guide/src/thir.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tracing.md2
-rw-r--r--src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md2
-rw-r--r--src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md2
-rw-r--r--src/doc/rustc-dev-guide/src/traits/resolution.md2
-rw-r--r--src/doc/rustc-dev-guide/src/ty.md2
-rw-r--r--src/doc/rustc-dev-guide/src/type-inference.md2
-rw-r--r--src/doc/rustc-dev-guide/src/typing_parameter_envs.md2
-rw-r--r--src/doc/rustc-dev-guide/src/variance.md2
-rw-r--r--src/doc/rustc-dev-guide/src/walkthrough.md2
-rw-r--r--src/doc/rustc-dev-guide/triagebot.toml3
-rw-r--r--src/doc/rustc/src/platform-support/lynxos178.md2
-rw-r--r--src/librustdoc/clean/cfg.rs1
-rw-r--r--src/librustdoc/clean/types.rs6
-rw-r--r--src/librustdoc/html/format.rs25
-rw-r--r--src/librustdoc/html/layout.rs29
-rw-r--r--src/librustdoc/html/layout/tests.rs24
-rw-r--r--src/librustdoc/html/templates/page.html2
-rw-r--r--src/librustdoc/json/conversions.rs8
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs32
-rw-r--r--src/rustdoc-json-types/lib.rs7
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_str_case_mismatch.stderr2
-rw-r--r--src/tools/compiletest/src/common.rs35
-rw-r--r--src/tools/compiletest/src/directives.rs10
-rw-r--r--src/tools/compiletest/src/directives/directive_names.rs1
-rw-r--r--src/tools/compiletest/src/directives/tests.rs18
-rw-r--r--src/tools/compiletest/src/lib.rs7
-rw-r--r--src/tools/compiletest/src/runtest.rs114
-rw-r--r--src/tools/compiletest/src/runtest/debuginfo.rs4
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc.rs4
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc_json.rs4
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr2
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/abort_unwind.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/double_panic.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort1.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort2.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort3.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort4.stderr2
-rw-r--r--src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr2
-rw-r--r--src/tools/miri/tests/fail/terminate-terminator.stderr2
-rw-r--r--src/tools/miri/tests/fail/unwind-action-terminate.stderr2
-rw-r--r--src/tools/miri/tests/fail/validity/dangling_ref3.rs3
-rw-r--r--src/tools/miri/tests/pass/fn_align.rs25
-rw-r--r--src/tools/run-make-support/src/artifact_names.rs2
-rw-r--r--src/tools/rust-analyzer/.github/workflows/rustc-pull.yml3
-rw-r--r--src/tools/rust-analyzer/Cargo.lock116
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/lib.rs3
-rw-r--r--src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/attr.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs39
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/find_path.rs72
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs23
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs64
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs154
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs94
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs13
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/files.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs22
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/builder.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs64
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs123
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs25
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs47
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs37
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs154
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs46
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs75
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs119
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs31
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs120
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs38
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs73
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs76
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs11
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs60
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs49
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/traits.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/diagnostics.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs80
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs93
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs83
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/term_search.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs24
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs23
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs57
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs59
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs169
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs130
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs101
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs81
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs42
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs15
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs58
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs86
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs51
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs87
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs49
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs95
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs24
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs40
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs22
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs105
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions.rs17
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs92
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs17
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs153
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs140
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/item.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/lib.rs14
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs108
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs34
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/defs.rs64
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/helpers.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs45
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs100
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/rename.rs22
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs100
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs23
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs50
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs24
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs14
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs54
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs25
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs101
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs61
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/search.rs27
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/annotations.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/extend_selection.rs54
-rwxr-xr-xsrc/tools/rust-analyzer/crates/ide/src/folding_ranges.rs88
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/highlight_related.rs45
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs116
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs42
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs43
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs50
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/join_lines.rs26
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/parent_module.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/rename.rs178
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/runnables.rs34
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/signature_help.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs39
-rw-r--r--src/tools/rust-analyzer/crates/load-cargo/src/lib.rs10
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/benchmark.rs32
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs12
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs69
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/input.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/shortcuts.rs8
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs172
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs25
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs105
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs93
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs126
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv-cli/build.rs48
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs56
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs74
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/version.rs58
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs215
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs (renamed from src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs)23
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs71
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs53
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs16
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs18
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs12
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs111
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/progress_report.rs10
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs624
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs24
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs14
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs11
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs32
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs37
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs150
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs64
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs14
-rw-r--r--src/tools/rust-analyzer/crates/span/src/lib.rs12
-rw-r--r--src/tools/rust-analyzer/crates/span/src/map.rs14
-rw-r--r--src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs22
-rw-r--r--src/tools/rust-analyzer/crates/syntax-bridge/src/prettify_macro_expansion.rs9
-rw-r--r--src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs9
-rw-r--r--src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs20
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs24
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs196
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs4
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs24
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs18
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs18
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs26
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ted.rs42
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/validation.rs92
-rw-r--r--src/tools/rust-analyzer/crates/test-fixture/src/lib.rs12
-rw-r--r--src/tools/rust-analyzer/crates/tt/src/lib.rs16
-rw-r--r--src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs85
-rw-r--r--src/tools/rust-analyzer/docs/book/src/configuration_generated.md303
-rw-r--r--src/tools/rust-analyzer/docs/book/src/contributing/style.md14
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json645
-rw-r--r--src/tools/rust-analyzer/triagebot.toml3
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen.rs10
-rw-r--r--src/tools/rust-analyzer/xtask/src/publish/notes.rs138
-rw-r--r--src/tools/rustbook/Cargo.lock27
-rw-r--r--src/tools/tidy/src/ui_tests.rs278
-rw-r--r--src/version2
-rw-r--r--tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs31
-rw-r--r--tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs14
-rw-r--r--tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs28
-rw-r--r--tests/codegen-llvm/bounds-check-elision-slice-min.rs19
-rw-r--r--tests/codegen-llvm/simd/extract-insert-dyn.rs27
-rw-r--r--tests/coverage/branch/no-mir-spans.cov-map63
-rw-r--r--tests/coverage/branch/no-mir-spans.coverage77
-rw-r--r--tests/coverage/branch/no-mir-spans.rs62
-rw-r--r--tests/debuginfo/associated-types.rs3
-rw-r--r--tests/debuginfo/auxiliary/cross_crate_spans.rs2
-rw-r--r--tests/debuginfo/basic-stepping.rs47
-rw-r--r--tests/debuginfo/basic-types-globals-metadata.rs3
-rw-r--r--tests/debuginfo/basic-types-globals.rs3
-rw-r--r--tests/debuginfo/basic-types-metadata.rs3
-rw-r--r--tests/debuginfo/basic-types-mut-globals.rs3
-rw-r--r--tests/debuginfo/basic-types.rs3
-rw-r--r--tests/debuginfo/borrowed-basic.rs3
-rw-r--r--tests/debuginfo/borrowed-c-style-enum.rs3
-rw-r--r--tests/debuginfo/borrowed-enum.rs3
-rw-r--r--tests/debuginfo/borrowed-struct.rs3
-rw-r--r--tests/debuginfo/borrowed-tuple.rs3
-rw-r--r--tests/debuginfo/borrowed-unique-basic.rs3
-rw-r--r--tests/debuginfo/box.rs3
-rw-r--r--tests/debuginfo/boxed-struct.rs3
-rw-r--r--tests/debuginfo/by-value-non-immediate-argument.rs4
-rw-r--r--tests/debuginfo/by-value-self-argument-in-trait-impl.rs4
-rw-r--r--tests/debuginfo/c-style-enum-in-composite.rs3
-rw-r--r--tests/debuginfo/c-style-enum.rs3
-rw-r--r--tests/debuginfo/closure-in-generic-function.rs4
-rw-r--r--tests/debuginfo/constant-debug-locs.rs3
-rw-r--r--tests/debuginfo/constant-in-match-pattern.rs3
-rw-r--r--tests/debuginfo/coroutine-locals.rs4
-rw-r--r--tests/debuginfo/coroutine-objects.rs4
-rw-r--r--tests/debuginfo/cross-crate-spans.rs8
-rw-r--r--tests/debuginfo/destructured-fn-argument.rs3
-rw-r--r--tests/debuginfo/destructured-for-loop-variable.rs3
-rw-r--r--tests/debuginfo/destructured-local.rs3
-rw-r--r--tests/debuginfo/enum-thinlto.rs3
-rw-r--r--tests/debuginfo/evec-in-struct.rs3
-rw-r--r--tests/debuginfo/extern-c-fn.rs4
-rw-r--r--tests/debuginfo/function-arg-initialization.rs3
-rw-r--r--tests/debuginfo/function-arguments.rs5
-rw-r--r--tests/debuginfo/function-names.rs3
-rw-r--r--tests/debuginfo/function-prologue-stepping-regular.rs3
-rw-r--r--tests/debuginfo/gdb-char.rs3
-rw-r--r--tests/debuginfo/generic-enum-with-different-disr-sizes.rs3
-rw-r--r--tests/debuginfo/generic-function.rs4
-rw-r--r--tests/debuginfo/generic-functions-nested.rs5
-rw-r--r--tests/debuginfo/generic-method-on-generic-struct.rs4
-rw-r--r--tests/debuginfo/generic-static-method-on-struct-and-enum.rs4
-rw-r--r--tests/debuginfo/generic-struct-style-enum.rs4
-rw-r--r--tests/debuginfo/generic-struct.rs4
-rw-r--r--tests/debuginfo/generic-tuple-style-enum.rs3
-rw-r--r--tests/debuginfo/include_string.rs3
-rw-r--r--tests/debuginfo/issue-12886.rs5
-rw-r--r--tests/debuginfo/issue-22656.rs3
-rw-r--r--tests/debuginfo/issue-57822.rs4
-rw-r--r--tests/debuginfo/lexical-scope-in-for-loop.rs4
-rw-r--r--tests/debuginfo/lexical-scope-in-if.rs4
-rw-r--r--tests/debuginfo/lexical-scope-in-match.rs4
-rw-r--r--tests/debuginfo/lexical-scope-in-stack-closure.rs4
-rw-r--r--tests/debuginfo/lexical-scope-in-unconditional-loop.rs4
-rw-r--r--tests/debuginfo/lexical-scope-in-unique-closure.rs4
-rw-r--r--tests/debuginfo/lexical-scope-in-while.rs4
-rw-r--r--tests/debuginfo/lexical-scope-with-macro.rs4
-rw-r--r--tests/debuginfo/lexical-scopes-in-block-expression.rs3
-rw-r--r--tests/debuginfo/limited-debuginfo.rs3
-rw-r--r--tests/debuginfo/method-on-enum.rs4
-rw-r--r--tests/debuginfo/method-on-generic-struct.rs4
-rw-r--r--tests/debuginfo/method-on-struct.rs4
-rw-r--r--tests/debuginfo/method-on-trait.rs4
-rw-r--r--tests/debuginfo/method-on-tuple-struct.rs4
-rw-r--r--tests/debuginfo/multi-cgu.rs4
-rw-r--r--tests/debuginfo/multiple-functions-equal-var-names.rs3
-rw-r--r--tests/debuginfo/multiple-functions.rs3
-rw-r--r--tests/debuginfo/name-shadowing-and-scope-nesting.rs4
-rw-r--r--tests/debuginfo/option-like-enum.rs4
-rw-r--r--tests/debuginfo/packed-struct-with-destructor.rs3
-rw-r--r--tests/debuginfo/packed-struct.rs3
-rw-r--r--tests/debuginfo/recursive-enum.rs3
-rw-r--r--tests/debuginfo/recursive-struct.rs3
-rw-r--r--tests/debuginfo/reference-debuginfo.rs3
-rw-r--r--tests/debuginfo/self-in-default-method.rs4
-rw-r--r--tests/debuginfo/self-in-generic-default-method.rs4
-rw-r--r--tests/debuginfo/shadowed-argument.rs4
-rw-r--r--tests/debuginfo/shadowed-variable.rs4
-rw-r--r--tests/debuginfo/simd.rs3
-rw-r--r--tests/debuginfo/simple-lexical-scope.rs4
-rw-r--r--tests/debuginfo/simple-struct.rs3
-rw-r--r--tests/debuginfo/simple-tuple.rs3
-rw-r--r--tests/debuginfo/static-method-on-struct-and-enum.rs4
-rw-r--r--tests/debuginfo/strings-and-strs.rs3
-rw-r--r--tests/debuginfo/struct-in-enum.rs3
-rw-r--r--tests/debuginfo/struct-in-struct.rs3
-rw-r--r--tests/debuginfo/struct-namespace.rs3
-rw-r--r--tests/debuginfo/struct-style-enum.rs3
-rw-r--r--tests/debuginfo/struct-with-destructor.rs3
-rw-r--r--tests/debuginfo/trait-pointers.rs3
-rw-r--r--tests/debuginfo/tuple-in-struct.rs3
-rw-r--r--tests/debuginfo/tuple-in-tuple.rs3
-rw-r--r--tests/debuginfo/tuple-struct.rs4
-rw-r--r--tests/debuginfo/tuple-style-enum.rs3
-rw-r--r--tests/debuginfo/type-names.rs3
-rw-r--r--tests/debuginfo/union-smoke.rs3
-rw-r--r--tests/debuginfo/unique-enum.rs3
-rw-r--r--tests/debuginfo/unreachable-locals.rs3
-rw-r--r--tests/debuginfo/unsized.rs4
-rw-r--r--tests/debuginfo/var-captured-in-nested-closure.rs3
-rw-r--r--tests/debuginfo/var-captured-in-sendable-closure.rs3
-rw-r--r--tests/debuginfo/var-captured-in-stack-closure.rs3
-rw-r--r--tests/debuginfo/vec-slices.rs3
-rw-r--r--tests/debuginfo/vec.rs3
-rw-r--r--tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir8
-rw-r--r--tests/mir-opt/building/custom/terminators.tail_call.built.after.mir2
-rw-r--r--tests/mir-opt/pre-codegen/derived_ord_debug.rs18
-rw-r--r--tests/mir-opt/pre-codegen/derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.panic-abort.mir52
-rw-r--r--tests/mir-opt/pre-codegen/derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.panic-unwind.mir52
-rw-r--r--tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.PreCodegen.after.panic-abort.mir42
-rw-r--r--tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.PreCodegen.after.panic-unwind.mir42
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir12
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir12
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir12
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir12
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.rs3
-rw-r--r--tests/mir-opt/pre-codegen/option_bubble_debug.option_direct.PreCodegen.after.panic-abort.mir37
-rw-r--r--tests/mir-opt/pre-codegen/option_bubble_debug.option_direct.PreCodegen.after.panic-unwind.mir37
-rw-r--r--tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.PreCodegen.after.panic-abort.mir47
-rw-r--r--tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.PreCodegen.after.panic-unwind.mir47
-rw-r--r--tests/mir-opt/pre-codegen/option_bubble_debug.rs29
-rw-r--r--tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff15
-rw-r--r--tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff26
-rw-r--r--tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff30
-rw-r--r--tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff15
-rw-r--r--tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff26
-rw-r--r--tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff30
-rw-r--r--tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff15
-rw-r--r--tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff26
-rw-r--r--tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff26
-rw-r--r--tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff15
-rw-r--r--tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff26
-rw-r--r--tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff26
-rw-r--r--tests/mir-opt/remove_unneeded_drops.rs40
-rw-r--r--tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff2
-rw-r--r--tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff2
-rw-r--r--tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir2
-rw-r--r--tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs43
-rw-r--r--tests/rustdoc-json/attrs/macro_export.rs40
-rw-r--r--tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs30
-rw-r--r--tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr122
-rw-r--r--tests/rustdoc-ui/intra-doc/bad-intra-doc.rs15
-rw-r--r--tests/rustdoc-ui/intra-doc/bad-intra-doc.stderr31
-rw-r--r--tests/rustdoc-ui/intra-doc/weird-syntax.rs2
-rw-r--r--tests/rustdoc-ui/intra-doc/weird-syntax.stderr10
-rw-r--r--tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs14
-rw-r--r--tests/rustdoc-ui/lints/redundant_explicit_links-utf8.stderr59
-rw-r--r--tests/rustdoc/attribute-rendering.rs6
-rw-r--r--tests/rustdoc/attributes-2021-edition.rs14
-rw-r--r--tests/rustdoc/attributes-re-export-2021-edition.rs13
-rw-r--r--tests/rustdoc/attributes-re-export.rs2
-rw-r--r--tests/rustdoc/attributes.rs13
-rw-r--r--tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs12
-rw-r--r--tests/rustdoc/reexport/reexport-attrs.rs6
-rw-r--r--tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs16
-rw-r--r--tests/ui/associated-consts/constant-trait-item-reference-selection-26095.rs (renamed from tests/ui/issues/issue-26095.rs)2
-rw-r--r--tests/ui/async-await/async-closures/def-path.stderr4
-rw-r--r--tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr26
-rw-r--r--tests/ui/async-await/issue-70818.rs1
-rw-r--r--tests/ui/async-await/issue-70818.stderr23
-rw-r--r--tests/ui/async-await/issue-86507.stderr2
-rw-r--r--tests/ui/attributes/cold-attribute-application-54044.rs (renamed from tests/ui/issues/issue-54044.rs)1
-rw-r--r--tests/ui/attributes/cold-attribute-application-54044.stderr (renamed from tests/ui/issues/issue-54044.stderr)6
-rw-r--r--tests/ui/attributes/malformed-attrs.rs4
-rw-r--r--tests/ui/attributes/malformed-attrs.stderr169
-rw-r--r--tests/ui/autoref-autoderef/autoderef-vec-box-fn-36786.rs (renamed from tests/ui/issues/issue-36786-resolve-call.rs)1
-rw-r--r--tests/ui/autoref-autoderef/deref-chain-method-calls-13264.rs (renamed from tests/ui/issues/issue-13264.rs)2
-rw-r--r--tests/ui/block-result/blocks-without-results-11709.rs (renamed from tests/ui/issues/issue-11709.rs)2
-rw-r--r--tests/ui/borrowck/borrow-checker-lifetime-error-46471.rs (renamed from tests/ui/issues/issue-46471-1.rs)1
-rw-r--r--tests/ui/borrowck/borrow-checker-lifetime-error-46471.stderr (renamed from tests/ui/issues/issue-46471-1.stderr)2
-rw-r--r--tests/ui/borrowck/moved-value-in-thread-loop-12041.rs (renamed from tests/ui/issues/issue-12041.rs)2
-rw-r--r--tests/ui/borrowck/moved-value-in-thread-loop-12041.stderr (renamed from tests/ui/issues/issue-12041.stderr)2
-rw-r--r--tests/ui/borrowck/refcell-borrow-comparison-12033.rs (renamed from tests/ui/issues/issue-12033.rs)2
-rw-r--r--tests/ui/borrowck/string-borrowing-pattern-matching-11869.rs (renamed from tests/ui/issues/issue-11869.rs)1
-rw-r--r--tests/ui/borrowck/string-literal-match-patterns-11869.rs18
-rw-r--r--tests/ui/cast/u8-to-char-cast-9918.rs (renamed from tests/ui/issues/issue-9918.rs)1
-rw-r--r--tests/ui/cfg/both-true-false.stderr16
-rw-r--r--tests/ui/cfg/cfg-version/syntax.stderr90
-rw-r--r--tests/ui/cfg/cmdline-false.stderr8
-rw-r--r--tests/ui/cfg/diagnostics-cross-crate.rs4
-rw-r--r--tests/ui/cfg/diagnostics-cross-crate.stderr34
-rw-r--r--tests/ui/cfg/diagnostics-reexport-2.stderr40
-rw-r--r--tests/ui/cfg/diagnostics-reexport.rs2
-rw-r--r--tests/ui/cfg/diagnostics-reexport.stderr28
-rw-r--r--tests/ui/cfg/diagnostics-same-crate.rs12
-rw-r--r--tests/ui/cfg/diagnostics-same-crate.stderr52
-rw-r--r--tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs5
-rw-r--r--tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr8
-rw-r--r--tests/ui/closures/fnonce-moved-twice-12127.rs (renamed from tests/ui/issues/issue-12127.rs)2
-rw-r--r--tests/ui/closures/fnonce-moved-twice-12127.stderr (renamed from tests/ui/issues/issue-12127.stderr)6
-rw-r--r--tests/ui/closures/moved-upvar-mut-rebind-11958.rs (renamed from tests/ui/issues/issue-11958.rs)2
-rw-r--r--tests/ui/closures/moved-upvar-mut-rebind-11958.stderr (renamed from tests/ui/issues/issue-11958.stderr)4
-rw-r--r--tests/ui/codegen/llvm-miscompile-metadata-invalidation-36023.rs (renamed from tests/ui/issues/issue-36023.rs)1
-rw-r--r--tests/ui/codegen/unsupported-static-initializer-in-const-array.rs18
-rw-r--r--tests/ui/coercion/any-trait-object-debug-12744.rs (renamed from tests/ui/issues/issue-12744.rs)2
-rw-r--r--tests/ui/coherence/impl-coherence-error-for-undefined-type-18058.rs (renamed from tests/ui/issues/issue-18058.rs)1
-rw-r--r--tests/ui/coherence/impl-coherence-error-for-undefined-type-18058.stderr (renamed from tests/ui/issues/issue-18058.stderr)2
-rw-r--r--tests/ui/collections/hashset-connected-border-12860.rs (renamed from tests/ui/issues/issue-12860.rs)2
-rw-r--r--tests/ui/conditional-compilation/test-cfg.rs4
-rw-r--r--tests/ui/conditional-compilation/test-cfg.stderr11
-rw-r--r--tests/ui/const-generics/trait-resolution-error-with-const-generics-77919.rs (renamed from tests/ui/issues/issue-77919.rs)1
-rw-r--r--tests/ui/const-generics/trait-resolution-error-with-const-generics-77919.stderr (renamed from tests/ui/issues/issue-77919.stderr)6
-rw-r--r--tests/ui/const-generics/vec-macro-in-static-array.rs (renamed from tests/ui/issues/issue-13446.rs)2
-rw-r--r--tests/ui/const-generics/vec-macro-in-static-array.stderr (renamed from tests/ui/issues/issue-13446.stderr)2
-rw-r--r--tests/ui/coroutine/clone-impl-async.rs6
-rw-r--r--tests/ui/coroutine/clone-impl-async.stderr132
-rw-r--r--tests/ui/coroutine/clone-impl-static.stderr12
-rw-r--r--tests/ui/coroutine/clone-impl.rs1
-rw-r--r--tests/ui/coroutine/clone-impl.stderr88
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-2.stderr4
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-3.stderr2
-rw-r--r--tests/ui/coroutine/ref-upvar-not-send.stderr14
-rw-r--r--tests/ui/drop/destructor-run-for-expression-4734.rs (renamed from tests/ui/issues/issue-4734.rs)1
-rw-r--r--tests/ui/error-codes/E0423.stderr2
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_ref.fixed26
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_ref.rs26
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_ref.stderr38
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_weird.rs29
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_weird.stderr26
-rw-r--r--tests/ui/explicit-tail-calls/infinite-recursion-in-ctfe.rs10
-rw-r--r--tests/ui/explicit-tail-calls/infinite-recursion-in-ctfe.stderr17
-rw-r--r--tests/ui/explicit-tail-calls/intrinsics.rs13
-rw-r--r--tests/ui/explicit-tail-calls/intrinsics.stderr14
-rw-r--r--tests/ui/extern/windows-tcb-trash-13259.rs49
-rw-r--r--tests/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.stderr12
-rw-r--r--tests/ui/fn/anonymous-parameters-trait-13105.rs (renamed from tests/ui/issues/issue-13105.rs)2
-rw-r--r--tests/ui/generics/unnecessary-path-disambiguator-36116.rs (renamed from tests/ui/issues/issue-36116.rs)1
-rw-r--r--tests/ui/impl-trait/issues/issue-55872-2.rs1
-rw-r--r--tests/ui/impl-trait/issues/issue-55872-2.stderr10
-rw-r--r--tests/ui/impl-trait/issues/issue-55872-3.rs1
-rw-r--r--tests/ui/impl-trait/issues/issue-55872-3.stderr17
-rw-r--r--tests/ui/inference/collection-type-copy-behavior-12909.rs (renamed from tests/ui/issues/issue-12909.rs)1
-rw-r--r--tests/ui/instrument-coverage/coverage-options.bad.stderr2
-rw-r--r--tests/ui/issues/auxiliary/issue-25185-2.rs3
-rw-r--r--tests/ui/issues/issue-13259-windows-tcb-trash.rs39
-rw-r--r--tests/ui/issues/issue-25185.rs12
-rw-r--r--tests/ui/issues/issue-32655.rs19
-rw-r--r--tests/ui/issues/issue-32655.stderr25
-rw-r--r--tests/ui/iterators/bytes-iterator-clone-12677.rs (renamed from tests/ui/issues/issue-12677.rs)2
-rw-r--r--tests/ui/iterators/iterator-type-inference-sum-15673.rs (renamed from tests/ui/issues/issue-15673.rs)1
-rw-r--r--tests/ui/lifetimes/iterator-trait-lifetime-error-13058.rs (renamed from tests/ui/issues/issue-13058.rs)2
-rw-r--r--tests/ui/lifetimes/iterator-trait-lifetime-error-13058.stderr (renamed from tests/ui/issues/issue-13058.stderr)2
-rw-r--r--tests/ui/lifetimes/lifetime-inference-destructuring-arg.rs (renamed from tests/ui/issues/issue-13167.rs)2
-rw-r--r--tests/ui/lifetimes/matcher-trait-equality-13323.rs (renamed from tests/ui/issues/issue-13323.rs)2
-rw-r--r--tests/ui/lifetimes/struct-lifetime-field-assignment-13405.rs (renamed from tests/ui/issues/issue-13405.rs)2
-rw-r--r--tests/ui/lifetimes/unsafe-transmute-in-find-11740.rs (renamed from tests/ui/issues/issue-11740.rs)2
-rw-r--r--tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs1
-rw-r--r--tests/ui/linking/auxiliary/aux-25185-1.rs (renamed from tests/ui/issues/auxiliary/issue-25185-1.rs)0
-rw-r--r--tests/ui/linking/auxiliary/aux-25185-2.rs3
-rw-r--r--tests/ui/linking/rlib-to-dylib-native-deps-inclusion-25185.rs13
-rw-r--r--tests/ui/lint/dangling-pointers-from-locals.rs188
-rw-r--r--tests/ui/lint/dangling-pointers-from-locals.stderr247
-rw-r--r--tests/ui/lint/lint-non-uppercase-usages.stderr2
-rw-r--r--tests/ui/loop-match/const-continue-to-block.rs21
-rw-r--r--tests/ui/loop-match/const-continue-to-block.stderr17
-rw-r--r--tests/ui/loop-match/invalid.rs19
-rw-r--r--tests/ui/loop-match/invalid.stderr22
-rw-r--r--tests/ui/macros/builtin-std-paths-fail.stderr4
-rw-r--r--tests/ui/macros/invalid-assignment-in-macro-26093.rs (renamed from tests/ui/issues/issue-26093.rs)1
-rw-r--r--tests/ui/macros/invalid-assignment-in-macro-26093.stderr (renamed from tests/ui/issues/issue-26093.stderr)4
-rw-r--r--tests/ui/macros/macro-inner-attributes.stderr7
-rw-r--r--tests/ui/macros/macro-outer-attributes.stderr7
-rw-r--r--tests/ui/match/option-result-mismatch-11844.rs (renamed from tests/ui/issues/issue-11844.rs)2
-rw-r--r--tests/ui/match/option-result-mismatch-11844.stderr (renamed from tests/ui/issues/issue-11844.stderr)2
-rw-r--r--tests/ui/match/option-result-type-param-mismatch-13466.rs (renamed from tests/ui/issues/issue-13466.rs)2
-rw-r--r--tests/ui/match/option-result-type-param-mismatch-13466.stderr (renamed from tests/ui/issues/issue-13466.stderr)4
-rw-r--r--tests/ui/match/overeager-sub-match-pruning-13027.rs (renamed from tests/ui/issues/issue-13027.rs)2
-rw-r--r--tests/ui/match/slice-move-out-error-12567.rs (renamed from tests/ui/issues/issue-12567.rs)2
-rw-r--r--tests/ui/match/slice-move-out-error-12567.stderr (renamed from tests/ui/issues/issue-12567.stderr)4
-rw-r--r--tests/ui/match/struct-reference-patterns-12285.rs (renamed from tests/ui/issues/issue-12285.rs)2
-rw-r--r--tests/ui/parser/encode-symbol-ice-12920.rs (renamed from tests/ui/issues/issue-12920.rs)2
-rw-r--r--tests/ui/parser/item-kw-case-mismatch.stderr6
-rw-r--r--tests/ui/parser/kw-in-trait-bounds.stderr8
-rw-r--r--tests/ui/parser/misspelled-keywords/hrdt.stderr2
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-return.stderr2
-rw-r--r--tests/ui/parser/misspelled-keywords/static.stderr2
-rw-r--r--tests/ui/parser/misspelled-keywords/struct.stderr2
-rw-r--r--tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr4
-rw-r--r--tests/ui/parser/typod-const-in-const-param-def.stderr8
-rw-r--r--tests/ui/pattern/unit-pattern-matching-in-function-argument-7519.rs (renamed from tests/ui/issues/issue-7519-match-unit-in-arg.rs)1
-rw-r--r--tests/ui/privacy/private-in-public-warn.stderr72
-rw-r--r--tests/ui/privacy/private-unit-struct-assignment.rs (renamed from tests/ui/issues/issue-13407.rs)2
-rw-r--r--tests/ui/privacy/private-unit-struct-assignment.stderr (renamed from tests/ui/issues/issue-13407.stderr)6
-rw-r--r--tests/ui/privacy/projections.stderr26
-rw-r--r--tests/ui/privacy/use-in-impl-scope-12729.rs (renamed from tests/ui/issues/issue-12729.rs)2
-rw-r--r--tests/ui/resolve/reference-clone-nonclone-11820.rs (renamed from tests/ui/issues/issue-11820.rs)2
-rw-r--r--tests/ui/rustdoc/cfg-rustdoc.rs7
-rw-r--r--tests/ui/rustdoc/cfg-rustdoc.stderr8
-rw-r--r--tests/ui/statics/enum-with-static-str-variant-13214.rs (renamed from tests/ui/issues/issue-13214.rs)2
-rw-r--r--tests/ui/suggestions/assoc-ct-for-assoc-method.stderr2
-rw-r--r--tests/ui/suggestions/bool_typo_err_suggest.stderr2
-rw-r--r--tests/ui/suggestions/case-difference-suggestions.rs57
-rw-r--r--tests/ui/suggestions/case-difference-suggestions.stderr99
-rw-r--r--tests/ui/suggestions/incorrect-variant-literal.svg2
-rw-r--r--tests/ui/threads-sendsync/tcp-stress.rs64
-rw-r--r--tests/ui/traits/const-traits/conditionally-const-in-anon-const.rs28
-rw-r--r--tests/ui/traits/const-traits/conditionally-const-in-anon-const.stderr32
-rw-r--r--tests/ui/traits/const-traits/conditionally-const-in-struct-args.rs21
-rw-r--r--tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr30
-rw-r--r--tests/ui/traits/default-method-lifetime-params-13204.rs (renamed from tests/ui/issues/issue-13204.rs)2
-rw-r--r--tests/ui/traits/fnonce-repro-trait-impl-13434.rs (renamed from tests/ui/issues/issue-13434.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/rayon-hang-1.rs32
-rw-r--r--tests/ui/traits/next-solver/cycles/rayon-hang-2.rs49
-rw-r--r--tests/ui/type-alias/missing-associated-type-in-trait-object-22434.rs (renamed from tests/ui/issues/issue-22434.rs)1
-rw-r--r--tests/ui/type-alias/missing-associated-type-in-trait-object-22434.stderr (renamed from tests/ui/issues/issue-22434.stderr)2
-rw-r--r--tests/ui/type-inference/partial-type-hint-12909.rs21
-rw-r--r--tests/ui/typeck/function-in-pattern-error-12863.rs (renamed from tests/ui/issues/issue-12863.rs)2
-rw-r--r--tests/ui/typeck/function-in-pattern-error-12863.stderr (renamed from tests/ui/issues/issue-12863.stderr)2
-rw-r--r--tests/ui/typeck/incorrect-self-type-in-trait-impl-48276.rs (renamed from tests/ui/issues/issue-48276.rs)1
-rw-r--r--tests/ui/typeck/incorrect-self-type-in-trait-impl-48276.stderr (renamed from tests/ui/issues/issue-48276.stderr)6
-rw-r--r--tests/ui/typeck/isize-usize-mismatch-error.rs (renamed from tests/ui/issues/issue-13359.rs)2
-rw-r--r--tests/ui/typeck/isize-usize-mismatch-error.stderr (renamed from tests/ui/issues/issue-13359.stderr)8
-rw-r--r--tests/ui/typeck/parenthesized-type-parameters-error-32995.rs (renamed from tests/ui/issues/issue-32995-2.rs)1
-rw-r--r--tests/ui/typeck/parenthesized-type-parameters-error-32995.stderr (renamed from tests/ui/issues/issue-32995-2.stderr)6
-rw-r--r--tests/ui/typeck/unit-type-add-error-11771.rs (renamed from tests/ui/issues/issue-11771.rs)2
-rw-r--r--tests/ui/typeck/unit-type-add-error-11771.stderr (renamed from tests/ui/issues/issue-11771.stderr)4
-rw-r--r--tests/ui/typeck/unwrap-or-panic-input-13202.rs (renamed from tests/ui/issues/issue-13202.rs)2
-rw-r--r--tests/ui/unboxed-closures/self-param-space-conflict-in-unboxed-closure-18685.rs (renamed from tests/ui/issues/issue-18685.rs)2
-rw-r--r--triagebot.toml17
899 files changed, 13858 insertions, 9418 deletions
diff --git a/.mailmap b/.mailmap
index 90533e81b39..2b75f5a145f 100644
--- a/.mailmap
+++ b/.mailmap
@@ -597,6 +597,7 @@ Sam Radhakrishnan <sk09idm@gmail.com>
 Samuel Tardieu <sam@rfc1149.net>
 Santiago Pastorino <spastorino@gmail.com>
 Santiago Pastorino <spastorino@gmail.com> <santiago@wyeworks.com>
+Sasha Pourcelot <sasha.pourcelot@protonmail.com> Sasha <sasha.pourcelot@protonmail.com>
 Scott McMurray <scottmcm@users.noreply.github.com>
 Scott McMurray <scottmcm@users.noreply.github.com> <smcmurray@acm.org>
 Scott Olson <scott@solson.me> Scott Olson <scott@scott-olson.org>
diff --git a/Cargo.lock b/Cargo.lock
index d9cfda17ad9..5a3906c470f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -518,9 +518,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.41"
+version = "4.5.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
+checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -538,9 +538,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.41"
+version = "4.5.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
+checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
 dependencies = [
  "anstream",
  "anstyle",
@@ -1171,7 +1171,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
 dependencies = [
  "libc",
  "option-ext",
- "redox_users 0.5.0",
+ "redox_users 0.5.2",
  "windows-sys 0.60.2",
 ]
 
@@ -2094,9 +2094,9 @@ dependencies = [
 
 [[package]]
 name = "jsonpath-rust"
-version = "1.0.3"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d057f8fd19e20c3f14d3663983397155739b6bc1148dc5cd4c4a1a5b3130eb0"
+checksum = "633a7320c4bb672863a3782e89b9094ad70285e097ff6832cddd0ec615beadfa"
 dependencies = [
  "pest",
  "pest_derive",
@@ -2190,7 +2190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
 dependencies = [
  "cfg-if",
- "windows-targets 0.53.2",
+ "windows-targets 0.53.3",
 ]
 
 [[package]]
@@ -2201,9 +2201,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
 
 [[package]]
 name = "libredox"
-version = "0.1.6"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0"
+checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
 dependencies = [
  "bitflags",
  "libc",
@@ -2643,9 +2643,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.37.1"
+version = "0.37.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a"
+checksum = "b3e3d0a7419f081f4a808147e845310313a39f322d7ae1f996b7f001d6cbed04"
 dependencies = [
  "crc32fast",
  "flate2",
@@ -2653,7 +2653,7 @@ dependencies = [
  "indexmap",
  "memchr",
  "ruzstd 0.8.1",
- "wasmparser 0.234.0",
+ "wasmparser 0.236.0",
 ]
 
 [[package]]
@@ -3167,9 +3167,9 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.16"
+version = "0.5.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792"
+checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
 dependencies = [
  "bitflags",
 ]
@@ -3187,9 +3187,9 @@ dependencies = [
 
 [[package]]
 name = "redox_users"
-version = "0.5.0"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
+checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
 dependencies = [
  "getrandom 0.2.16",
  "libredox",
@@ -3279,7 +3279,7 @@ dependencies = [
  "build_helper",
  "gimli 0.32.0",
  "libc",
- "object 0.37.1",
+ "object 0.37.2",
  "regex",
  "serde_json",
  "similar",
@@ -3301,9 +3301,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.25"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
+checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
 
 [[package]]
 name = "rustc-hash"
@@ -3569,7 +3569,7 @@ dependencies = [
  "itertools",
  "libc",
  "measureme",
- "object 0.37.1",
+ "object 0.37.2",
  "rustc-demangle",
  "rustc_abi",
  "rustc_ast",
@@ -3607,7 +3607,7 @@ dependencies = [
  "cc",
  "itertools",
  "libc",
- "object 0.37.1",
+ "object 0.37.2",
  "pathdiff",
  "regex",
  "rustc_abi",
@@ -4519,6 +4519,7 @@ name = "rustc_resolve"
 version = "0.0.0"
 dependencies = [
  "bitflags",
+ "indexmap",
  "itertools",
  "pulldown-cmark",
  "rustc_arena",
@@ -4642,7 +4643,7 @@ name = "rustc_target"
 version = "0.0.0"
 dependencies = [
  "bitflags",
- "object 0.37.1",
+ "object 0.37.2",
  "rustc_abi",
  "rustc_data_structures",
  "rustc_fs_util",
@@ -5039,9 +5040,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.141"
+version = "1.0.142"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
+checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
 dependencies = [
  "itoa",
  "memchr",
@@ -6099,12 +6100,12 @@ dependencies = [
 
 [[package]]
 name = "wasm-encoder"
-version = "0.235.0"
+version = "0.236.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3bc393c395cb621367ff02d854179882b9a351b4e0c93d1397e6090b53a5c2a"
+checksum = "3108979166ab0d3c7262d2e16a2190ffe784b2a5beb963edef154b5e8e07680b"
 dependencies = [
  "leb128fmt",
- "wasmparser 0.235.0",
+ "wasmparser 0.236.0",
 ]
 
 [[package]]
@@ -6144,9 +6145,9 @@ dependencies = [
 
 [[package]]
 name = "wasmparser"
-version = "0.235.0"
+version = "0.236.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "161296c618fa2d63f6ed5fffd1112937e803cb9ec71b32b01a76321555660917"
+checksum = "16d1eee846a705f6f3cb9d7b9f79b54583810f1fb57a1e3aea76d1742db2e3d2"
 dependencies = [
  "bitflags",
  "indexmap",
@@ -6155,22 +6156,22 @@ dependencies = [
 
 [[package]]
 name = "wast"
-version = "235.0.0"
+version = "236.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1eda4293f626c99021bb3a6fbe4fbbe90c0e31a5ace89b5f620af8925de72e13"
+checksum = "11d6b6faeab519ba6fbf9b26add41617ca6f5553f99ebc33d876e591d2f4f3c6"
 dependencies = [
  "bumpalo",
  "leb128fmt",
  "memchr",
  "unicode-width 0.2.1",
- "wasm-encoder 0.235.0",
+ "wasm-encoder 0.236.0",
 ]
 
 [[package]]
 name = "wat"
-version = "1.235.0"
+version = "1.236.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e777e0327115793cb96ab220b98f85327ec3d11f34ec9e8d723264522ef206aa"
+checksum = "cc31704322400f461f7f31a5f9190d5488aaeafb63ae69ad2b5888d2704dcb08"
 dependencies = [
  "wast",
 ]
@@ -6426,7 +6427,7 @@ version = "0.60.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
 dependencies = [
- "windows-targets 0.53.2",
+ "windows-targets 0.53.3",
 ]
 
 [[package]]
@@ -6462,10 +6463,11 @@ dependencies = [
 
 [[package]]
 name = "windows-targets"
-version = "0.53.2"
+version = "0.53.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
+checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
 dependencies = [
+ "windows-link",
  "windows_aarch64_gnullvm 0.53.0",
  "windows_aarch64_msvc 0.53.0",
  "windows_i686_gnu 0.53.0",
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 5b63206d7d6..5f8933aa2be 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -311,7 +311,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         );
 
         self.with_parent(const_arg.hir_id, |this| {
-            intravisit::walk_ambig_const_arg(this, const_arg);
+            intravisit::walk_const_arg(this, const_arg);
         });
     }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 189c82b614c..d097e3cbaa8 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -675,7 +675,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let bodies = SortedMap::from_presorted_elements(bodies);
 
         // Don't hash unless necessary, because it's expensive.
-        let (opt_hash_including_bodies, attrs_hash, delayed_lints_hash) =
+        let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash, delayed_lints_hash } =
             self.tcx.hash_owner_nodes(node, &bodies, &attrs, &delayed_lints, define_opaque);
         let num_nodes = self.item_local_id_counter.as_usize();
         let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index af93d55c898..42f3569f0f1 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -241,6 +241,10 @@ ast_passes_tilde_const_disallowed = `[const]` is not allowed here
     .trait_assoc_ty = associated types in non-`const` traits cannot have `[const]` trait bounds
     .trait_impl_assoc_ty = associated types in non-const impls cannot have `[const]` trait bounds
     .inherent_assoc_ty = inherent associated types cannot have `[const]` trait bounds
+    .struct = structs cannot have `[const]` trait bounds
+    .enum = enums cannot have `[const]` trait bounds
+    .union = unions cannot have `[const]` trait bounds
+    .anon_const = anonymous constants cannot have `[const]` trait bounds
     .object = trait objects cannot have `[const]` trait bounds
     .item = this item cannot have `[const]` trait bounds
 
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 895a457ec1d..ae482ceb9b7 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1124,7 +1124,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         );
                     }
                 }
-                visit::walk_item(self, item)
+                self.with_tilde_const(Some(TildeConstReason::Enum { span: item.span }), |this| {
+                    visit::walk_item(this, item)
+                });
             }
             ItemKind::Trait(box Trait {
                 constness,
@@ -1175,26 +1177,32 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
                 visit::walk_item(self, item)
             }
-            ItemKind::Struct(ident, generics, vdata) => match vdata {
-                VariantData::Struct { fields, .. } => {
-                    self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
-                    self.visit_generics(generics);
-                    walk_list!(self, visit_field_def, fields);
-                }
-                _ => visit::walk_item(self, item),
-            },
+            ItemKind::Struct(ident, generics, vdata) => {
+                self.with_tilde_const(Some(TildeConstReason::Struct { span: item.span }), |this| {
+                    match vdata {
+                        VariantData::Struct { fields, .. } => {
+                            this.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
+                            this.visit_generics(generics);
+                            walk_list!(this, visit_field_def, fields);
+                        }
+                        _ => visit::walk_item(this, item),
+                    }
+                })
+            }
             ItemKind::Union(ident, generics, vdata) => {
                 if vdata.fields().is_empty() {
                     self.dcx().emit_err(errors::FieldlessUnion { span: item.span });
                 }
-                match vdata {
-                    VariantData::Struct { fields, .. } => {
-                        self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
-                        self.visit_generics(generics);
-                        walk_list!(self, visit_field_def, fields);
+                self.with_tilde_const(Some(TildeConstReason::Union { span: item.span }), |this| {
+                    match vdata {
+                        VariantData::Struct { fields, .. } => {
+                            this.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
+                            this.visit_generics(generics);
+                            walk_list!(this, visit_field_def, fields);
+                        }
+                        _ => visit::walk_item(this, item),
                     }
-                    _ => visit::walk_item(self, item),
-                }
+                });
             }
             ItemKind::Const(box ConstItem { defaultness, expr, .. }) => {
                 self.check_defaultness(item.span, *defaultness);
@@ -1623,6 +1631,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             _ => self.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt)),
         }
     }
+
+    fn visit_anon_const(&mut self, anon_const: &'a AnonConst) {
+        self.with_tilde_const(
+            Some(TildeConstReason::AnonConst { span: anon_const.value.span }),
+            |this| visit::walk_anon_const(this, anon_const),
+        )
+    }
 }
 
 /// When encountering an equality constraint in a `where` clause, emit an error. If the code seems
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index fd4b2528541..8b5873a3ef3 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -623,6 +623,26 @@ pub(crate) enum TildeConstReason {
         #[primary_span]
         span: Span,
     },
+    #[note(ast_passes_struct)]
+    Struct {
+        #[primary_span]
+        span: Span,
+    },
+    #[note(ast_passes_enum)]
+    Enum {
+        #[primary_span]
+        span: Span,
+    },
+    #[note(ast_passes_union)]
+    Union {
+        #[primary_span]
+        span: Span,
+    },
+    #[note(ast_passes_anon_const)]
+    AnonConst {
+        #[primary_span]
+        span: Span,
+    },
     #[note(ast_passes_object)]
     TraitObject,
     #[note(ast_passes_item)]
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index 7c8ef90ed7f..c5fb11dbf6a 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -374,11 +374,3 @@ impl<S: Stage> CombineAttributeParser<S> for TargetFeatureParser {
         features
     }
 }
-
-pub(crate) struct OmitGdbPrettyPrinterSectionParser;
-
-impl<S: Stage> NoArgsAttributeParser<S> for OmitGdbPrettyPrinterSectionParser {
-    const PATH: &[Symbol] = &[sym::omit_gdb_pretty_printer_section];
-    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
-    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::OmitGdbPrettyPrinterSection;
-}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index 54c0fbcd062..c6599f20c2d 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -17,9 +17,8 @@ use crate::attributes::allow_unstable::{
     AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser,
 };
 use crate::attributes::codegen_attrs::{
-    ColdParser, CoverageParser, ExportNameParser, NakedParser, NoMangleParser,
-    OmitGdbPrettyPrinterSectionParser, OptimizeParser, TargetFeatureParser, TrackCallerParser,
-    UsedParser,
+    ColdParser, CoverageParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser,
+    TargetFeatureParser, TrackCallerParser, UsedParser,
 };
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::deprecation::DeprecationParser;
@@ -62,15 +61,23 @@ use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
 use crate::parser::{ArgParser, MetaItemParser, PathParser};
 use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem};
 
-macro_rules! group_type {
-    ($stage: ty) => {
-         LazyLock<(
-            BTreeMap<&'static [Symbol], Vec<(AttributeTemplate, Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, $stage>, &ArgParser<'a>) + Send + Sync>)>>,
-            Vec<Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, $stage>) -> Option<AttributeKind>>>
-        )>
-    };
+type GroupType<S> = LazyLock<GroupTypeInner<S>>;
+
+struct GroupTypeInner<S: Stage> {
+    accepters: BTreeMap<&'static [Symbol], Vec<GroupTypeInnerAccept<S>>>,
+    finalizers: Vec<FinalizeFn<S>>,
+}
+
+struct GroupTypeInnerAccept<S: Stage> {
+    template: AttributeTemplate,
+    accept_fn: AcceptFn<S>,
 }
 
+type AcceptFn<S> =
+    Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, S>, &ArgParser<'a>) + Send + Sync>;
+type FinalizeFn<S> =
+    Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, S>) -> Option<AttributeKind>>;
+
 macro_rules! attribute_parsers {
     (
         pub(crate) static $name: ident = [$($names: ty),* $(,)?];
@@ -93,11 +100,11 @@ macro_rules! attribute_parsers {
         }
     };
     (
-        @[$ty: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
+        @[$stage: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
     ) => {
-        pub(crate) static $name: group_type!($ty) = LazyLock::new(|| {
-            let mut accepts = BTreeMap::<_, Vec<(AttributeTemplate, Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, $ty>, &ArgParser<'a>) + Send + Sync>)>>::new();
-            let mut finalizes = Vec::<Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, $ty>) -> Option<AttributeKind>>>::new();
+        pub(crate) static $name: GroupType<$stage> = LazyLock::new(|| {
+            let mut accepts = BTreeMap::<_, Vec<GroupTypeInnerAccept<$stage>>>::new();
+            let mut finalizes = Vec::<FinalizeFn<$stage>>::new();
             $(
                 {
                     thread_local! {
@@ -105,11 +112,14 @@ macro_rules! attribute_parsers {
                     };
 
                     for (path, template, accept_fn) in <$names>::ATTRIBUTES {
-                        accepts.entry(*path).or_default().push((*template, Box::new(|cx, args| {
-                            STATE_OBJECT.with_borrow_mut(|s| {
-                                accept_fn(s, cx, args)
+                        accepts.entry(*path).or_default().push(GroupTypeInnerAccept {
+                            template: *template,
+                            accept_fn: Box::new(|cx, args| {
+                                STATE_OBJECT.with_borrow_mut(|s| {
+                                    accept_fn(s, cx, args)
+                                })
                             })
-                        })));
+                        });
                     }
 
                     finalizes.push(Box::new(|cx| {
@@ -119,7 +129,7 @@ macro_rules! attribute_parsers {
                 }
             )*
 
-            (accepts, finalizes)
+            GroupTypeInner { accepters:accepts, finalizers:finalizes }
         });
     };
 }
@@ -187,7 +197,6 @@ attribute_parsers!(
         Single<WithoutArgs<NoImplicitPreludeParser>>,
         Single<WithoutArgs<NoMangleParser>>,
         Single<WithoutArgs<NonExhaustiveParser>>,
-        Single<WithoutArgs<OmitGdbPrettyPrinterSectionParser>>,
         Single<WithoutArgs<ParenSugarParser>>,
         Single<WithoutArgs<PassByValueParser>>,
         Single<WithoutArgs<PointeeParser>>,
@@ -213,24 +222,24 @@ mod private {
 #[allow(private_interfaces)]
 pub trait Stage: Sized + 'static + Sealed {
     type Id: Copy;
-    const SHOULD_EMIT_LINTS: bool;
 
-    fn parsers() -> &'static group_type!(Self);
+    fn parsers() -> &'static GroupType<Self>;
 
     fn emit_err<'sess>(
         &self,
         sess: &'sess Session,
         diag: impl for<'x> Diagnostic<'x>,
     ) -> ErrorGuaranteed;
+
+    fn should_emit(&self) -> ShouldEmit;
 }
 
 // allow because it's a sealed trait
 #[allow(private_interfaces)]
 impl Stage for Early {
     type Id = NodeId;
-    const SHOULD_EMIT_LINTS: bool = false;
 
-    fn parsers() -> &'static group_type!(Self) {
+    fn parsers() -> &'static GroupType<Self> {
         &early::ATTRIBUTE_PARSERS
     }
     fn emit_err<'sess>(
@@ -244,15 +253,18 @@ impl Stage for Early {
             sess.dcx().create_err(diag).delay_as_bug()
         }
     }
+
+    fn should_emit(&self) -> ShouldEmit {
+        self.emit_errors
+    }
 }
 
 // allow because it's a sealed trait
 #[allow(private_interfaces)]
 impl Stage for Late {
     type Id = HirId;
-    const SHOULD_EMIT_LINTS: bool = true;
 
-    fn parsers() -> &'static group_type!(Self) {
+    fn parsers() -> &'static GroupType<Self> {
         &late::ATTRIBUTE_PARSERS
     }
     fn emit_err<'sess>(
@@ -262,6 +274,10 @@ impl Stage for Late {
     ) -> ErrorGuaranteed {
         tcx.dcx().emit_err(diag)
     }
+
+    fn should_emit(&self) -> ShouldEmit {
+        ShouldEmit::ErrorsAndLints
+    }
 }
 
 /// used when parsing attributes for miscellaneous things *before* ast lowering
@@ -300,7 +316,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
     /// must be delayed until after HIR is built. This method will take care of the details of
     /// that.
     pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) {
-        if !S::SHOULD_EMIT_LINTS {
+        if !self.stage.should_emit().should_emit() {
             return;
         }
         let id = self.target_id;
@@ -811,8 +827,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
                     let args = parser.args();
                     let parts = path.segments().map(|i| i.name).collect::<Vec<_>>();
 
-                    if let Some(accepts) = S::parsers().0.get(parts.as_slice()) {
-                        for (template, accept) in accepts {
+                    if let Some(accepts) = S::parsers().accepters.get(parts.as_slice()) {
+                        for accept in accepts {
                             let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext {
                                 shared: SharedContext {
                                     cx: self,
@@ -821,11 +837,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
                                     emit_lint: &mut emit_lint,
                                 },
                                 attr_span: lower_span(attr.span),
-                                template,
+                                template: &accept.template,
                                 attr_path: path.get_attribute_path(),
                             };
 
-                            accept(&mut cx, args)
+                            (accept.accept_fn)(&mut cx, args)
                         }
                     } else {
                         // If we're here, we must be compiling a tool attribute... Or someone
@@ -856,7 +872,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
         }
 
         let mut parsed_attributes = Vec::new();
-        for f in &S::parsers().1 {
+        for f in &S::parsers().finalizers {
             if let Some(attr) = f(&mut FinalizeContext {
                 shared: SharedContext {
                     cx: self,
@@ -877,7 +893,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
 
     /// Returns whether there is a parser for an attribute with this name
     pub fn is_parsed_attribute(path: &[Symbol]) -> bool {
-        Late::parsers().0.contains_key(path)
+        Late::parsers().accepters.contains_key(path)
     }
 
     fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs {
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 56fdaf1c724..34bed375cb9 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -613,7 +613,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
     /// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime
     /// name where required.
     pub(super) fn get_name_for_ty(&self, ty: Ty<'tcx>, counter: usize) -> String {
-        let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, Namespace::TypeNS);
+        let mut p = ty::print::FmtPrinter::new(self.infcx.tcx, Namespace::TypeNS);
 
         // We need to add synthesized lifetimes where appropriate. We do
         // this by hooking into the pretty printer and telling it to label the
@@ -624,19 +624,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 | ty::RePlaceholder(ty::PlaceholderRegion {
                     bound: ty::BoundRegion { kind: br, .. },
                     ..
-                }) => printer.region_highlight_mode.highlighting_bound_region(br, counter),
+                }) => p.region_highlight_mode.highlighting_bound_region(br, counter),
                 _ => {}
             }
         }
 
-        ty.print(&mut printer).unwrap();
-        printer.into_buffer()
+        ty.print(&mut p).unwrap();
+        p.into_buffer()
     }
 
     /// Returns the name of the provided `Ty` (that must be a reference)'s region with a
     /// synthesized lifetime name where required.
     pub(super) fn get_region_name_for_ty(&self, ty: Ty<'tcx>, counter: usize) -> String {
-        let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, Namespace::TypeNS);
+        let mut p = ty::print::FmtPrinter::new(self.infcx.tcx, Namespace::TypeNS);
 
         let region = if let ty::Ref(region, ..) = ty.kind() {
             match region.kind() {
@@ -644,7 +644,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 | ty::RePlaceholder(ty::PlaceholderRegion {
                     bound: ty::BoundRegion { kind: br, .. },
                     ..
-                }) => printer.region_highlight_mode.highlighting_bound_region(br, counter),
+                }) => p.region_highlight_mode.highlighting_bound_region(br, counter),
                 _ => {}
             }
             region
@@ -652,8 +652,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             bug!("ty for annotation of borrow region is not a reference");
         };
 
-        region.print(&mut printer).unwrap();
-        printer.into_buffer()
+        region.print(&mut p).unwrap();
+        p.into_buffer()
     }
 
     /// Add a note to region errors and borrow explanations when higher-ranked regions in predicates
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 68f1637e07e..f1320048533 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -417,7 +417,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// minimum values.
     ///
     /// For example:
-    /// ```
+    /// ```ignore (illustrative)
     /// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
     /// ```
     /// would initialize two variables like so:
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index 99392ea1915..eb31b5de05d 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -86,7 +86,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         // 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/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index e023300f1c2..bb72d1d52f3 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -187,7 +187,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
                 types: &mut |_bound_ty: ty::BoundTy| {
                     unreachable!("we only replace regions in nll_relate, not types")
                 },
-                consts: &mut |_bound_var: ty::BoundVar| {
+                consts: &mut |_bound_const: ty::BoundConst| {
                     unreachable!("we only replace regions in nll_relate, not consts")
                 },
             };
@@ -226,7 +226,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
             types: &mut |_bound_ty: ty::BoundTy| {
                 unreachable!("we only replace regions in nll_relate, not types")
             },
-            consts: &mut |_bound_var: ty::BoundVar| {
+            consts: &mut |_bound_const: ty::BoundConst| {
                 unreachable!("we only replace regions in nll_relate, not consts")
             },
         };
diff --git a/compiler/rustc_codegen_gcc/build_system/src/abi_test.rs b/compiler/rustc_codegen_gcc/build_system/src/abi_test.rs
index 3c1531be27a..a85886d87f3 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/abi_test.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/abi_test.rs
@@ -31,7 +31,7 @@ pub fn run() -> Result<(), String> {
         Some("clones/abi-cafe".as_ref()),
         true,
     )
-    .map_err(|err| (format!("Git clone failed with message: {err:?}!")))?;
+    .map_err(|err| format!("Git clone failed with message: {err:?}!"))?;
     // Configure abi-cafe to use the exact same rustc version we use - this is crucial.
     // Otherwise, the concept of ABI compatibility becomes meanignless.
     std::fs::copy("rust-toolchain", "clones/abi-cafe/rust-toolchain")
diff --git a/compiler/rustc_codegen_gcc/build_system/src/fuzz.rs b/compiler/rustc_codegen_gcc/build_system/src/fuzz.rs
index 453211366b3..9714ce29af9 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/fuzz.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/fuzz.rs
@@ -43,18 +43,18 @@ pub fn run() -> Result<(), String> {
             "--start" => {
                 start =
                     str::parse(&args.next().ok_or_else(|| "Fuzz start not provided!".to_string())?)
-                        .map_err(|err| (format!("Fuzz start not a number {err:?}!")))?;
+                        .map_err(|err| format!("Fuzz start not a number {err:?}!"))?;
             }
             "--count" => {
                 count =
                     str::parse(&args.next().ok_or_else(|| "Fuzz count not provided!".to_string())?)
-                        .map_err(|err| (format!("Fuzz count not a number {err:?}!")))?;
+                        .map_err(|err| format!("Fuzz count not a number {err:?}!"))?;
             }
             "-j" | "--jobs" => {
                 threads = str::parse(
                     &args.next().ok_or_else(|| "Fuzz thread count not provided!".to_string())?,
                 )
-                .map_err(|err| (format!("Fuzz thread count not a number {err:?}!")))?;
+                .map_err(|err| format!("Fuzz thread count not a number {err:?}!"))?;
             }
             _ => return Err(format!("Unknown option {arg}")),
         }
@@ -66,7 +66,7 @@ pub fn run() -> Result<(), String> {
         Some("clones/rustlantis".as_ref()),
         true,
     )
-    .map_err(|err| (format!("Git clone failed with message: {err:?}!")))?;
+    .map_err(|err| format!("Git clone failed with message: {err:?}!"))?;
 
     // Ensure that we are on the newest rustlantis commit.
     let cmd: &[&dyn AsRef<OsStr>] = &[&"git", &"pull", &"origin"];
diff --git a/compiler/rustc_codegen_gcc/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch b/compiler/rustc_codegen_gcc/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch
index 9cc377850b9..3a8c37a8b8d 100644
--- a/compiler/rustc_codegen_gcc/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch
+++ b/compiler/rustc_codegen_gcc/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch
@@ -1,29 +1,28 @@
-From b8f3eed3053c9333b5dfbeaeb2a6a65a4b3156df Mon Sep 17 00:00:00 2001
-From: Antoni Boucher <bouanto@zoho.com>
-Date: Tue, 29 Aug 2023 13:06:34 -0400
+From 190e26c9274b3c93a9ee3516b395590e6bd9213b Mon Sep 17 00:00:00 2001
+From: None <none@example.com>
+Date: Sun, 3 Aug 2025 19:54:56 -0400
 Subject: [PATCH] Patch 0001-Add-stdarch-Cargo.toml-for-testing.patch
 
 ---
- library/stdarch/Cargo.toml | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
+ library/stdarch/Cargo.toml | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
  create mode 100644 library/stdarch/Cargo.toml
 
 diff --git a/library/stdarch/Cargo.toml b/library/stdarch/Cargo.toml
 new file mode 100644
-index 0000000..4c63700
+index 0000000..bd6725c
 --- /dev/null
 +++ b/library/stdarch/Cargo.toml
-@@ -0,0 +1,21 @@
+@@ -0,0 +1,20 @@
 +[workspace]
 +resolver = "1"
 +members = [
-+  "crates/core_arch",
-+  "crates/std_detect",
-+  "crates/stdarch-gen-arm",
++  "crates/*",
 +  #"examples/"
 +]
 +exclude = [
-+  "crates/wasm-assert-instr-tests"
++  "crates/wasm-assert-instr-tests",
++  "rust_programs",
 +]
 +
 +[profile.release]
@@ -36,5 +35,5 @@ index 0000000..4c63700
 +opt-level = 3
 +incremental = true
 -- 
-2.42.0
+2.50.1
 
diff --git a/compiler/rustc_codegen_gcc/rust-toolchain b/compiler/rustc_codegen_gcc/rust-toolchain
index 2fe8ec4647f..058e734be5c 100644
--- a/compiler/rustc_codegen_gcc/rust-toolchain
+++ b/compiler/rustc_codegen_gcc/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2025-07-04"
+channel = "nightly-2025-08-03"
 components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs
index 0d8dc93274f..2a95a7368aa 100644
--- a/compiler/rustc_codegen_gcc/src/allocator.rs
+++ b/compiler/rustc_codegen_gcc/src/allocator.rs
@@ -99,11 +99,15 @@ fn create_const_value_function(
     let func = context.new_function(None, FunctionType::Exported, output, &[], name, false);
 
     #[cfg(feature = "master")]
-    func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
-        tcx.sess.default_visibility(),
-    )));
-
-    func.add_attribute(FnAttribute::AlwaysInline);
+    {
+        func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
+            tcx.sess.default_visibility(),
+        )));
+
+        // FIXME(antoyo): cg_llvm sets AlwaysInline, but AlwaysInline is different in GCC and using
+        // it here will causes linking errors when using LTO.
+        func.add_attribute(FnAttribute::Inline);
+    }
 
     if tcx.sess.must_emit_unwind_tables() {
         // TODO(antoyo): emit unwind tables.
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 4aee211e2ef..34ade3d025f 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -540,9 +540,15 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
 
     fn ret(&mut self, mut value: RValue<'gcc>) {
         let expected_return_type = self.current_func().get_return_type();
-        if !expected_return_type.is_compatible_with(value.get_type()) {
-            // NOTE: due to opaque pointers now being used, we need to cast here.
-            value = self.context.new_cast(self.location, value, expected_return_type);
+        let value_type = value.get_type();
+        if !expected_return_type.is_compatible_with(value_type) {
+            // NOTE: due to opaque pointers now being used, we need to (bit)cast here.
+            if self.is_native_int_type(value_type) && self.is_native_int_type(expected_return_type)
+            {
+                value = self.context.new_cast(self.location, value, expected_return_type);
+            } else {
+                value = self.context.new_bitcast(self.location, value, expected_return_type);
+            }
         }
         self.llbb().end_with_return(self.location, value);
     }
@@ -1279,11 +1285,19 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
 
     fn intcast(
         &mut self,
-        value: RValue<'gcc>,
+        mut value: RValue<'gcc>,
         dest_typ: Type<'gcc>,
-        _is_signed: bool,
+        is_signed: bool,
     ) -> RValue<'gcc> {
-        // NOTE: is_signed is for value, not dest_typ.
+        let value_type = value.get_type();
+        if is_signed && !value_type.is_signed(self.cx) {
+            let signed_type = value_type.to_signed(self.cx);
+            value = self.gcc_int_cast(value, signed_type);
+        } else if !is_signed && value_type.is_signed(self.cx) {
+            let unsigned_type = value_type.to_unsigned(self.cx);
+            value = self.gcc_int_cast(value, unsigned_type);
+        }
+
         self.gcc_int_cast(value, dest_typ)
     }
 
diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs
index 6f21ce9352b..9fb7f6bad68 100644
--- a/compiler/rustc_codegen_gcc/src/int.rs
+++ b/compiler/rustc_codegen_gcc/src/int.rs
@@ -4,12 +4,15 @@
 
 // cSpell:words cmpti divti modti mulodi muloti udivti umodti
 
-use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp};
+use gccjit::{
+    BinaryOp, CType, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp,
+};
 use rustc_abi::{CanonAbi, Endian, ExternAbi};
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp};
 use rustc_middle::ty::{self, Ty};
 use rustc_target::callconv::{ArgAbi, ArgAttributes, FnAbi, PassMode};
+use rustc_type_ir::{Interner, TyKind};
 
 use crate::builder::{Builder, ToGccComp};
 use crate::common::{SignType, TypeReflection};
@@ -167,9 +170,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
                 if a_type.is_vector() {
                     // Vector types need to be bitcast.
                     // TODO(antoyo): perhaps use __builtin_convertvector for vector casting.
-                    b = self.context.new_bitcast(self.location, b, a.get_type());
+                    b = self.context.new_bitcast(self.location, b, a_type);
                 } else {
-                    b = self.context.new_cast(self.location, b, a.get_type());
+                    b = self.context.new_cast(self.location, b, a_type);
                 }
             }
             self.context.new_binary_op(self.location, operation, a_type, a, b)
@@ -216,13 +219,22 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         operation_name: &str,
         signed: bool,
         a: RValue<'gcc>,
-        b: RValue<'gcc>,
+        mut b: RValue<'gcc>,
     ) -> RValue<'gcc> {
         let a_type = a.get_type();
         let b_type = b.get_type();
         if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type))
             || (a_type.is_vector() && b_type.is_vector())
         {
+            if !a_type.is_compatible_with(b_type) {
+                if a_type.is_vector() {
+                    // Vector types need to be bitcast.
+                    // TODO(antoyo): perhaps use __builtin_convertvector for vector casting.
+                    b = self.context.new_bitcast(self.location, b, a_type);
+                } else {
+                    b = self.context.new_cast(self.location, b, a_type);
+                }
+            }
             self.context.new_binary_op(self.location, operation, a_type, a, b)
         } else {
             debug_assert!(a_type.dyncast_array().is_some());
@@ -351,6 +363,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
             // TODO(antoyo): is it correct to use rhs type instead of the parameter typ?
             .new_local(self.location, rhs.get_type(), "binopResult")
             .get_address(self.location);
+        let new_type = type_kind_to_gcc_type(new_kind);
+        let new_type = self.context.new_c_type(new_type);
+        let lhs = self.context.new_cast(self.location, lhs, new_type);
+        let rhs = self.context.new_cast(self.location, rhs, new_type);
+        let res = self.context.new_cast(self.location, res, new_type.make_pointer());
         let overflow = self.overflow_call(intrinsic, &[lhs, rhs, res], None);
         (res.dereference(self.location).to_rvalue(), overflow)
     }
@@ -477,11 +494,27 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
             let lhs_low = self.context.new_cast(self.location, self.low(lhs), unsigned_type);
             let rhs_low = self.context.new_cast(self.location, self.low(rhs), unsigned_type);
 
+            let mut lhs_high = self.high(lhs);
+            let mut rhs_high = self.high(rhs);
+
+            match op {
+                IntPredicate::IntUGT
+                | IntPredicate::IntUGE
+                | IntPredicate::IntULT
+                | IntPredicate::IntULE => {
+                    lhs_high = self.context.new_cast(self.location, lhs_high, unsigned_type);
+                    rhs_high = self.context.new_cast(self.location, rhs_high, unsigned_type);
+                }
+                // TODO(antoyo): we probably need to handle signed comparison for unsigned
+                // integers.
+                _ => (),
+            }
+
             let condition = self.context.new_comparison(
                 self.location,
                 ComparisonOp::LessThan,
-                self.high(lhs),
-                self.high(rhs),
+                lhs_high,
+                rhs_high,
             );
             self.llbb().end_with_conditional(self.location, condition, block1, block2);
 
@@ -495,8 +528,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
             let condition = self.context.new_comparison(
                 self.location,
                 ComparisonOp::GreaterThan,
-                self.high(lhs),
-                self.high(rhs),
+                lhs_high,
+                rhs_high,
             );
             block2.end_with_conditional(self.location, condition, block3, block4);
 
@@ -620,7 +653,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         }
     }
 
-    pub fn gcc_xor(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
+    pub fn gcc_xor(&self, a: RValue<'gcc>, mut b: RValue<'gcc>) -> RValue<'gcc> {
         let a_type = a.get_type();
         let b_type = b.get_type();
         if a_type.is_vector() && b_type.is_vector() {
@@ -628,6 +661,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
             a ^ b
         } else if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type)
         {
+            if !a_type.is_compatible_with(b_type) {
+                b = self.context.new_cast(self.location, b, a_type);
+            }
             a ^ b
         } else {
             self.concat_low_high_rvalues(
@@ -1042,3 +1078,25 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
         self.context.new_array_constructor(None, typ, &values)
     }
 }
+
+fn type_kind_to_gcc_type<I: Interner>(kind: TyKind<I>) -> CType {
+    use rustc_middle::ty::IntTy::*;
+    use rustc_middle::ty::UintTy::*;
+    use rustc_middle::ty::{Int, Uint};
+
+    match kind {
+        Int(I8) => CType::Int8t,
+        Int(I16) => CType::Int16t,
+        Int(I32) => CType::Int32t,
+        Int(I64) => CType::Int64t,
+        Int(I128) => CType::Int128t,
+
+        Uint(U8) => CType::UInt8t,
+        Uint(U16) => CType::UInt16t,
+        Uint(U32) => CType::UInt32t,
+        Uint(U64) => CType::UInt64t,
+        Uint(U128) => CType::UInt128t,
+
+        _ => unimplemented!("Kind: {:?}", kind),
+    }
+}
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs b/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs
index 915ed875e32..d1b2a93243d 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs
@@ -95,8 +95,11 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str {
                     "cubema" => "__builtin_amdgcn_cubema",
                     "cubesc" => "__builtin_amdgcn_cubesc",
                     "cubetc" => "__builtin_amdgcn_cubetc",
+                    "cvt.f16.bf8" => "__builtin_amdgcn_cvt_f16_bf8",
+                    "cvt.f16.fp8" => "__builtin_amdgcn_cvt_f16_fp8",
                     "cvt.f32.bf8" => "__builtin_amdgcn_cvt_f32_bf8",
                     "cvt.f32.fp8" => "__builtin_amdgcn_cvt_f32_fp8",
+                    "cvt.f32.fp8.e5m3" => "__builtin_amdgcn_cvt_f32_fp8_e5m3",
                     "cvt.off.f32.i4" => "__builtin_amdgcn_cvt_off_f32_i4",
                     "cvt.pk.bf8.f32" => "__builtin_amdgcn_cvt_pk_bf8_f32",
                     "cvt.pk.f16.bf8" => "__builtin_amdgcn_cvt_pk_f16_bf8",
@@ -181,6 +184,12 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str {
                     "dot4.f32.fp8.bf8" => "__builtin_amdgcn_dot4_f32_fp8_bf8",
                     "dot4.f32.fp8.fp8" => "__builtin_amdgcn_dot4_f32_fp8_fp8",
                     "ds.add.gs.reg.rtn" => "__builtin_amdgcn_ds_add_gs_reg_rtn",
+                    "ds.atomic.async.barrier.arrive.b64" => {
+                        "__builtin_amdgcn_ds_atomic_async_barrier_arrive_b64"
+                    }
+                    "ds.atomic.barrier.arrive.rtn.b64" => {
+                        "__builtin_amdgcn_ds_atomic_barrier_arrive_rtn_b64"
+                    }
                     "ds.bpermute" => "__builtin_amdgcn_ds_bpermute",
                     "ds.bpermute.fi.b32" => "__builtin_amdgcn_ds_bpermute_fi_b32",
                     "ds.gws.barrier" => "__builtin_amdgcn_ds_gws_barrier",
@@ -198,8 +207,32 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str {
                     "fdot2.f16.f16" => "__builtin_amdgcn_fdot2_f16_f16",
                     "fdot2.f32.bf16" => "__builtin_amdgcn_fdot2_f32_bf16",
                     "fdot2c.f32.bf16" => "__builtin_amdgcn_fdot2c_f32_bf16",
+                    "flat.prefetch" => "__builtin_amdgcn_flat_prefetch",
                     "fmul.legacy" => "__builtin_amdgcn_fmul_legacy",
+                    "global.load.async.to.lds.b128" => {
+                        "__builtin_amdgcn_global_load_async_to_lds_b128"
+                    }
+                    "global.load.async.to.lds.b32" => {
+                        "__builtin_amdgcn_global_load_async_to_lds_b32"
+                    }
+                    "global.load.async.to.lds.b64" => {
+                        "__builtin_amdgcn_global_load_async_to_lds_b64"
+                    }
+                    "global.load.async.to.lds.b8" => "__builtin_amdgcn_global_load_async_to_lds_b8",
                     "global.load.lds" => "__builtin_amdgcn_global_load_lds",
+                    "global.prefetch" => "__builtin_amdgcn_global_prefetch",
+                    "global.store.async.from.lds.b128" => {
+                        "__builtin_amdgcn_global_store_async_from_lds_b128"
+                    }
+                    "global.store.async.from.lds.b32" => {
+                        "__builtin_amdgcn_global_store_async_from_lds_b32"
+                    }
+                    "global.store.async.from.lds.b64" => {
+                        "__builtin_amdgcn_global_store_async_from_lds_b64"
+                    }
+                    "global.store.async.from.lds.b8" => {
+                        "__builtin_amdgcn_global_store_async_from_lds_b8"
+                    }
                     "groupstaticsize" => "__builtin_amdgcn_groupstaticsize",
                     "iglp.opt" => "__builtin_amdgcn_iglp_opt",
                     "implicit.buffer.ptr" => "__builtin_amdgcn_implicit_buffer_ptr",
@@ -291,6 +324,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str {
                     "s.incperflevel" => "__builtin_amdgcn_s_incperflevel",
                     "s.memrealtime" => "__builtin_amdgcn_s_memrealtime",
                     "s.memtime" => "__builtin_amdgcn_s_memtime",
+                    "s.monitor.sleep" => "__builtin_amdgcn_s_monitor_sleep",
                     "s.sendmsg" => "__builtin_amdgcn_s_sendmsg",
                     "s.sendmsghalt" => "__builtin_amdgcn_s_sendmsghalt",
                     "s.setprio" => "__builtin_amdgcn_s_setprio",
@@ -300,11 +334,15 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str {
                     "s.sleep.var" => "__builtin_amdgcn_s_sleep_var",
                     "s.ttracedata" => "__builtin_amdgcn_s_ttracedata",
                     "s.ttracedata.imm" => "__builtin_amdgcn_s_ttracedata_imm",
+                    "s.wait.asynccnt" => "__builtin_amdgcn_s_wait_asynccnt",
                     "s.wait.event.export.ready" => "__builtin_amdgcn_s_wait_event_export_ready",
+                    "s.wait.tensorcnt" => "__builtin_amdgcn_s_wait_tensorcnt",
                     "s.waitcnt" => "__builtin_amdgcn_s_waitcnt",
                     "sad.hi.u8" => "__builtin_amdgcn_sad_hi_u8",
                     "sad.u16" => "__builtin_amdgcn_sad_u16",
                     "sad.u8" => "__builtin_amdgcn_sad_u8",
+                    "sat.pk4.i4.i8" => "__builtin_amdgcn_sat_pk4_i4_i8",
+                    "sat.pk4.u4.u8" => "__builtin_amdgcn_sat_pk4_u4_u8",
                     "sched.barrier" => "__builtin_amdgcn_sched_barrier",
                     "sched.group.barrier" => "__builtin_amdgcn_sched_group_barrier",
                     "sdot2" => "__builtin_amdgcn_sdot2",
@@ -346,8 +384,13 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str {
                     "smfmac.i32.16x16x64.i8" => "__builtin_amdgcn_smfmac_i32_16x16x64_i8",
                     "smfmac.i32.32x32x32.i8" => "__builtin_amdgcn_smfmac_i32_32x32x32_i8",
                     "smfmac.i32.32x32x64.i8" => "__builtin_amdgcn_smfmac_i32_32x32x64_i8",
+                    "struct.ptr.buffer.load.lds" => "__builtin_amdgcn_struct_ptr_buffer_load_lds",
                     "sudot4" => "__builtin_amdgcn_sudot4",
                     "sudot8" => "__builtin_amdgcn_sudot8",
+                    "tensor.load.to.lds" => "__builtin_amdgcn_tensor_load_to_lds",
+                    "tensor.load.to.lds.d2" => "__builtin_amdgcn_tensor_load_to_lds_d2",
+                    "tensor.store.from.lds" => "__builtin_amdgcn_tensor_store_from_lds",
+                    "tensor.store.from.lds.d2" => "__builtin_amdgcn_tensor_store_from_lds_d2",
                     "udot2" => "__builtin_amdgcn_udot2",
                     "udot4" => "__builtin_amdgcn_udot4",
                     "udot8" => "__builtin_amdgcn_udot8",
@@ -6326,6 +6369,23 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str {
             }
             s390(name, full_name)
         }
+        "spv" => {
+            #[allow(non_snake_case)]
+            fn spv(name: &str, full_name: &str) -> &'static str {
+                match name {
+                    // spv
+                    "num.subgroups" => "__builtin_spirv_num_subgroups",
+                    "subgroup.id" => "__builtin_spirv_subgroup_id",
+                    "subgroup.local.invocation.id" => {
+                        "__builtin_spirv_subgroup_local_invocation_id"
+                    }
+                    "subgroup.max.size" => "__builtin_spirv_subgroup_max_size",
+                    "subgroup.size" => "__builtin_spirv_subgroup_size",
+                    _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"),
+                }
+            }
+            spv(name, full_name)
+        }
         "ve" => {
             #[allow(non_snake_case)]
             fn ve(name: &str, full_name: &str) -> &'static str {
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 0753ac1aeb8..eb0a5336a1f 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -925,10 +925,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         // TODO(antoyo): use width?
         let arg_type = arg.get_type();
         let result_type = self.u32_type;
+        let arg = if arg_type.is_signed(self.cx) {
+            let new_type = arg_type.to_unsigned(self.cx);
+            self.gcc_int_cast(arg, new_type)
+        } else {
+            arg
+        };
+        let arg_type = arg.get_type();
         let count_leading_zeroes =
             // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here
             // instead of using is_uint().
-            if arg_type.is_uint(self.cx) {
+            if arg_type.is_uchar(self.cx) || arg_type.is_ushort(self.cx) || arg_type.is_uint(self.cx) {
                 "__builtin_clz"
             }
             else if arg_type.is_ulong(self.cx) {
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 350915a277e..fdc15d580ef 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -206,6 +206,28 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         );
     }
 
+    #[cfg(feature = "master")]
+    if name == sym::simd_funnel_shl {
+        return Ok(simd_funnel_shift(
+            bx,
+            args[0].immediate(),
+            args[1].immediate(),
+            args[2].immediate(),
+            true,
+        ));
+    }
+
+    #[cfg(feature = "master")]
+    if name == sym::simd_funnel_shr {
+        return Ok(simd_funnel_shift(
+            bx,
+            args[0].immediate(),
+            args[1].immediate(),
+            args[2].immediate(),
+            false,
+        ));
+    }
+
     if name == sym::simd_bswap {
         return Ok(simd_bswap(bx, args[0].immediate()));
     }
@@ -1434,3 +1456,62 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
 
     unimplemented!("simd {}", name);
 }
+
+#[cfg(feature = "master")]
+fn simd_funnel_shift<'a, 'gcc, 'tcx>(
+    bx: &mut Builder<'a, 'gcc, 'tcx>,
+    a: RValue<'gcc>,
+    b: RValue<'gcc>,
+    shift: RValue<'gcc>,
+    shift_left: bool,
+) -> RValue<'gcc> {
+    use crate::common::SignType;
+
+    let a_type = a.get_type();
+    let vector_type = a_type.unqualified().dyncast_vector().expect("vector type");
+    let num_units = vector_type.get_num_units();
+    let elem_type = vector_type.get_element_type();
+
+    let (new_int_type, int_shift_val, int_mask) = if elem_type.is_compatible_with(bx.u8_type)
+        || elem_type.is_compatible_with(bx.i8_type)
+    {
+        (bx.u16_type, 8, u8::MAX as u64)
+    } else if elem_type.is_compatible_with(bx.u16_type) || elem_type.is_compatible_with(bx.i16_type)
+    {
+        (bx.u32_type, 16, u16::MAX as u64)
+    } else if elem_type.is_compatible_with(bx.u32_type) || elem_type.is_compatible_with(bx.i32_type)
+    {
+        (bx.u64_type, 32, u32::MAX as u64)
+    } else if elem_type.is_compatible_with(bx.u64_type) || elem_type.is_compatible_with(bx.i64_type)
+    {
+        (bx.u128_type, 64, u64::MAX)
+    } else {
+        unimplemented!("funnel shift on {:?}", elem_type);
+    };
+
+    let int_mask = bx.context.new_rvalue_from_long(new_int_type, int_mask as i64);
+    let int_shift_val = bx.context.new_rvalue_from_int(new_int_type, int_shift_val);
+    let mut elements = vec![];
+    let unsigned_type = elem_type.to_unsigned(bx);
+    for i in 0..num_units {
+        let index = bx.context.new_rvalue_from_int(bx.int_type, i as i32);
+        let a_val = bx.context.new_vector_access(None, a, index).to_rvalue();
+        let a_val = bx.context.new_bitcast(None, a_val, unsigned_type);
+        // TODO: we probably need to use gcc_int_cast instead.
+        let a_val = bx.gcc_int_cast(a_val, new_int_type);
+        let b_val = bx.context.new_vector_access(None, b, index).to_rvalue();
+        let b_val = bx.context.new_bitcast(None, b_val, unsigned_type);
+        let b_val = bx.gcc_int_cast(b_val, new_int_type);
+        let shift_val = bx.context.new_vector_access(None, shift, index).to_rvalue();
+        let shift_val = bx.gcc_int_cast(shift_val, new_int_type);
+        let mut val = a_val << int_shift_val | b_val;
+        if shift_left {
+            val = (val << shift_val) >> int_shift_val;
+        } else {
+            val = (val >> shift_val) & int_mask;
+        }
+        let val = bx.gcc_int_cast(val, elem_type);
+        elements.push(val);
+    }
+    bx.context.new_rvalue_from_vector(None, a_type, &elements)
+}
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 613315f77a6..b11f11d38e3 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -50,6 +50,7 @@ extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_symbol_mangling;
 extern crate rustc_target;
+extern crate rustc_type_ir;
 
 // This prevents duplicating functions and statics that are already part of the host rustc process.
 #[allow(unused_extern_crates)]
@@ -362,9 +363,9 @@ impl WriteBackendMethods for GccCodegenBackend {
         _exported_symbols_for_lto: &[String],
         each_linked_rlib_for_lto: &[PathBuf],
         modules: Vec<FatLtoInput<Self>>,
-        diff_fncs: Vec<AutoDiffItem>,
+        diff_functions: Vec<AutoDiffItem>,
     ) -> Result<ModuleCodegen<Self::Module>, FatalError> {
-        if !diff_fncs.is_empty() {
+        if !diff_functions.is_empty() {
             unimplemented!();
         }
 
diff --git a/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt
index b9126fb73a7..bf0633f7320 100644
--- a/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt
+++ b/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt
@@ -28,6 +28,6 @@ tests/ui/macros/macro-comma-behavior-rpass.rs
 tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs
 tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs
 tests/ui/macros/stringify.rs
-tests/ui/reexport-test-harness-main.rs
 tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-in-test.rs
 tests/ui/binding/fn-arg-incomplete-pattern-drop-order.rs
+tests/ui/lto/debuginfo-lto-alloc.rs
diff --git a/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt
index 842533cd3c6..29032b321fa 100644
--- a/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt
+++ b/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt
@@ -6,7 +6,6 @@ tests/run-make/doctests-keep-binaries/
 tests/run-make/doctests-runtool/
 tests/run-make/emit-shared-files/
 tests/run-make/exit-code/
-tests/run-make/issue-22131/
 tests/run-make/issue-64153/
 tests/run-make/llvm-ident/
 tests/run-make/native-link-modifier-bundle/
diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt
index 6979c04d534..41fb4729c07 100644
--- a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt
+++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt
@@ -10,11 +10,10 @@ tests/ui/iterators/iter-sum-overflow-overflow-checks.rs
 tests/ui/mir/mir_drop_order.rs
 tests/ui/mir/mir_let_chains_drop_order.rs
 tests/ui/mir/mir_match_guard_let_chains_drop_order.rs
-tests/ui/oom_unwind.rs
+tests/ui/panics/oom-panic-unwind.rs
 tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs
 tests/ui/panic-runtime/abort.rs
 tests/ui/panic-runtime/link-to-abort.rs
-tests/ui/unwind-no-uwtable.rs
 tests/ui/parser/unclosed-delimiter-in-dep.rs
 tests/ui/consts/missing_span_in_backtrace.rs
 tests/ui/drop/dynamic-drop.rs
@@ -82,3 +81,8 @@ tests/ui/coroutine/panic-drops.rs
 tests/ui/coroutine/panic-safe.rs
 tests/ui/process/nofile-limit.rs
 tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+tests/ui/linking/no-gc-encapsulation-symbols.rs
+tests/ui/panics/unwind-force-no-unwind-tables.rs
+tests/ui/attributes/fn-align-dyn.rs
+tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs
+tests/ui/explicit-tail-calls/recursion-etc.rs
diff --git a/compiler/rustc_codegen_gcc/tools/cspell_dicts/rustc_codegen_gcc.txt b/compiler/rustc_codegen_gcc/tools/cspell_dicts/rustc_codegen_gcc.txt
index 31023e50ffa..4fb018b3ecd 100644
--- a/compiler/rustc_codegen_gcc/tools/cspell_dicts/rustc_codegen_gcc.txt
+++ b/compiler/rustc_codegen_gcc/tools/cspell_dicts/rustc_codegen_gcc.txt
@@ -8,6 +8,7 @@ clzll
 cmse
 codegened
 csky
+ctfe
 ctlz
 ctpop
 cttz
@@ -25,6 +26,7 @@ fwrapv
 gimple
 hrtb
 immediates
+interner
 liblto
 llbb
 llcx
@@ -47,6 +49,7 @@ mavx
 mcmodel
 minimumf
 minnumf
+miri
 monomorphization
 monomorphizations
 monomorphized
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 8c9dfcfd18c..d1cb95507d9 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -1,3 +1,4 @@
+use std::assert_matches::assert_matches;
 use std::sync::Arc;
 
 use itertools::Itertools;
@@ -5,6 +6,7 @@ use rustc_abi::Align;
 use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_index::IndexVec;
+use rustc_macros::TryFromU32;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::RemapFileNameExt;
 use rustc_session::config::RemapPathScopeComponents;
@@ -20,6 +22,23 @@ mod covfun;
 mod spans;
 mod unused;
 
+/// Version number that will be included the `__llvm_covmap` section header.
+/// Corresponds to LLVM's `llvm::coverage::CovMapVersion` (in `CoverageMapping.h`),
+/// or at least the subset that we know and care about.
+///
+/// Note that version `n` is encoded as `(n-1)`.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, TryFromU32)]
+enum CovmapVersion {
+    /// Used by LLVM 18 onwards.
+    Version7 = 6,
+}
+
+impl CovmapVersion {
+    fn to_u32(self) -> u32 {
+        self as u32
+    }
+}
+
 /// Generates and exports the coverage map, which is embedded in special
 /// linker sections in the final binary.
 ///
@@ -29,19 +48,13 @@ pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) {
     let tcx = cx.tcx;
 
     // Ensure that LLVM is using a version of the coverage mapping format that
-    // agrees with our Rust-side code. Expected versions (encoded as n-1) are:
-    // - `CovMapVersion::Version7` (6) used by LLVM 18-19
-    let covmap_version = {
-        let llvm_covmap_version = llvm_cov::mapping_version();
-        let expected_versions = 6..=6;
-        assert!(
-            expected_versions.contains(&llvm_covmap_version),
-            "Coverage mapping version exposed by `llvm-wrapper` is out of sync; \
-            expected {expected_versions:?} but was {llvm_covmap_version}"
-        );
-        // This is the version number that we will embed in the covmap section:
-        llvm_covmap_version
-    };
+    // agrees with our Rust-side code. Expected versions are:
+    // - `Version7` (6) used by LLVM 18 onwards.
+    let covmap_version =
+        CovmapVersion::try_from(llvm_cov::mapping_version()).unwrap_or_else(|raw_version: u32| {
+            panic!("unknown coverage mapping version reported by `llvm-wrapper`: {raw_version}")
+        });
+    assert_matches!(covmap_version, CovmapVersion::Version7);
 
     debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name());
 
@@ -201,7 +214,11 @@ impl VirtualFileMapping {
 /// Generates the contents of the covmap record for this CGU, which mostly
 /// consists of a header and a list of filenames. The record is then stored
 /// as a global variable in the `__llvm_covmap` section.
-fn generate_covmap_record<'ll>(cx: &mut CodegenCx<'ll, '_>, version: u32, filenames_buffer: &[u8]) {
+fn generate_covmap_record<'ll>(
+    cx: &mut CodegenCx<'ll, '_>,
+    version: CovmapVersion,
+    filenames_buffer: &[u8],
+) {
     // A covmap record consists of four target-endian u32 values, followed by
     // the encoded filenames table. Two of the header fields are unused in
     // modern versions of the LLVM coverage mapping format, and are always 0.
@@ -212,7 +229,7 @@ fn generate_covmap_record<'ll>(cx: &mut CodegenCx<'ll, '_>, version: u32, filena
             cx.const_u32(0), // (unused)
             cx.const_u32(filenames_buffer.len() as u32),
             cx.const_u32(0), // (unused)
-            cx.const_u32(version),
+            cx.const_u32(version.to_u32()),
         ],
         /* packed */ false,
     );
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
index b704cf2b1cd..fd1e7f7f160 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
@@ -27,6 +27,9 @@ use crate::llvm;
 /// the final record that will be embedded in the `__llvm_covfun` section.
 #[derive(Debug)]
 pub(crate) struct CovfunRecord<'tcx> {
+    /// Not used directly, but helpful in debug messages.
+    _instance: Instance<'tcx>,
+
     mangled_function_name: &'tcx str,
     source_hash: u64,
     is_used: bool,
@@ -55,6 +58,7 @@ pub(crate) fn prepare_covfun_record<'tcx>(
     let expressions = prepare_expressions(ids_info);
 
     let mut covfun = CovfunRecord {
+        _instance: instance,
         mangled_function_name: tcx.symbol_name(instance).name,
         source_hash: if is_used { fn_cov_info.function_source_hash } else { 0 },
         is_used,
@@ -102,11 +106,21 @@ fn fill_region_tables<'tcx>(
     ids_info: &'tcx CoverageIdsInfo,
     covfun: &mut CovfunRecord<'tcx>,
 ) {
+    // 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)
+    };
+
     // Currently a function's mappings must all be in the same file, so use the
     // first mapping's span to determine the file.
     let source_map = tcx.sess.source_map();
     let Some(first_span) = (try { fn_cov_info.mappings.first()?.span }) else {
-        debug_assert!(false, "function has no mappings: {:?}", covfun.mangled_function_name);
+        debug_assert!(false, "function has no mappings: {covfun:?}");
         return;
     };
     let source_file = source_map.lookup_source_file(first_span.lo());
@@ -117,7 +131,7 @@ fn fill_region_tables<'tcx>(
     // codegen needs to handle that gracefully to avoid #133606.
     // It's hard for tests to trigger this organically, so instead we set
     // `-Zcoverage-options=discard-all-spans-in-codegen` to force it to occur.
-    let discard_all = tcx.sess.coverage_discard_all_spans_in_codegen();
+    let discard_all = tcx.sess.coverage_options().discard_all_spans_in_codegen;
     let make_coords = |span: Span| {
         if discard_all { None } else { spans::make_coords(source_map, &source_file, span) }
     };
@@ -133,16 +147,6 @@ fn fill_region_tables<'tcx>(
     // For each counter/region pair in this function+file, convert it to a
     // form suitable for FFI.
     for &Mapping { ref kind, span } in &fn_cov_info.mappings {
-        // 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)
-        };
-
         let Some(coords) = make_coords(span) else { continue };
         let cov_span = coords.make_coverage_span(local_file_id);
 
@@ -184,6 +188,7 @@ pub(crate) fn generate_covfun_record<'tcx>(
     covfun: &CovfunRecord<'tcx>,
 ) {
     let &CovfunRecord {
+        _instance,
         mangled_function_name,
         source_hash,
         is_used,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
index bcfa0381cc1..6eb7042da61 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
@@ -2,9 +2,7 @@
 
 use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
 use rustc_codegen_ssa::traits::*;
-use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def_id::LOCAL_CRATE;
-use rustc_hir::find_attr;
 use rustc_middle::bug;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType;
 use rustc_session::config::{CrateType, DebugInfo};
@@ -86,9 +84,6 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
 }
 
 pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
-    let omit_gdb_pretty_printer_section =
-        find_attr!(cx.tcx.hir_krate_attrs(), AttributeKind::OmitGdbPrettyPrinterSection);
-
     // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create
     // ODR violations at link time, this section will not be emitted for rlibs since
     // each rlib could produce a different set of visualizers that would be embedded
@@ -117,8 +112,7 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
         }
     });
 
-    !omit_gdb_pretty_printer_section
-        && cx.sess().opts.debuginfo != DebugInfo::None
+    cx.sess().opts.debuginfo != DebugInfo::None
         && cx.sess().target.emit_debug_gdb_scripts
         && embed_visualizers
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 162fbf3d6e2..b69fbf61185 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1011,11 +1011,12 @@ fn link_natively(
             (Strip::Debuginfo, _) => {
                 strip_with_external_utility(sess, stripcmd, out_filename, &["--strip-debug"])
             }
-            // Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988)
+
+            // Per the manpage, --discard-all is the maximum safe strip level for dynamic libraries. (#93988)
             (
                 Strip::Symbols,
                 CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro | CrateType::Sdylib,
-            ) => strip_with_external_utility(sess, stripcmd, out_filename, &["-x"]),
+            ) => strip_with_external_utility(sess, stripcmd, out_filename, &["--discard-all"]),
             (Strip::Symbols, _) => {
                 strip_with_external_utility(sess, stripcmd, out_filename, &["--strip-all"])
             }
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index 5b3adba0265..b8a65369825 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -11,6 +11,7 @@ use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::sym;
 use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
+use tracing::field::Empty;
 use tracing::{info, instrument, trace};
 
 use super::{
@@ -18,7 +19,8 @@ use super::{
     Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, StackPopInfo, interp_ok,
     throw_ub, throw_ub_custom, throw_unsup_format,
 };
-use crate::fluent_generated as fluent;
+use crate::interpret::EnteredTraceSpan;
+use crate::{enter_trace_span, fluent_generated as fluent};
 
 /// An argument passed to a function.
 #[derive(Clone, Debug)]
@@ -344,6 +346,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         destination: &PlaceTy<'tcx, M::Provenance>,
         mut cont: ReturnContinuation,
     ) -> InterpResult<'tcx> {
+        let _span = enter_trace_span!(M, step::init_stack_frame, %instance, tracing_separate_thread = Empty);
+
         // Compute callee information.
         // FIXME: for variadic support, do we have to somehow determine callee's extra_args?
         let callee_fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;
@@ -523,7 +527,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         target: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
-        trace!("init_fn_call: {:#?}", fn_val);
+        let _span =
+            enter_trace_span!(M, step::init_fn_call, tracing_separate_thread = Empty, ?fn_val)
+                .or_if_tracing_disabled(|| trace!("init_fn_call: {:#?}", fn_val));
 
         let instance = match fn_val {
             FnVal::Instance(instance) => instance,
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 47bebf5371a..23b40894f16 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -937,8 +937,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         // (both global from `alloc_map` and local from `extra_fn_ptr_map`)
         if let Some(fn_val) = self.get_fn_alloc(id) {
             let align = match fn_val {
-                FnVal::Instance(instance) => {
-                    self.tcx.codegen_instance_attrs(instance.def).alignment.unwrap_or(Align::ONE)
+                FnVal::Instance(_instance) => {
+                    // FIXME: Until we have a clear design for the effects of align(N) functions
+                    // on the address of function pointers, we don't consider the align(N)
+                    // attribute on functions in the interpreter.
+                    // See <https://github.com/rust-lang/rust/issues/144661> for more context.
+                    Align::ONE
                 }
                 // Machine-specific extra functions currently do not support alignment restrictions.
                 FnVal::Other(_) => Align::ONE,
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 21afd082a05..14541809070 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -13,6 +13,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
 use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
 use rustc_middle::{bug, mir, span_bug, ty};
 use rustc_span::DUMMY_SP;
+use tracing::field::Empty;
 use tracing::trace;
 
 use super::{
@@ -20,6 +21,7 @@ use super::{
     OffsetMode, PlaceTy, Pointer, Projectable, Provenance, Scalar, alloc_range, err_ub,
     from_known_layout, interp_ok, mir_assign_valid_types, throw_ub,
 };
+use crate::enter_trace_span;
 
 /// An `Immediate` represents a single immediate self-contained Rust value.
 ///
@@ -186,18 +188,18 @@ pub struct ImmTy<'tcx, Prov: Provenance = CtfeProvenance> {
 impl<Prov: Provenance> std::fmt::Display for ImmTy<'_, Prov> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         /// Helper function for printing a scalar to a FmtPrinter
-        fn p<'a, 'tcx, Prov: Provenance>(
-            cx: &mut FmtPrinter<'a, 'tcx>,
+        fn print_scalar<'a, 'tcx, Prov: Provenance>(
+            p: &mut FmtPrinter<'a, 'tcx>,
             s: Scalar<Prov>,
             ty: Ty<'tcx>,
         ) -> Result<(), std::fmt::Error> {
             match s {
-                Scalar::Int(int) => cx.pretty_print_const_scalar_int(int, ty, true),
+                Scalar::Int(int) => p.pretty_print_const_scalar_int(int, ty, true),
                 Scalar::Ptr(ptr, _sz) => {
                     // Just print the ptr value. `pretty_print_const_scalar_ptr` would also try to
                     // print what is points to, which would fail since it has no access to the local
                     // memory.
-                    cx.pretty_print_const_pointer(ptr, ty)
+                    p.pretty_print_const_pointer(ptr, ty)
                 }
             }
         }
@@ -205,8 +207,9 @@ impl<Prov: Provenance> std::fmt::Display for ImmTy<'_, Prov> {
             match self.imm {
                 Immediate::Scalar(s) => {
                     if let Some(ty) = tcx.lift(self.layout.ty) {
-                        let s =
-                            FmtPrinter::print_string(tcx, Namespace::ValueNS, |cx| p(cx, s, ty))?;
+                        let s = FmtPrinter::print_string(tcx, Namespace::ValueNS, |p| {
+                            print_scalar(p, s, ty)
+                        })?;
                         f.write_str(&s)?;
                         return Ok(());
                     }
@@ -770,6 +773,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         mir_place: mir::Place<'tcx>,
         layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
+        let _span = enter_trace_span!(
+            M,
+            step::eval_place_to_op,
+            ?mir_place,
+            tracing_separate_thread = Empty
+        );
+
         // Do not use the layout passed in as argument if the base we are looking at
         // here is not the entire place.
         let layout = if mir_place.projection.is_empty() { layout } else { None };
@@ -813,6 +823,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         mir_op: &mir::Operand<'tcx>,
         layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
+        let _span =
+            enter_trace_span!(M, step::eval_operand, ?mir_op, tracing_separate_thread = Empty);
+
         use rustc_middle::mir::Operand::*;
         let op = match mir_op {
             // FIXME: do some more logic on `move` to invalidate the old location
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index e2284729efd..45c4edb8503 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -9,6 +9,7 @@ use rustc_abi::{BackendRepr, HasDataLayout, Size};
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::{bug, mir, span_bug};
+use tracing::field::Empty;
 use tracing::{instrument, trace};
 
 use super::{
@@ -16,6 +17,7 @@ use super::{
     InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy, Operand, Pointer,
     Projectable, Provenance, Scalar, alloc_range, interp_ok, mir_assign_valid_types,
 };
+use crate::enter_trace_span;
 
 #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
 /// Information required for the sound usage of a `MemPlace`.
@@ -524,6 +526,9 @@ where
         &self,
         mir_place: mir::Place<'tcx>,
     ) -> InterpResult<'tcx, PlaceTy<'tcx, M::Provenance>> {
+        let _span =
+            enter_trace_span!(M, step::eval_place, ?mir_place, tracing_separate_thread = Empty);
+
         let mut place = self.local_to_place(mir_place.local)?;
         // Using `try_fold` turned out to be bad for performance, hence the loop.
         for elem in mir_place.projection.iter() {
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index f72c4418081..d05871bfc77 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -199,6 +199,15 @@ where
         base.offset_with_meta(offset, OffsetMode::Inbounds, meta, field_layout, self)
     }
 
+    /// Projects multiple fields at once. See [`Self::project_field`] for details.
+    pub fn project_fields<P: Projectable<'tcx, M::Provenance>, const N: usize>(
+        &self,
+        base: &P,
+        fields: [FieldIdx; N],
+    ) -> InterpResult<'tcx, [P; N]> {
+        fields.try_map(|field| self.project_field(base, field))
+    }
+
     /// Downcasting to an enum variant.
     pub fn project_downcast<P: Projectable<'tcx, M::Provenance>>(
         &self,
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 629dcc3523c..9df49c0f4cc 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,13 +9,15 @@ use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::source_map::Spanned;
 use rustc_target::callconv::FnAbi;
+use tracing::field::Empty;
 use tracing::{info, instrument, trace};
 
 use super::{
     FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy,
     Projectable, Scalar, interp_ok, throw_ub, throw_unsup_format,
 };
-use crate::util;
+use crate::interpret::EnteredTraceSpan;
+use crate::{enter_trace_span, util};
 
 struct EvaluatedCalleeAndArgs<'tcx, M: Machine<'tcx>> {
     callee: FnVal<'tcx, M::ExtraFnVal>,
@@ -74,7 +76,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     ///
     /// This does NOT move the statement counter forward, the caller has to do that!
     pub fn eval_statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> {
-        info!("{:?}", stmt);
+        let _span = enter_trace_span!(
+            M,
+            step::eval_statement,
+            stmt = ?stmt.kind,
+            span = ?stmt.source_info.span,
+            tracing_separate_thread = Empty,
+        )
+        .or_if_tracing_disabled(|| info!(stmt = ?stmt.kind));
 
         use rustc_middle::mir::StatementKind::*;
 
@@ -456,7 +465,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     }
 
     fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> InterpResult<'tcx> {
-        info!("{:?}", terminator.kind);
+        let _span = enter_trace_span!(
+            M,
+            step::eval_terminator,
+            terminator = ?terminator.kind,
+            span = ?terminator.source_info.span,
+            tracing_separate_thread = Empty,
+        )
+        .or_if_tracing_disabled(|| info!(terminator = ?terminator.kind));
 
         use rustc_middle::mir::TerminatorKind::*;
         match terminator.kind {
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index 6696a0c5026..71800950faa 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -48,10 +48,24 @@ pub(crate) fn create_static_alloc<'tcx>(
 
 /// A marker trait returned by [crate::interpret::Machine::enter_trace_span], identifying either a
 /// real [tracing::span::EnteredSpan] in case tracing is enabled, or the dummy type `()` when
-/// tracing is disabled.
-pub trait EnteredTraceSpan {}
-impl EnteredTraceSpan for () {}
-impl EnteredTraceSpan for tracing::span::EnteredSpan {}
+/// tracing is disabled. Also see [crate::enter_trace_span!] below.
+pub trait EnteredTraceSpan {
+    /// Allows executing an alternative function when tracing is disabled. Useful for example if you
+    /// want to open a trace span when tracing is enabled, and alternatively just log a line when
+    /// tracing is disabled.
+    fn or_if_tracing_disabled(self, f: impl FnOnce()) -> Self;
+}
+impl EnteredTraceSpan for () {
+    fn or_if_tracing_disabled(self, f: impl FnOnce()) -> Self {
+        f(); // tracing is disabled, execute the function
+        self
+    }
+}
+impl EnteredTraceSpan for tracing::span::EnteredSpan {
+    fn or_if_tracing_disabled(self, _f: impl FnOnce()) -> Self {
+        self // tracing is enabled, don't execute anything
+    }
+}
 
 /// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span!].
 /// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the
@@ -112,6 +126,19 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan {}
 /// # type M = rustc_const_eval::const_eval::CompileTimeMachine<'static>;
 /// let _span = enter_trace_span!(M, step::eval_statement, tracing_separate_thread = tracing::field::Empty);
 /// ```
+///
+/// ### Executing something else when tracing is disabled
+///
+/// [crate::interpret::Machine::enter_trace_span] returns [EnteredTraceSpan], on which you can call
+/// [EnteredTraceSpan::or_if_tracing_disabled], to e.g. log a line as an alternative to the tracing
+/// span for when tracing is disabled. For example:
+/// ```rust
+/// # use rustc_const_eval::enter_trace_span;
+/// # use rustc_const_eval::interpret::EnteredTraceSpan;
+/// # type M = rustc_const_eval::const_eval::CompileTimeMachine<'static>;
+/// let _span = enter_trace_span!(M, step::eval_statement)
+///     .or_if_tracing_disabled(|| tracing::info!("eval_statement"));
+/// ```
 #[macro_export]
 macro_rules! enter_trace_span {
     ($machine:ty, $name:ident :: $subname:ident $($tt:tt)*) => {
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs
index a27b6646131..82c50fac6c0 100644
--- a/compiler/rustc_const_eval/src/interpret/visitor.rs
+++ b/compiler/rustc_const_eval/src/interpret/visitor.rs
@@ -121,25 +121,24 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
 
                 // `Box` has two fields: the pointer we care about, and the allocator.
                 assert_eq!(v.layout().fields.count(), 2, "`Box` must have exactly 2 fields");
-                let (unique_ptr, alloc) = (
-                    self.ecx().project_field(v, FieldIdx::ZERO)?,
-                    self.ecx().project_field(v, FieldIdx::ONE)?,
-                );
+                let [unique_ptr, alloc] =
+                    self.ecx().project_fields(v, [FieldIdx::ZERO, FieldIdx::ONE])?;
+
                 // Unfortunately there is some type junk in the way here: `unique_ptr` is a `Unique`...
                 // (which means another 2 fields, the second of which is a `PhantomData`)
                 assert_eq!(unique_ptr.layout().fields.count(), 2);
-                let (nonnull_ptr, phantom) = (
-                    self.ecx().project_field(&unique_ptr, FieldIdx::ZERO)?,
-                    self.ecx().project_field(&unique_ptr, FieldIdx::ONE)?,
-                );
+                let [nonnull_ptr, phantom] =
+                    self.ecx().project_fields(&unique_ptr, [FieldIdx::ZERO, FieldIdx::ONE])?;
                 assert!(
                     phantom.layout().ty.ty_adt_def().is_some_and(|adt| adt.is_phantom_data()),
                     "2nd field of `Unique` should be PhantomData but is {:?}",
                     phantom.layout().ty,
                 );
+
                 // ... that contains a `NonNull`... (gladly, only a single field here)
                 assert_eq!(nonnull_ptr.layout().fields.count(), 1);
                 let raw_ptr = self.ecx().project_field(&nonnull_ptr, FieldIdx::ZERO)?; // the actual raw ptr
+
                 // ... whose only field finally is a raw ptr we can dereference.
                 self.visit_box(ty, &raw_ptr)?;
 
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index bf7a79dcb20..3840cdf7575 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -2,6 +2,7 @@
 #![allow(internal_features)]
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![doc(rust_logo)]
+#![feature(array_try_map)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(decl_macro)]
diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs
index c437934eaab..5249b32eca4 100644
--- a/compiler/rustc_const_eval/src/util/caller_location.rs
+++ b/compiler/rustc_const_eval/src/util/caller_location.rs
@@ -42,12 +42,12 @@ fn alloc_caller_location<'tcx>(
     let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
 
     // Initialize fields.
-    ecx.write_immediate(filename, &ecx.project_field(&location, FieldIdx::from_u32(0)).unwrap())
-        .expect("writing to memory we just allocated cannot fail");
-    ecx.write_scalar(line, &ecx.project_field(&location, FieldIdx::from_u32(1)).unwrap())
-        .expect("writing to memory we just allocated cannot fail");
-    ecx.write_scalar(col, &ecx.project_field(&location, FieldIdx::from_u32(2)).unwrap())
+    let [filename_field, line_field, col_field] =
+        ecx.project_fields(&location, [0, 1, 2].map(FieldIdx::from_u32)).unwrap();
+    ecx.write_immediate(filename, &filename_field)
         .expect("writing to memory we just allocated cannot fail");
+    ecx.write_scalar(line, &line_field).expect("writing to memory we just allocated cannot fail");
+    ecx.write_scalar(col, &col_field).expect("writing to memory we just allocated cannot fail");
 
     location
 }
diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index e8f2728a772..e6b9759819f 100644
--- a/compiler/rustc_const_eval/src/util/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::DisambiguatedDefPathData;
 use rustc_middle::bug;
-use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
+use rustc_middle::ty::print::{PrettyPrinter, PrintError, Printer};
 use rustc_middle::ty::{self, GenericArg, GenericArgKind, Ty, TyCtxt};
 
 struct AbsolutePathPrinter<'tcx> {
@@ -18,7 +18,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
     }
 
     fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
-        Ok(())
+        unreachable!(); // because `<Self As PrettyPrinter>::should_print_region` returns false
     }
 
     fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
@@ -89,7 +89,6 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
     fn path_append_impl(
         &mut self,
         print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
-        _disambiguated_data: &DisambiguatedDefPathData,
         self_ty: Ty<'tcx>,
         trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError> {
@@ -138,19 +137,6 @@ impl<'tcx> PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> {
     fn should_print_region(&self, _region: ty::Region<'_>) -> bool {
         false
     }
-    fn comma_sep<T>(&mut self, mut elems: impl Iterator<Item = T>) -> Result<(), PrintError>
-    where
-        T: Print<'tcx, Self>,
-    {
-        if let Some(first) = elems.next() {
-            first.print(self)?;
-            for elem in elems {
-                self.path.push_str(", ");
-                elem.print(self)?;
-            }
-        }
-        Ok(())
-    }
 
     fn generic_delimiters(
         &mut self,
@@ -179,7 +165,7 @@ impl Write for AbsolutePathPrinter<'_> {
 }
 
 pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> String {
-    let mut printer = AbsolutePathPrinter { tcx, path: String::new() };
-    printer.print_type(ty).unwrap();
-    printer.path
+    let mut p = AbsolutePathPrinter { tcx, path: String::new() };
+    p.print_type(ty).unwrap();
+    p.path
 }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0562.md b/compiler/rustc_error_codes/src/error_codes/E0562.md
index 95f038df56d..af7b219fb12 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0562.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0562.md
@@ -1,5 +1,4 @@
-Abstract return types (written `impl Trait` for some trait `Trait`) are only
-allowed as function and inherent impl return types.
+`impl Trait` is only allowed as a function return and argument type.
 
 Erroneous code example:
 
@@ -14,7 +13,7 @@ fn main() {
 }
 ```
 
-Make sure `impl Trait` only appears in return-type position.
+Make sure `impl Trait` appears in a function signature.
 
 ```
 fn count_to_n(n: usize) -> impl Iterator<Item=usize> {
@@ -28,6 +27,6 @@ fn main() {
 }
 ```
 
-See [RFC 1522] for more details.
+See the [reference] for more details on `impl Trait`.
 
-[RFC 1522]: https://github.com/rust-lang/rfcs/blob/master/text/1522-conservative-impl-trait.md
+[reference]: https://doc.rust-lang.org/stable/reference/types/impl-trait.html
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 8794bf930fd..84970e7c162 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -262,19 +262,11 @@ pub trait Emitter {
                     format!("help: {msg}")
                 } else {
                     // Show the default suggestion text with the substitution
-                    format!(
-                        "help: {}{}: `{}`",
-                        msg,
-                        if self
-                            .source_map()
-                            .is_some_and(|sm| is_case_difference(sm, snippet, part.span,))
-                        {
-                            " (notice the capitalization)"
-                        } else {
-                            ""
-                        },
-                        snippet,
-                    )
+                    let confusion_type = self
+                        .source_map()
+                        .map(|sm| detect_confusion_type(sm, snippet, part.span))
+                        .unwrap_or(ConfusionType::None);
+                    format!("help: {}{}: `{}`", msg, confusion_type.label_text(), snippet,)
                 };
                 primary_span.push_span_label(part.span, msg);
 
@@ -2031,12 +2023,12 @@ impl HumanEmitter {
         buffer.append(0, ": ", Style::HeaderMsg);
 
         let mut msg = vec![(suggestion.msg.to_owned(), Style::NoStyle)];
-        if suggestions
-            .iter()
-            .take(MAX_SUGGESTIONS)
-            .any(|(_, _, _, only_capitalization)| *only_capitalization)
+        if let Some(confusion_type) =
+            suggestions.iter().take(MAX_SUGGESTIONS).find_map(|(_, _, _, confusion_type)| {
+                if confusion_type.has_confusion() { Some(*confusion_type) } else { None }
+            })
         {
-            msg.push((" (notice the capitalization difference)".into(), Style::NoStyle));
+            msg.push((confusion_type.label_text().into(), Style::NoStyle));
         }
         self.msgs_to_buffer(
             &mut buffer,
@@ -3531,24 +3523,107 @@ pub fn is_different(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
 }
 
 /// Whether the original and suggested code are visually similar enough to warrant extra wording.
-pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
-    // FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode.
+pub fn detect_confusion_type(sm: &SourceMap, suggested: &str, sp: Span) -> ConfusionType {
     let found = match sm.span_to_snippet(sp) {
         Ok(snippet) => snippet,
         Err(e) => {
             warn!(error = ?e, "Invalid span {:?}", sp);
-            return false;
+            return ConfusionType::None;
         }
     };
-    let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
-    // All the chars that differ in capitalization are confusable (above):
-    let confusable = iter::zip(found.chars(), suggested.chars())
-        .filter(|(f, s)| f != s)
-        .all(|(f, s)| ascii_confusables.contains(&f) || ascii_confusables.contains(&s));
-    confusable && found.to_lowercase() == suggested.to_lowercase()
-            // FIXME: We sometimes suggest the same thing we already have, which is a
-            //        bug, but be defensive against that here.
-            && found != suggested
+
+    let mut has_case_confusion = false;
+    let mut has_digit_letter_confusion = false;
+
+    if found.len() == suggested.len() {
+        let mut has_case_diff = false;
+        let mut has_digit_letter_confusable = false;
+        let mut has_other_diff = false;
+
+        let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
+
+        let digit_letter_confusables = [('0', 'O'), ('1', 'l'), ('5', 'S'), ('8', 'B'), ('9', 'g')];
+
+        for (f, s) in iter::zip(found.chars(), suggested.chars()) {
+            if f != s {
+                if f.to_lowercase().to_string() == s.to_lowercase().to_string() {
+                    // Check for case differences (any character that differs only in case)
+                    if ascii_confusables.contains(&f) || ascii_confusables.contains(&s) {
+                        has_case_diff = true;
+                    } else {
+                        has_other_diff = true;
+                    }
+                } else if digit_letter_confusables.contains(&(f, s))
+                    || digit_letter_confusables.contains(&(s, f))
+                {
+                    // Check for digit-letter confusables (like 0 vs O, 1 vs l, etc.)
+                    has_digit_letter_confusable = true;
+                } else {
+                    has_other_diff = true;
+                }
+            }
+        }
+
+        // If we have case differences and no other differences
+        if has_case_diff && !has_other_diff && found != suggested {
+            has_case_confusion = true;
+        }
+        if has_digit_letter_confusable && !has_other_diff && found != suggested {
+            has_digit_letter_confusion = true;
+        }
+    }
+
+    match (has_case_confusion, has_digit_letter_confusion) {
+        (true, true) => ConfusionType::Both,
+        (true, false) => ConfusionType::Case,
+        (false, true) => ConfusionType::DigitLetter,
+        (false, false) => ConfusionType::None,
+    }
+}
+
+/// Represents the type of confusion detected between original and suggested code.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum ConfusionType {
+    /// No confusion detected
+    None,
+    /// Only case differences (e.g., "hello" vs "Hello")
+    Case,
+    /// Only digit-letter confusion (e.g., "0" vs "O", "1" vs "l")
+    DigitLetter,
+    /// Both case and digit-letter confusion
+    Both,
+}
+
+impl ConfusionType {
+    /// Returns the appropriate label text for this confusion type.
+    pub fn label_text(&self) -> &'static str {
+        match self {
+            ConfusionType::None => "",
+            ConfusionType::Case => " (notice the capitalization)",
+            ConfusionType::DigitLetter => " (notice the digit/letter confusion)",
+            ConfusionType::Both => " (notice the capitalization and digit/letter confusion)",
+        }
+    }
+
+    /// Combines two confusion types. If either is `Both`, the result is `Both`.
+    /// If one is `Case` and the other is `DigitLetter`, the result is `Both`.
+    /// Otherwise, returns the non-`None` type, or `None` if both are `None`.
+    pub fn combine(self, other: ConfusionType) -> ConfusionType {
+        match (self, other) {
+            (ConfusionType::None, other) => other,
+            (this, ConfusionType::None) => this,
+            (ConfusionType::Both, _) | (_, ConfusionType::Both) => ConfusionType::Both,
+            (ConfusionType::Case, ConfusionType::DigitLetter)
+            | (ConfusionType::DigitLetter, ConfusionType::Case) => ConfusionType::Both,
+            (ConfusionType::Case, ConfusionType::Case) => ConfusionType::Case,
+            (ConfusionType::DigitLetter, ConfusionType::DigitLetter) => ConfusionType::DigitLetter,
+        }
+    }
+
+    /// Returns true if this confusion type represents any kind of confusion.
+    pub fn has_confusion(&self) -> bool {
+        *self != ConfusionType::None
+    }
 }
 
 pub(crate) fn should_show_source_code(
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 381d780077d..2534cddf105 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -50,7 +50,7 @@ pub use diagnostic_impls::{
     IndicateAnonymousLifetime, SingleLabelManySpans,
 };
 pub use emitter::ColorConfig;
-use emitter::{DynEmitter, Emitter, is_case_difference, is_different};
+use emitter::{ConfusionType, DynEmitter, Emitter, detect_confusion_type, is_different};
 use rustc_data_structures::AtomicRef;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::stable_hasher::StableHasher;
@@ -308,7 +308,7 @@ impl CodeSuggestion {
     pub(crate) fn splice_lines(
         &self,
         sm: &SourceMap,
-    ) -> Vec<(String, Vec<SubstitutionPart>, Vec<Vec<SubstitutionHighlight>>, bool)> {
+    ) -> Vec<(String, Vec<SubstitutionPart>, Vec<Vec<SubstitutionHighlight>>, ConfusionType)> {
         // For the `Vec<Vec<SubstitutionHighlight>>` value, the first level of the vector
         // corresponds to the output snippet's lines, while the second level corresponds to the
         // substrings within that line that should be highlighted.
@@ -414,14 +414,15 @@ impl CodeSuggestion {
                 // We need to keep track of the difference between the existing code and the added
                 // or deleted code in order to point at the correct column *after* substitution.
                 let mut acc = 0;
-                let mut only_capitalization = false;
+                let mut confusion_type = ConfusionType::None;
                 for part in &mut substitution.parts {
                     // If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the
                     // suggestion and snippet to look as if we just suggested to add
                     // `"b"`, which is typically much easier for the user to understand.
                     part.trim_trivial_replacements(sm);
 
-                    only_capitalization |= is_case_difference(sm, &part.snippet, part.span);
+                    let part_confusion = detect_confusion_type(sm, &part.snippet, part.span);
+                    confusion_type = confusion_type.combine(part_confusion);
                     let cur_lo = sm.lookup_char_pos(part.span.lo());
                     if prev_hi.line == cur_lo.line {
                         let mut count =
@@ -511,7 +512,7 @@ impl CodeSuggestion {
                 if highlights.iter().all(|parts| parts.is_empty()) {
                     None
                 } else {
-                    Some((buf, substitution.parts, highlights, only_capitalization))
+                    Some((buf, substitution.parts, highlights, confusion_type))
                 }
             })
             .collect()
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 0517fd0419d..f02aa6c120f 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1411,9 +1411,8 @@ impl InvocationCollectorNode for P<ast::Item> {
                     }
                 }
             }
-
             let mut idents = Vec::new();
-            collect_use_tree_leaves(ut, &mut idents);
+            collect_use_tree_leaves(&ut, &mut idents);
             idents
         } else {
             self.kind.ident().into_iter().collect()
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index ceb7fc5bf6f..5c63d4808db 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -1257,11 +1257,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/),
         DuplicatesOk, EncodeCrossCrate::No
     ),
-    gated!(
-        omit_gdb_pretty_printer_section, Normal, template!(Word),
-        WarnFollowing, EncodeCrossCrate::No,
-        "the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
-    ),
     rustc_attr!(
         TEST, pattern_complexity_limit, CrateLevel, template!(NameValueStr: "N"),
         ErrorFollowing, EncodeCrossCrate::No,
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 7e174c465d5..4eee79a2a71 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -199,6 +199,8 @@ declare_features! (
     /// Renamed to `dyn_compatible_for_dispatch`.
     (removed, object_safe_for_dispatch, "1.83.0", Some(43561),
      Some("renamed to `dyn_compatible_for_dispatch`"), 131511),
+    /// Allows using `#[omit_gdb_pretty_printer_section]`.
+    (removed, omit_gdb_pretty_printer_section, "CURRENT_RUSTC_VERSION", None, None, 144738),
     /// Allows using `#[on_unimplemented(..)]` on traits.
     /// (Moved to `rustc_attrs`.)
     (removed, on_unimplemented, "1.40.0", None, None, 65794),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index e985e04ba33..1303b3317e0 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -225,8 +225,6 @@ declare_features! (
     (unstable, multiple_supertrait_upcastable, "1.69.0", None),
     /// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
     (internal, negative_bounds, "1.71.0", None),
-    /// Allows using `#[omit_gdb_pretty_printer_section]`.
-    (internal, omit_gdb_pretty_printer_section, "1.5.0", None),
     /// Set the maximum pattern complexity allowed (not limited by default).
     (internal, pattern_complexity_limit, "1.78.0", None),
     /// Allows using pattern types.
diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
index 80f5e6177f7..80618422b56 100644
--- a/compiler/rustc_hir/src/attrs/data_structures.rs
+++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -391,9 +391,6 @@ pub enum AttributeKind {
     /// Represents `#[non_exhaustive]`
     NonExhaustive(Span),
 
-    /// Represents `#[omit_gdb_pretty_printer_section]`
-    OmitGdbPrettyPrinterSection,
-
     /// Represents `#[optimize(size|speed)]`
     Optimize(OptimizeAttr, Span),
 
diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
index bbdecb2986e..9644a597a31 100644
--- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
+++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
@@ -55,7 +55,6 @@ impl AttributeKind {
             NoImplicitPrelude(..) => No,
             NoMangle(..) => Yes,      // Needed for rustdoc
             NonExhaustive(..) => Yes, // Needed for rustdoc
-            OmitGdbPrettyPrinterSection => No,
             Optimize(..) => No,
             ParenSugar(..) => No,
             PassByValue(..) => Yes,
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 3fee9af01b3..2201d493f2d 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -360,7 +360,7 @@ impl DefKind {
 /// For example, everything prefixed with `/* Res */` in this example has
 /// an associated `Res`:
 ///
-/// ```
+/// ```ignore (illustrative)
 /// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
 ///     /* Res */ String::from(/* Res */ s)
 /// }
@@ -421,7 +421,7 @@ pub enum Res<Id = hir::HirId> {
     /// }
     ///
     /// impl Foo for Bar {
-    ///     fn foo() -> Box<Self> { // SelfTyAlias
+    ///     fn foo() -> Box<Self /* SelfTyAlias */> {
     ///         let _: Self;        // SelfTyAlias
     ///
     ///         todo!()
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1b1b3ced44d..c30c830f9af 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -412,10 +412,8 @@ impl<'hir> PathSegment<'hir> {
 /// that are [just paths](ConstArgKind::Path) (currently just bare const params)
 /// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`).
 ///
-/// The `Unambig` generic parameter represents whether the position this const is from is
-/// unambiguously a const or ambiguous as to whether it is a type or a const. When in an
-/// ambiguous context the parameter is instantiated with an uninhabited type making the
-/// [`ConstArgKind::Infer`] variant unusable and [`GenericArg::Infer`] is used instead.
+/// For an explanation of the `Unambig` generic parameter see the dev-guide:
+/// <https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html>
 #[derive(Clone, Copy, Debug, HashStable_Generic)]
 #[repr(C)]
 pub struct ConstArg<'hir, Unambig = ()> {
@@ -427,7 +425,7 @@ pub struct ConstArg<'hir, Unambig = ()> {
 impl<'hir> ConstArg<'hir, AmbigArg> {
     /// Converts a `ConstArg` in an ambiguous position to one in an unambiguous position.
     ///
-    /// Functions accepting an unambiguous consts may expect the [`ConstArgKind::Infer`] variant
+    /// Functions accepting unambiguous consts may expect the [`ConstArgKind::Infer`] variant
     /// to be used. Care should be taken to separately handle infer consts when calling this
     /// function as it cannot be handled by downstream code making use of the returned const.
     ///
@@ -3016,7 +3014,7 @@ impl fmt::Display for LoopIdError {
     }
 }
 
-#[derive(Copy, Clone, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
 pub struct Destination {
     /// This is `Some(_)` iff there is an explicit user-specified 'label
     pub label: Option<Label>,
@@ -3314,14 +3312,12 @@ impl<'hir> AssocItemConstraintKind<'hir> {
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum AmbigArg {}
 
-#[derive(Debug, Clone, Copy, HashStable_Generic)]
-#[repr(C)]
 /// Represents a type in the `HIR`.
 ///
-/// The `Unambig` generic parameter represents whether the position this type is from is
-/// unambiguously a type or ambiguous as to whether it is a type or a const. When in an
-/// ambiguous context the parameter is instantiated with an uninhabited type making the
-/// [`TyKind::Infer`] variant unusable and [`GenericArg::Infer`] is used instead.
+/// For an explanation of the `Unambig` generic parameter see the dev-guide:
+/// <https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html>
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
+#[repr(C)]
 pub struct Ty<'hir, Unambig = ()> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -3656,9 +3652,12 @@ pub enum InferDelegationKind {
 }
 
 /// The various kinds of types recognized by the compiler.
-#[derive(Debug, Clone, Copy, HashStable_Generic)]
+///
+/// For an explanation of the `Unambig` generic parameter see the dev-guide:
+/// <https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html>
 // SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
 #[repr(u8, C)]
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum TyKind<'hir, Unambig = ()> {
     /// Actual type should be inherited from `DefId` signature
     InferDelegation(DefId, InferDelegationKind),
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index f33915d5b07..23fa466859a 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -364,9 +364,6 @@ pub trait Visitor<'v>: Sized {
     /// All types are treated as ambiguous types for the purposes of hir visiting in
     /// order to ensure that visitors can handle infer vars without it being too error-prone.
     ///
-    /// See the doc comments on [`Ty`] for an explanation of what it means for a type to be
-    /// ambiguous.
-    ///
     /// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars.
     fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) -> Self::Result {
         walk_ty(self, t)
@@ -375,12 +372,9 @@ pub trait Visitor<'v>: Sized {
     /// All consts are treated as ambiguous consts for the purposes of hir visiting in
     /// order to ensure that visitors can handle infer vars without it being too error-prone.
     ///
-    /// See the doc comments on [`ConstArg`] for an explanation of what it means for a const to be
-    /// ambiguous.
-    ///
     /// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars.
     fn visit_const_arg(&mut self, c: &'v ConstArg<'v, AmbigArg>) -> Self::Result {
-        walk_ambig_const_arg(self, c)
+        walk_const_arg(self, c)
     }
 
     #[allow(unused_variables)]
@@ -522,7 +516,7 @@ pub trait VisitorExt<'v>: Visitor<'v> {
     /// Named `visit_const_arg_unambig` instead of `visit_unambig_const_arg` to aid in
     /// discovery by IDes when `v.visit_const_arg` is written.
     fn visit_const_arg_unambig(&mut self, c: &'v ConstArg<'v>) -> Self::Result {
-        walk_const_arg(self, c)
+        walk_unambig_const_arg(self, c)
     }
 }
 impl<'v, V: Visitor<'v>> VisitorExt<'v> for V {}
@@ -985,7 +979,6 @@ pub fn walk_unambig_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) ->
         Some(ambig_ty) => visitor.visit_ty(ambig_ty),
         None => {
             let Ty { hir_id, span, kind: _ } = typ;
-            try_visit!(visitor.visit_id(*hir_id));
             visitor.visit_infer(*hir_id, *span, InferKind::Ty(typ))
         }
     }
@@ -1043,7 +1036,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) -
     V::Result::output()
 }
 
-pub fn walk_const_arg<'v, V: Visitor<'v>>(
+pub fn walk_unambig_const_arg<'v, V: Visitor<'v>>(
     visitor: &mut V,
     const_arg: &'v ConstArg<'v>,
 ) -> V::Result {
@@ -1051,13 +1044,12 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
         Some(ambig_ct) => visitor.visit_const_arg(ambig_ct),
         None => {
             let ConstArg { hir_id, kind: _ } = const_arg;
-            try_visit!(visitor.visit_id(*hir_id));
             visitor.visit_infer(*hir_id, const_arg.span(), InferKind::Const(const_arg))
         }
     }
 }
 
-pub fn walk_ambig_const_arg<'v, V: Visitor<'v>>(
+pub fn walk_const_arg<'v, V: Visitor<'v>>(
     visitor: &mut V,
     const_arg: &'v ConstArg<'v, AmbigArg>,
 ) -> V::Result {
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 e24426f9fed..6767e5ed88d 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -356,14 +356,14 @@ fn compare_method_predicate_entailment<'tcx>(
     }
 
     if !(impl_sig, trait_sig).references_error() {
-        ocx.register_obligation(traits::Obligation::new(
-            infcx.tcx,
-            cause,
-            param_env,
-            ty::ClauseKind::WellFormed(
-                Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig)).into(),
-            ),
-        ));
+        for ty in unnormalized_impl_sig.inputs_and_output {
+            ocx.register_obligation(traits::Obligation::new(
+                infcx.tcx,
+                cause.clone(),
+                param_env,
+                ty::ClauseKind::WellFormed(ty.into()),
+            ));
+        }
     }
 
     // Check that all obligations are satisfied by the implementation's
@@ -425,7 +425,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> {
 ///
 /// trait Foo {
 ///     fn bar() -> impl Deref<Target = impl Sized>;
-///              // ^- RPITIT #1        ^- RPITIT #2
+///     //          ^- RPITIT #1        ^- RPITIT #2
 /// }
 ///
 /// impl Foo for () {
@@ -2498,7 +2498,7 @@ fn param_env_with_gat_bounds<'tcx>(
                     ty::Const::new_bound(
                         tcx,
                         ty::INNERMOST,
-                        ty::BoundVar::from_usize(bound_vars.len() - 1),
+                        ty::BoundConst { var: ty::BoundVar::from_usize(bound_vars.len() - 1) },
                     )
                     .into()
                 }
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index b2cfab37c1f..85445cb3c00 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -493,7 +493,7 @@ fn suggestion_signature<'tcx>(
     let args = ty::GenericArgs::identity_for_item(tcx, assoc.def_id).rebase_onto(
         tcx,
         assoc.container_id(tcx),
-        impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).args,
+        impl_trait_ref.with_replaced_self_ty(tcx, tcx.types.self_param).args,
     );
 
     match assoc.kind {
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 31e9c3b80fb..e2462c2d465 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -379,20 +379,14 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
         // for info on the usage of each of these fields.
         let dummy_args = match kind {
             ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
-            ClosureKind::Coroutine(_) => &[
-                "<coroutine_kind>",
-                "<resume_ty>",
-                "<yield_ty>",
-                "<return_ty>",
-                "<witness>",
-                "<upvars>",
-            ][..],
+            ClosureKind::Coroutine(_) => {
+                &["<coroutine_kind>", "<resume_ty>", "<yield_ty>", "<return_ty>", "<upvars>"][..]
+            }
             ClosureKind::CoroutineClosure(_) => &[
                 "<closure_kind>",
                 "<closure_signature_parts>",
                 "<upvars>",
                 "<bound_captures_by_ref>",
-                "<witness>",
             ][..],
         };
 
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 548ba343aae..ba54fa8cc0d 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -189,7 +189,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
             }
             ty::GenericArgKind::Const(ct) => {
                 if let ty::ConstKind::Bound(ty::INNERMOST, bv) = ct.kind() {
-                    mapping.insert(bv, tcx.mk_param_from_def(param))
+                    mapping.insert(bv.var, tcx.mk_param_from_def(param))
                 } else {
                     return None;
                 }
@@ -307,16 +307,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
             return ct;
         }
 
-        if let ty::ConstKind::Bound(binder, old_var) = ct.kind()
+        if let ty::ConstKind::Bound(binder, old_bound) = ct.kind()
             && self.binder == binder
         {
-            let mapped = if let Some(mapped) = self.mapping.get(&old_var) {
+            let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
                 mapped.expect_const()
             } else {
                 let var = ty::BoundVar::from_usize(self.still_bound_vars.len());
                 self.still_bound_vars.push(ty::BoundVariableKind::Const);
-                let mapped = ty::Const::new_bound(self.tcx, ty::INNERMOST, var);
-                self.mapping.insert(old_var, mapped.into());
+                let mapped = ty::Const::new_bound(self.tcx, ty::INNERMOST, ty::BoundConst { var });
+                self.mapping.insert(old_bound.var, mapped.into());
                 mapped
             };
 
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 7760642d8fb..386e1091ac4 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -1077,7 +1077,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
             ty::ConstKind::Param(param) => {
                 self.params.insert(param.index);
             }
-            ty::ConstKind::Bound(db, ty::BoundVar { .. }) if db >= self.depth => {
+            ty::ConstKind::Bound(db, _) if db >= self.depth => {
                 let guar = self.cx.dcx().delayed_bug("unexpected escaping late-bound const var");
                 return ControlFlow::Break(guar);
             }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index f73442fdebd..3e446b7c656 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -888,8 +888,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
                     // `<Foo as Iterator>::Item = String`.
                     let projection_term = pred.projection_term;
-                    let quiet_projection_term =
-                        projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
+                    let quiet_projection_term = projection_term
+                        .with_replaced_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
 
                     let term = pred.term;
                     let obligation = format!("{projection_term} = {term}");
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 3daeb548a79..7e2bfa9f920 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2107,9 +2107,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let name = tcx.item_name(param_def_id);
                 ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
             }
-            Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
-                ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
-            }
+            Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => ty::Const::new_bound(
+                tcx,
+                debruijn,
+                ty::BoundConst { var: ty::BoundVar::from_u32(index) },
+            ),
             Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
             arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
         }
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index a413f805873..82b7c578a1f 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -161,8 +161,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Resume type defaults to `()` if the coroutine has no argument.
                 let resume_ty = liberated_sig.inputs().get(0).copied().unwrap_or(tcx.types.unit);
 
-                let interior = Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args);
-
                 // Coroutines that come from coroutine closures have not yet determined
                 // their kind ty, so make a fresh infer var which will be constrained
                 // later during upvar analysis. Regular coroutines always have the kind
@@ -182,7 +180,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         resume_ty,
                         yield_ty,
                         return_ty: liberated_sig.output(),
-                        witness: interior,
                         tupled_upvars_ty,
                     },
                 );
@@ -210,7 +207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 };
                 // Compute all of the variables that will be used to populate the coroutine.
                 let resume_ty = self.next_ty_var(expr_span);
-                let interior = self.next_ty_var(expr_span);
 
                 let closure_kind_ty = match expected_kind {
                     Some(kind) => Ty::from_closure_kind(tcx, kind),
@@ -243,7 +239,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ),
                         tupled_upvars_ty,
                         coroutine_captures_by_ref_ty,
-                        coroutine_witness_ty: interior,
                     },
                 );
 
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 9a4c6f98a48..e66601631fc 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1800,11 +1800,13 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                             .kind()
                             .map_bound(|clause| match clause {
                                 ty::ClauseKind::Trait(trait_pred) => Some(ty::ClauseKind::Trait(
-                                    trait_pred.with_self_ty(fcx.tcx, ty),
+                                    trait_pred.with_replaced_self_ty(fcx.tcx, ty),
                                 )),
-                                ty::ClauseKind::Projection(proj_pred) => Some(
-                                    ty::ClauseKind::Projection(proj_pred.with_self_ty(fcx.tcx, ty)),
-                                ),
+                                ty::ClauseKind::Projection(proj_pred) => {
+                                    Some(ty::ClauseKind::Projection(
+                                        proj_pred.with_replaced_self_ty(fcx.tcx, ty),
+                                    ))
+                                }
                                 _ => None,
                             })
                             .transpose()?;
diff --git a/compiler/rustc_hir_typeck/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs
index d47a3246964..acfa5c473aa 100644
--- a/compiler/rustc_hir_typeck/src/loops.rs
+++ b/compiler/rustc_hir_typeck/src/loops.rs
@@ -2,7 +2,6 @@ use std::collections::BTreeMap;
 use std::fmt;
 
 use Context::*;
-use rustc_ast::Label;
 use rustc_hir as hir;
 use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::DefKind;
@@ -42,8 +41,8 @@ enum Context {
     ConstBlock,
     /// E.g. `#[loop_match] loop { state = 'label: { /* ... */ } }`.
     LoopMatch {
-        /// The label of the labeled block (not of the loop itself).
-        labeled_block: Label,
+        /// The destination pointing to the labeled block (not to the loop itself).
+        labeled_block: Destination,
     },
 }
 
@@ -186,18 +185,18 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
             {
                 self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b));
             }
-            hir::ExprKind::Break(break_label, ref opt_expr) => {
+            hir::ExprKind::Break(break_destination, ref opt_expr) => {
                 if let Some(e) = opt_expr {
                     self.visit_expr(e);
                 }
 
-                if self.require_label_in_labeled_block(e.span, &break_label, "break") {
+                if self.require_label_in_labeled_block(e.span, &break_destination, "break") {
                     // If we emitted an error about an unlabeled break in a labeled
                     // block, we don't need any further checking for this break any more
                     return;
                 }
 
-                let loop_id = match break_label.target_id {
+                let loop_id = match break_destination.target_id {
                     Ok(loop_id) => Some(loop_id),
                     Err(hir::LoopIdError::OutsideLoopScope) => None,
                     Err(hir::LoopIdError::UnlabeledCfInWhileCondition) => {
@@ -212,18 +211,25 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
 
                 // A `#[const_continue]` must break to a block in a `#[loop_match]`.
                 if find_attr!(self.tcx.hir_attrs(e.hir_id), AttributeKind::ConstContinue(_)) {
-                    if let Some(break_label) = break_label.label {
-                        let is_target_label = |cx: &Context| match cx {
-                            Context::LoopMatch { labeled_block } => {
-                                break_label.ident.name == labeled_block.ident.name
-                            }
-                            _ => false,
-                        };
+                    let Some(label) = break_destination.label else {
+                        let span = e.span;
+                        self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
+                    };
 
-                        if !self.cx_stack.iter().rev().any(is_target_label) {
-                            let span = break_label.ident.span;
-                            self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
+                    let is_target_label = |cx: &Context| match cx {
+                        Context::LoopMatch { labeled_block } => {
+                            // NOTE: with macro expansion, the label's span might be different here
+                            // even though it does still refer to the same HIR node. A block
+                            // can't have two labels, so the hir_id is a unique identifier.
+                            assert!(labeled_block.target_id.is_ok()); // see `is_loop_match`.
+                            break_destination.target_id == labeled_block.target_id
                         }
+                        _ => false,
+                    };
+
+                    if !self.cx_stack.iter().rev().any(is_target_label) {
+                        let span = label.ident.span;
+                        self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
                     }
                 }
 
@@ -249,7 +255,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
                         Some(kind) => {
                             let suggestion = format!(
                                 "break{}",
-                                break_label
+                                break_destination
                                     .label
                                     .map_or_else(String::new, |l| format!(" {}", l.ident))
                             );
@@ -259,7 +265,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
                                 kind: kind.name(),
                                 suggestion,
                                 loop_label,
-                                break_label: break_label.label,
+                                break_label: break_destination.label,
                                 break_expr_kind: &break_expr.kind,
                                 break_expr_span: break_expr.span,
                             });
@@ -268,7 +274,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
                 }
 
                 let sp_lo = e.span.with_lo(e.span.lo() + BytePos("break".len() as u32));
-                let label_sp = match break_label.label {
+                let label_sp = match break_destination.label {
                     Some(label) => sp_lo.with_hi(label.ident.span.hi()),
                     None => sp_lo.shrink_to_lo(),
                 };
@@ -416,7 +422,7 @@ impl<'hir> CheckLoopVisitor<'hir> {
         &self,
         e: &'hir hir::Expr<'hir>,
         body: &'hir hir::Block<'hir>,
-    ) -> Option<Label> {
+    ) -> Option<Destination> {
         if !find_attr!(self.tcx.hir_attrs(e.hir_id), AttributeKind::LoopMatch(_)) {
             return None;
         }
@@ -438,8 +444,8 @@ impl<'hir> CheckLoopVisitor<'hir> {
 
         let hir::ExprKind::Assign(_, rhs_expr, _) = loop_body_expr.kind else { return None };
 
-        let hir::ExprKind::Block(_, label) = rhs_expr.kind else { return None };
+        let hir::ExprKind::Block(block, label) = rhs_expr.kind else { return None };
 
-        label
+        Some(Destination { label, target_id: Ok(block.hir_id) })
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 8d9f7eaf177..a23910a2006 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -116,7 +116,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         // If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that
         // something which derefs to `Self` actually implements the trait and the caller
         // wanted to make a static dispatch on it but forgot to import the trait.
-        // See test `tests/ui/issue-35976.rs`.
+        // See test `tests/ui/issues/issue-35976.rs`.
         //
         // In that case, we'll error anyway, but we'll also re-run the search with all traits
         // in scope, and if we find another method which can be used, we'll output an
@@ -142,7 +142,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
         let (method_sig, method_predicates) =
             self.normalize(self.span, (method_sig, method_predicates));
-        let method_sig = ty::Binder::dummy(method_sig);
 
         // Make sure nobody calls `drop()` explicitly.
         self.check_for_illegal_method_calls(pick);
@@ -154,20 +153,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         // We won't add these if we encountered an illegal sized bound, so that we can use
         // a custom error in that case.
         if illegal_sized_bound.is_none() {
-            self.add_obligations(
-                Ty::new_fn_ptr(self.tcx, method_sig),
-                all_args,
-                method_predicates,
-                pick.item.def_id,
-            );
+            self.add_obligations(method_sig, all_args, method_predicates, pick.item.def_id);
         }
 
         // Create the final `MethodCallee`.
-        let callee = MethodCallee {
-            def_id: pick.item.def_id,
-            args: all_args,
-            sig: method_sig.skip_binder(),
-        };
+        let callee = MethodCallee { def_id: pick.item.def_id, args: all_args, sig: method_sig };
         ConfirmResult { callee, illegal_sized_bound }
     }
 
@@ -601,14 +591,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
     fn add_obligations(
         &mut self,
-        fty: Ty<'tcx>,
+        sig: ty::FnSig<'tcx>,
         all_args: GenericArgsRef<'tcx>,
         method_predicates: ty::InstantiatedPredicates<'tcx>,
         def_id: DefId,
     ) {
         debug!(
-            "add_obligations: fty={:?} all_args={:?} method_predicates={:?} def_id={:?}",
-            fty, all_args, method_predicates, def_id
+            "add_obligations: sig={:?} all_args={:?} method_predicates={:?} def_id={:?}",
+            sig, all_args, method_predicates, def_id
         );
 
         // FIXME: could replace with the following, but we already calculated `method_predicates`,
@@ -637,7 +627,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         // the function type must also be well-formed (this is not
         // implied by the args being well-formed because of inherent
         // impls and late-bound regions - see issue #28609).
-        self.register_wf_obligation(fty.into(), self.span, ObligationCauseCode::WellFormed(None));
+        for ty in sig.inputs_and_output {
+            self.register_wf_obligation(
+                ty.into(),
+                self.span,
+                ObligationCauseCode::WellFormed(None),
+            );
+        }
     }
 
     ///////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 316468b0a5d..e37ea031672 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -428,19 +428,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ));
 
         // Also add an obligation for the method type being well-formed.
-        let method_ty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(fn_sig));
         debug!(
-            "lookup_method_in_trait: matched method method_ty={:?} obligation={:?}",
-            method_ty, obligation
+            "lookup_method_in_trait: matched method fn_sig={:?} obligation={:?}",
+            fn_sig, obligation
         );
-        obligations.push(traits::Obligation::new(
-            tcx,
-            obligation.cause,
-            self.param_env,
-            ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
-                method_ty.into(),
-            ))),
-        ));
+        for ty in fn_sig.inputs_and_output {
+            obligations.push(traits::Obligation::new(
+                tcx,
+                obligation.cause.clone(),
+                self.param_env,
+                ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty.into()))),
+            ));
+        }
 
         let callee = MethodCallee { def_id, args, sig: fn_sig };
         debug!("callee = {:?}", callee);
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 1f3969bd93c..3ca3b56b87e 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -2051,7 +2051,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     /// probe. This will result in a pending obligation so when more type-info is available we can
     /// make the final decision.
     ///
-    /// Example (`tests/ui/method-two-trait-defer-resolution-1.rs`):
+    /// Example (`tests/ui/methods/method-two-trait-defer-resolution-1.rs`):
     ///
     /// ```ignore (illustrative)
     /// trait Foo { ... }
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 495f592baa8..0c0cc752b01 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1053,8 +1053,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let pred = bound_predicate.rebind(pred);
                         // `<Foo as Iterator>::Item = String`.
                         let projection_term = pred.skip_binder().projection_term;
-                        let quiet_projection_term =
-                            projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
+                        let quiet_projection_term = projection_term
+                            .with_replaced_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
 
                         let term = pred.skip_binder().term;
 
@@ -2157,7 +2157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     self.tcx,
                                     self.fresh_args_for_item(sugg_span, impl_did),
                                 )
-                                .with_self_ty(self.tcx, rcvr_ty),
+                                .with_replaced_self_ty(self.tcx, rcvr_ty),
                             idx,
                             sugg_span,
                             item,
@@ -2196,7 +2196,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 trait_did,
                                 self.fresh_args_for_item(sugg_span, trait_did),
                             )
-                            .with_self_ty(self.tcx, rcvr_ty),
+                            .with_replaced_self_ty(self.tcx, rcvr_ty),
                             idx,
                             sugg_span,
                             item,
diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
index d8f78204ca6..d8d217ca800 100644
--- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
+++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
@@ -167,7 +167,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
                 obligation.predicate.kind().rebind(
                     // (*) binder moved here
                     ty::PredicateKind::Clause(ty::ClauseKind::Trait(
-                        tpred.with_self_ty(self.tcx, new_self_ty),
+                        tpred.with_replaced_self_ty(self.tcx, new_self_ty),
                     )),
                 ),
             );
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index df38c3a1214..50fa3f2cc9d 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -2391,13 +2391,11 @@ fn migration_suggestion_for_2229(
 /// let mut p = Point { x: 10, y: 10 };
 ///
 /// let c = || {
-///     p.x     += 10;
-/// // ^ E1 ^
+///     p.x += 10; // E1
 ///     // ...
 ///     // More code
 ///     // ...
 ///     p.x += 10; // E2
-/// // ^ E2 ^
 /// };
 /// ```
 /// `CaptureKind` associated with both `E1` and `E2` will be ByRef(MutBorrow),
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index db37669d85b..3ad14dc79d5 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -752,7 +752,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     ) -> Ty<'tcx> {
         debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
         let var = self.canonical_var(var_kind, ty_var.into());
-        Ty::new_bound(self.tcx, self.binder_index, var.into())
+        let bt = ty::BoundTy { var, kind: ty::BoundTyKind::Anon };
+        Ty::new_bound(self.tcx, self.binder_index, bt)
     }
 
     /// Given a type variable `const_var` of the given kind, first check
@@ -768,6 +769,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
             !self.infcx.is_some_and(|infcx| ct_var != infcx.shallow_resolve_const(ct_var))
         );
         let var = self.canonical_var(var_kind, ct_var.into());
-        ty::Const::new_bound(self.tcx, self.binder_index, var)
+        let bc = ty::BoundConst { var };
+        ty::Const::new_bound(self.tcx, self.binder_index, bc)
     }
 }
diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
index 2385c68ef6b..cc052fbd85c 100644
--- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs
+++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
@@ -133,7 +133,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
         match ct.kind() {
             ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
-                self.var_values[bound_const.as_usize()].expect_const()
+                self.var_values[bound_const.var.as_usize()].expect_const()
             }
             _ => ct.super_fold_with(self),
         }
@@ -217,7 +217,7 @@ fn highest_var_in_clauses<'tcx>(c: ty::Clauses<'tcx>) -> usize {
             if let ty::ConstKind::Bound(debruijn, bound_const) = ct.kind()
                 && debruijn == self.current_index
             {
-                self.max_var = self.max_var.max(bound_const.as_usize());
+                self.max_var = self.max_var.max(bound_const.var.as_usize());
             } else if ct.has_vars_bound_at_or_above(self.current_index) {
                 ct.super_visit_with(self);
             }
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index d92f4c2444b..09578598114 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -430,12 +430,12 @@ impl<'tcx> InferCtxt<'tcx> {
                 }
                 GenericArgKind::Lifetime(result_value) => {
                     // e.g., here `result_value` might be `'?1` in the example above...
-                    if let ty::ReBound(debruijn, br) = result_value.kind() {
+                    if let ty::ReBound(debruijn, b) = result_value.kind() {
                         // ... in which case we would set `canonical_vars[0]` to `Some('static)`.
 
                         // We only allow a `ty::INNERMOST` index in generic parameters.
                         assert_eq!(debruijn, ty::INNERMOST);
-                        opt_values[br.var] = Some(*original_value);
+                        opt_values[b.var] = Some(*original_value);
                     }
                 }
                 GenericArgKind::Const(result_value) => {
@@ -444,7 +444,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
                         // We only allow a `ty::INNERMOST` index in generic parameters.
                         assert_eq!(debruijn, ty::INNERMOST);
-                        opt_values[b] = Some(*original_value);
+                        opt_values[b.var] = Some(*original_value);
                     }
                 }
             }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 5bbd8a84b7f..7379df7c7c7 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1265,8 +1265,8 @@ impl<'tcx> InferCtxt<'tcx> {
             fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> {
                 self.args[bt.var.index()].expect_ty()
             }
-            fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
-                self.args[bv.index()].expect_const()
+            fn replace_const(&mut self, bc: ty::BoundConst) -> ty::Const<'tcx> {
+                self.args[bc.var.index()].expect_const()
             }
         }
         let delegate = ToFreshVars { args };
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index bb3b51c0ab2..b989d419057 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -36,7 +36,7 @@
 //! fn bar<T>(a: T, b: impl for<'a> Fn(&'a T)) {}
 //! fn foo<T>(x: T) {
 //!     bar(x, |y| { /* ... */})
-//!          // ^ closure arg
+//!     //      ^ closure arg
 //! }
 //! ```
 //!
diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index 2143f72a3b0..16fe591b29b 100644
--- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -45,10 +45,10 @@ impl<'tcx> InferCtxt<'tcx> {
                     ty::PlaceholderType { universe: next_universe, bound: bound_ty },
                 )
             },
-            consts: &mut |bound_var: ty::BoundVar| {
+            consts: &mut |bound_const: ty::BoundConst| {
                 ty::Const::new_placeholder(
                     self.tcx,
-                    ty::PlaceholderConst { universe: next_universe, bound: bound_var },
+                    ty::PlaceholderConst { universe: next_universe, bound: bound_const },
                 )
             },
         };
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 83ac981429c..8dec8069bc7 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1151,7 +1151,9 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
 
                 parallel!(
                     {
-                        tcx.ensure_ok().check_private_in_public(());
+                        tcx.par_hir_for_each_module(|module| {
+                            tcx.ensure_ok().check_private_in_public(module)
+                        })
                     },
                     {
                         tcx.par_hir_for_each_module(|module| {
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 8771bb44050..86faab62d03 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -778,8 +778,8 @@ fn test_unstable_options_tracking_hash() {
         coverage_options,
         CoverageOptions {
             level: CoverageLevel::Mcdc,
-            no_mir_spans: true,
-            discard_all_spans_in_codegen: true
+            // (don't collapse test-only options onto the same line)
+            discard_all_spans_in_codegen: true,
         }
     );
     tracked!(crate_attr, vec!["abc".to_string()]);
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 69fe7fe83ff..4d0c0c94a81 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -207,6 +207,12 @@ lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as i
 
 lint_custom_inner_attribute_unstable = custom inner attributes are unstable
 
+lint_dangling_pointers_from_locals = a dangling pointer will be produced because the local variable `{$local_var_name}` will be dropped
+    .ret_ty = return type of the {$fn_kind} is `{$ret_ty}`
+    .local_var = `{$local_var_name}` is part the {$fn_kind} and will be dropped at the end of the {$fn_kind}
+    .created_at = dangling pointer created here
+    .note = pointers do not have a lifetime; after returning, the `{$local_var_ty}` will be deallocated at the end of the {$fn_kind} because nothing is referencing it as far as the type system is concerned
+
 lint_dangling_pointers_from_temporaries = a dangling pointer will be produced because the temporary `{$ty}` will be dropped
     .label_ptr = this pointer will immediately be invalid
     .label_temporary = this `{$ty}` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index b694d3dd49b..11181d10af5 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -756,22 +756,22 @@ impl<'tcx> LateContext<'tcx> {
             }
 
             fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
-                Ok(())
+                unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
             }
 
             fn print_type(&mut self, _ty: Ty<'tcx>) -> Result<(), PrintError> {
-                Ok(())
+                unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
             }
 
             fn print_dyn_existential(
                 &mut self,
                 _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
             ) -> Result<(), PrintError> {
-                Ok(())
+                unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
             }
 
             fn print_const(&mut self, _ct: ty::Const<'tcx>) -> Result<(), PrintError> {
-                Ok(())
+                unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
             }
 
             fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError> {
@@ -784,10 +784,10 @@ impl<'tcx> LateContext<'tcx> {
                 self_ty: Ty<'tcx>,
                 trait_ref: Option<ty::TraitRef<'tcx>>,
             ) -> Result<(), PrintError> {
-                if trait_ref.is_none() {
-                    if let ty::Adt(def, args) = self_ty.kind() {
-                        return self.print_def_path(def.did(), args);
-                    }
+                if trait_ref.is_none()
+                    && let ty::Adt(def, args) = self_ty.kind()
+                {
+                    return self.print_def_path(def.did(), args);
                 }
 
                 // This shouldn't ever be needed, but just in case:
@@ -803,7 +803,6 @@ impl<'tcx> LateContext<'tcx> {
             fn path_append_impl(
                 &mut self,
                 print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
-                _disambiguated_data: &DisambiguatedDefPathData,
                 self_ty: Ty<'tcx>,
                 trait_ref: Option<ty::TraitRef<'tcx>>,
             ) -> Result<(), PrintError> {
@@ -854,9 +853,9 @@ impl<'tcx> LateContext<'tcx> {
             }
         }
 
-        let mut printer = AbsolutePathPrinter { tcx: self.tcx, path: vec![] };
-        printer.print_def_path(def_id, &[]).unwrap();
-        printer.path
+        let mut p = AbsolutePathPrinter { tcx: self.tcx, path: vec![] };
+        p.print_def_path(def_id, &[]).unwrap();
+        p.path
     }
 
     /// Returns the associated type `name` for `self_ty` as an implementation of `trait_id`.
diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs
index 9e19949c3b6..af4457f4314 100644
--- a/compiler/rustc_lint/src/dangling.rs
+++ b/compiler/rustc_lint/src/dangling.rs
@@ -1,13 +1,14 @@
 use rustc_ast::visit::{visit_opt, walk_list};
 use rustc_hir::attrs::AttributeKind;
+use rustc_hir::def::Res;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
-use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem, find_attr};
-use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, LangItem, TyKind, find_attr};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::{declare_lint, impl_lint_pass};
 use rustc_span::{Span, sym};
 
-use crate::lints::DanglingPointersFromTemporaries;
+use crate::lints::{DanglingPointersFromLocals, DanglingPointersFromTemporaries};
 use crate::{LateContext, LateLintPass};
 
 declare_lint! {
@@ -42,6 +43,36 @@ declare_lint! {
     "detects getting a pointer from a temporary"
 }
 
+declare_lint! {
+    /// The `dangling_pointers_from_locals` lint detects getting a pointer to data
+    /// of a local that will be dropped at the end of the function.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// fn f() -> *const u8 {
+    ///     let x = 0;
+    ///     &x // returns a dangling ptr to `x`
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Returning a pointer from a local value will not prolong its lifetime,
+    /// which means that the value can be dropped and the allocation freed
+    /// while the pointer still exists, making the pointer dangling.
+    /// This is not an error (as far as the type system is concerned)
+    /// but probably is not what the user intended either.
+    ///
+    /// If you need stronger guarantees, consider using references instead,
+    /// as they are statically verified by the borrow-checker to never dangle.
+    pub DANGLING_POINTERS_FROM_LOCALS,
+    Warn,
+    "detects returning a pointer from a local variable"
+}
+
 /// FIXME: false negatives (i.e. the lint is not emitted when it should be)
 /// 1. Ways to get a temporary that are not recognized:
 ///    - `owning_temporary.field`
@@ -53,20 +84,123 @@ declare_lint! {
 #[derive(Clone, Copy, Default)]
 pub(crate) struct DanglingPointers;
 
-impl_lint_pass!(DanglingPointers => [DANGLING_POINTERS_FROM_TEMPORARIES]);
+impl_lint_pass!(DanglingPointers => [DANGLING_POINTERS_FROM_TEMPORARIES, DANGLING_POINTERS_FROM_LOCALS]);
 
 // This skips over const blocks, but they cannot use or return a dangling pointer anyways.
 impl<'tcx> LateLintPass<'tcx> for DanglingPointers {
     fn check_fn(
         &mut self,
         cx: &LateContext<'tcx>,
-        _: FnKind<'tcx>,
-        _: &'tcx FnDecl<'tcx>,
+        fn_kind: FnKind<'tcx>,
+        fn_decl: &'tcx FnDecl<'tcx>,
         body: &'tcx Body<'tcx>,
         _: Span,
-        _: LocalDefId,
+        def_id: LocalDefId,
     ) {
-        DanglingPointerSearcher { cx, inside_call_args: false }.visit_body(body)
+        DanglingPointerSearcher { cx, inside_call_args: false }.visit_body(body);
+
+        if let FnRetTy::Return(ret_ty) = &fn_decl.output
+            && let TyKind::Ptr(_) = ret_ty.kind
+        {
+            // get the return type of the function or closure
+            let ty = match cx.tcx.type_of(def_id).instantiate_identity().kind() {
+                ty::FnDef(..) => cx.tcx.fn_sig(def_id).instantiate_identity(),
+                ty::Closure(_, args) => args.as_closure().sig(),
+                _ => return,
+            };
+            let ty = ty.output();
+
+            // this type is only used for layout computation and pretty-printing, neither of them rely on regions
+            let ty = cx.tcx.instantiate_bound_regions_with_erased(ty);
+
+            // verify that we have a pointer type
+            let inner_ty = match ty.kind() {
+                ty::RawPtr(inner_ty, _) => *inner_ty,
+                _ => return,
+            };
+
+            if cx
+                .tcx
+                .layout_of(cx.typing_env().as_query_input(inner_ty))
+                .is_ok_and(|layout| !layout.is_1zst())
+            {
+                let dcx = &DanglingPointerLocalContext {
+                    body: def_id,
+                    fn_ret: ty,
+                    fn_ret_span: ret_ty.span,
+                    fn_ret_inner: inner_ty,
+                    fn_kind: match fn_kind {
+                        FnKind::ItemFn(..) => "function",
+                        FnKind::Method(..) => "method",
+                        FnKind::Closure => "closure",
+                    },
+                };
+
+                // look for `return`s
+                DanglingPointerReturnSearcher { cx, dcx }.visit_body(body);
+
+                // analyze implicit return expression
+                if let ExprKind::Block(block, None) = &body.value.kind
+                    && let innermost_block = block.innermost_block()
+                    && let Some(expr) = innermost_block.expr
+                {
+                    lint_addr_of_local(cx, dcx, expr);
+                }
+            }
+        }
+    }
+}
+
+struct DanglingPointerLocalContext<'tcx> {
+    body: LocalDefId,
+    fn_ret: Ty<'tcx>,
+    fn_ret_span: Span,
+    fn_ret_inner: Ty<'tcx>,
+    fn_kind: &'static str,
+}
+
+struct DanglingPointerReturnSearcher<'lcx, 'tcx> {
+    cx: &'lcx LateContext<'tcx>,
+    dcx: &'lcx DanglingPointerLocalContext<'tcx>,
+}
+
+impl<'tcx> Visitor<'tcx> for DanglingPointerReturnSearcher<'_, 'tcx> {
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> Self::Result {
+        if let ExprKind::Ret(Some(expr)) = expr.kind {
+            lint_addr_of_local(self.cx, self.dcx, expr);
+        }
+        walk_expr(self, expr)
+    }
+}
+
+/// Look for `&<path_to_local_in_same_body>` pattern and emit lint for it
+fn lint_addr_of_local<'a>(
+    cx: &LateContext<'a>,
+    dcx: &DanglingPointerLocalContext<'a>,
+    expr: &'a Expr<'a>,
+) {
+    // peel casts as they do not interest us here, we want the inner expression.
+    let (inner, _) = super::utils::peel_casts(cx, expr);
+
+    if let ExprKind::AddrOf(_, _, inner_of) = inner.kind
+        && let ExprKind::Path(ref qpath) = inner_of.peel_blocks().kind
+        && let Res::Local(from) = cx.qpath_res(qpath, inner_of.hir_id)
+        && cx.tcx.hir_enclosing_body_owner(from) == dcx.body
+    {
+        cx.tcx.emit_node_span_lint(
+            DANGLING_POINTERS_FROM_LOCALS,
+            expr.hir_id,
+            expr.span,
+            DanglingPointersFromLocals {
+                ret_ty: dcx.fn_ret,
+                ret_ty_span: dcx.fn_ret_span,
+                fn_kind: dcx.fn_kind,
+                local_var: cx.tcx.hir_span(from),
+                local_var_name: cx.tcx.hir_ident(from),
+                local_var_ty: dcx.fn_ret_inner,
+                created_at: (expr.hir_id != inner.hir_id).then_some(inner.span),
+            },
+        );
     }
 }
 
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index fd8d0f832aa..ef63c0dee8c 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1188,6 +1188,22 @@ pub(crate) struct DanglingPointersFromTemporaries<'tcx> {
     pub temporary_span: Span,
 }
 
+#[derive(LintDiagnostic)]
+#[diag(lint_dangling_pointers_from_locals)]
+#[note]
+pub(crate) struct DanglingPointersFromLocals<'tcx> {
+    pub ret_ty: Ty<'tcx>,
+    #[label(lint_ret_ty)]
+    pub ret_ty_span: Span,
+    pub fn_kind: &'static str,
+    #[label(lint_local_var)]
+    pub local_var: Span,
+    pub local_var_name: Ident,
+    pub local_var_ty: Ty<'tcx>,
+    #[label(lint_created_at)]
+    pub created_at: Option<Span>,
+}
+
 // multiple_supertrait_upcastable.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_multiple_supertrait_upcastable)]
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index b1edb5c3044..3b84c6b6110 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -125,6 +125,7 @@ declare_lint_pass! {
         UNSAFE_OP_IN_UNSAFE_FN,
         UNSTABLE_NAME_COLLISIONS,
         UNSTABLE_SYNTAX_PRE_EXPANSION,
+        UNSUPPORTED_CALLING_CONVENTIONS,
         UNUSED_ASSIGNMENTS,
         UNUSED_ASSOCIATED_TYPE_BOUNDS,
         UNUSED_ATTRIBUTES,
diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs
index 3683d1e251c..4370816d38e 100644
--- a/compiler/rustc_middle/src/hir/map.rs
+++ b/compiler/rustc_middle/src/hir/map.rs
@@ -533,8 +533,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// ```
     /// fn foo(x: usize) -> bool {
     ///     if x == 1 {
-    ///         true  // If `get_fn_id_for_return_block` gets passed the `id` corresponding
-    ///     } else {  // to this, it will return `foo`'s `HirId`.
+    ///         // If `get_fn_id_for_return_block` gets passed the `id` corresponding to this, it
+    ///         // will return `foo`'s `HirId`.
+    ///         true
+    ///     } else {
     ///         false
     ///     }
     /// }
@@ -543,8 +545,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// ```compile_fail,E0308
     /// fn foo(x: usize) -> bool {
     ///     loop {
-    ///         true  // If `get_fn_id_for_return_block` gets passed the `id` corresponding
-    ///     }         // to this, it will return `None`.
+    ///         // If `get_fn_id_for_return_block` gets passed the `id` corresponding to this, it
+    ///         // will return `None`.
+    ///         true
+    ///     }
     ///     false
     /// }
     /// ```
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 6c07e49734a..67bc89692ff 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -174,36 +174,52 @@ impl<'tcx> TyCtxt<'tcx> {
         attrs: &SortedMap<ItemLocalId, &[Attribute]>,
         delayed_lints: &[DelayedLint],
         define_opaque: Option<&[(Span, LocalDefId)]>,
-    ) -> (Option<Fingerprint>, Option<Fingerprint>, Option<Fingerprint>) {
-        if self.needs_crate_hash() {
-            self.with_stable_hashing_context(|mut hcx| {
-                let mut stable_hasher = StableHasher::new();
-                node.hash_stable(&mut hcx, &mut stable_hasher);
-                // Bodies are stored out of line, so we need to pull them explicitly in the hash.
-                bodies.hash_stable(&mut hcx, &mut stable_hasher);
-                let h1 = stable_hasher.finish();
-
-                let mut stable_hasher = StableHasher::new();
-                attrs.hash_stable(&mut hcx, &mut stable_hasher);
-
-                // Hash the defined opaque types, which are not present in the attrs.
-                define_opaque.hash_stable(&mut hcx, &mut stable_hasher);
-
-                let h2 = stable_hasher.finish();
-
-                // hash lints emitted during ast lowering
-                let mut stable_hasher = StableHasher::new();
-                delayed_lints.hash_stable(&mut hcx, &mut stable_hasher);
-                let h3 = stable_hasher.finish();
-
-                (Some(h1), Some(h2), Some(h3))
-            })
-        } else {
-            (None, None, None)
+    ) -> Hashes {
+        if !self.needs_crate_hash() {
+            return Hashes {
+                opt_hash_including_bodies: None,
+                attrs_hash: None,
+                delayed_lints_hash: None,
+            };
         }
+
+        self.with_stable_hashing_context(|mut hcx| {
+            let mut stable_hasher = StableHasher::new();
+            node.hash_stable(&mut hcx, &mut stable_hasher);
+            // Bodies are stored out of line, so we need to pull them explicitly in the hash.
+            bodies.hash_stable(&mut hcx, &mut stable_hasher);
+            let h1 = stable_hasher.finish();
+
+            let mut stable_hasher = StableHasher::new();
+            attrs.hash_stable(&mut hcx, &mut stable_hasher);
+
+            // Hash the defined opaque types, which are not present in the attrs.
+            define_opaque.hash_stable(&mut hcx, &mut stable_hasher);
+
+            let h2 = stable_hasher.finish();
+
+            // hash lints emitted during ast lowering
+            let mut stable_hasher = StableHasher::new();
+            delayed_lints.hash_stable(&mut hcx, &mut stable_hasher);
+            let h3 = stable_hasher.finish();
+
+            Hashes {
+                opt_hash_including_bodies: Some(h1),
+                attrs_hash: Some(h2),
+                delayed_lints_hash: Some(h3),
+            }
+        })
     }
 }
 
+/// Hashes computed by [`TyCtxt::hash_owner_nodes`] if necessary.
+#[derive(Clone, Copy, Debug)]
+pub struct Hashes {
+    pub opt_hash_including_bodies: Option<Fingerprint>,
+    pub attrs_hash: Option<Fingerprint>,
+    pub delayed_lints_hash: Option<Fingerprint>,
+}
+
 pub fn provide(providers: &mut Providers) {
     providers.hir_crate_items = map::hir_crate_items;
     providers.crate_hash = map::crate_hash;
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 803b645c8f7..e5cc23c213d 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -57,6 +57,7 @@
 #![feature(sized_hierarchy)]
 #![feature(try_blocks)]
 #![feature(try_trait_v2)]
+#![feature(try_trait_v2_residual)]
 #![feature(try_trait_v2_yeet)]
 #![feature(type_alias_impl_trait)]
 #![feature(yeet_expr)]
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 3e895c6b280..77427a12d11 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -793,36 +793,37 @@ impl Drop for Guard {
 /// We also make things panic if this type is ever implicitly dropped.
 #[derive(Debug)]
 #[must_use]
-pub struct InterpResult_<'tcx, T> {
+pub struct InterpResult<'tcx, T = ()> {
     res: Result<T, InterpErrorInfo<'tcx>>,
     guard: Guard,
 }
 
-// Type alias to be able to set a default type argument.
-pub type InterpResult<'tcx, T = ()> = InterpResult_<'tcx, T>;
-
-impl<'tcx, T> ops::Try for InterpResult_<'tcx, T> {
+impl<'tcx, T> ops::Try for InterpResult<'tcx, T> {
     type Output = T;
-    type Residual = InterpResult_<'tcx, convert::Infallible>;
+    type Residual = InterpResult<'tcx, convert::Infallible>;
 
     #[inline]
     fn from_output(output: Self::Output) -> Self {
-        InterpResult_::new(Ok(output))
+        InterpResult::new(Ok(output))
     }
 
     #[inline]
     fn branch(self) -> ops::ControlFlow<Self::Residual, Self::Output> {
         match self.disarm() {
             Ok(v) => ops::ControlFlow::Continue(v),
-            Err(e) => ops::ControlFlow::Break(InterpResult_::new(Err(e))),
+            Err(e) => ops::ControlFlow::Break(InterpResult::new(Err(e))),
         }
     }
 }
 
-impl<'tcx, T> ops::FromResidual for InterpResult_<'tcx, T> {
+impl<'tcx, T> ops::Residual<T> for InterpResult<'tcx, convert::Infallible> {
+    type TryType = InterpResult<'tcx, T>;
+}
+
+impl<'tcx, T> ops::FromResidual for InterpResult<'tcx, T> {
     #[inline]
     #[track_caller]
-    fn from_residual(residual: InterpResult_<'tcx, convert::Infallible>) -> Self {
+    fn from_residual(residual: InterpResult<'tcx, convert::Infallible>) -> Self {
         match residual.disarm() {
             Err(e) => Self::new(Err(e)),
         }
@@ -830,7 +831,7 @@ impl<'tcx, T> ops::FromResidual for InterpResult_<'tcx, T> {
 }
 
 // Allow `yeet`ing `InterpError` in functions returning `InterpResult_`.
-impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpErrorKind<'tcx>>> for InterpResult_<'tcx, T> {
+impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpErrorKind<'tcx>>> for InterpResult<'tcx, T> {
     #[inline]
     fn from_residual(ops::Yeet(e): ops::Yeet<InterpErrorKind<'tcx>>) -> Self {
         Self::new(Err(e.into()))
@@ -840,7 +841,7 @@ impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpErrorKind<'tcx>>> for InterpResu
 // Allow `?` on `Result<_, InterpError>` in functions returning `InterpResult_`.
 // This is useful e.g. for `option.ok_or_else(|| err_ub!(...))`.
 impl<'tcx, T, E: Into<InterpErrorInfo<'tcx>>> ops::FromResidual<Result<convert::Infallible, E>>
-    for InterpResult_<'tcx, T>
+    for InterpResult<'tcx, T>
 {
     #[inline]
     fn from_residual(residual: Result<convert::Infallible, E>) -> Self {
@@ -863,7 +864,7 @@ impl<'tcx, T, V: FromIterator<T>> FromIterator<InterpResult<'tcx, T>> for Interp
     }
 }
 
-impl<'tcx, T> InterpResult_<'tcx, T> {
+impl<'tcx, T> InterpResult<'tcx, T> {
     #[inline(always)]
     fn new(res: Result<T, InterpErrorInfo<'tcx>>) -> Self {
         Self { res, guard: Guard }
@@ -890,7 +891,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
 
     #[inline]
     pub fn map<U>(self, f: impl FnOnce(T) -> U) -> InterpResult<'tcx, U> {
-        InterpResult_::new(self.disarm().map(f))
+        InterpResult::new(self.disarm().map(f))
     }
 
     #[inline]
@@ -898,7 +899,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
         self,
         f: impl FnOnce(InterpErrorInfo<'tcx>) -> InterpErrorInfo<'tcx>,
     ) -> InterpResult<'tcx, T> {
-        InterpResult_::new(self.disarm().map_err(f))
+        InterpResult::new(self.disarm().map_err(f))
     }
 
     #[inline]
@@ -906,7 +907,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
         self,
         f: impl FnOnce(InterpErrorKind<'tcx>) -> InterpErrorKind<'tcx>,
     ) -> InterpResult<'tcx, T> {
-        InterpResult_::new(self.disarm().map_err(|mut e| {
+        InterpResult::new(self.disarm().map_err(|mut e| {
             e.0.kind = f(e.0.kind);
             e
         }))
@@ -914,7 +915,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
 
     #[inline]
     pub fn inspect_err_kind(self, f: impl FnOnce(&InterpErrorKind<'tcx>)) -> InterpResult<'tcx, T> {
-        InterpResult_::new(self.disarm().inspect_err(|e| f(&e.0.kind)))
+        InterpResult::new(self.disarm().inspect_err(|e| f(&e.0.kind)))
     }
 
     #[inline]
@@ -937,7 +938,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
 
     #[inline]
     pub fn and_then<U>(self, f: impl FnOnce(T) -> InterpResult<'tcx, U>) -> InterpResult<'tcx, U> {
-        InterpResult_::new(self.disarm().and_then(|t| f(t).disarm()))
+        InterpResult::new(self.disarm().and_then(|t| f(t).disarm()))
     }
 
     /// Returns success if both `self` and `other` succeed, while ensuring we don't
@@ -952,7 +953,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
                 // Discard the other error.
                 drop(other.disarm());
                 // Return `self`.
-                InterpResult_::new(Err(e))
+                InterpResult::new(Err(e))
             }
         }
     }
@@ -960,5 +961,5 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
 
 #[inline(always)]
 pub fn interp_ok<'tcx, T>(x: T) -> InterpResult<'tcx, T> {
-    InterpResult_::new(Ok(x))
+    InterpResult::new(Ok(x))
 }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index e819aa2d8f8..c55c7fc6002 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1017,7 +1017,8 @@ pub struct LocalDecl<'tcx> {
     /// ```
     /// fn foo(x: &str) {
     ///     #[allow(unused_mut)]
-    ///     let mut x: u32 = { // <- one unused mut
+    ///     let mut x: u32 = {
+    ///         //^ one unused mut
     ///         let mut y: u32 = x.parse().unwrap();
     ///         y + 2
     ///     };
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 809cdb329f7..ed067d49127 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -970,11 +970,11 @@ impl<'tcx> TerminatorKind<'tcx> {
             Call { func, args, destination, .. } => {
                 write!(fmt, "{destination:?} = ")?;
                 write!(fmt, "{func:?}(")?;
-                for (index, arg) in args.iter().map(|a| &a.node).enumerate() {
+                for (index, arg) in args.iter().enumerate() {
                     if index > 0 {
                         write!(fmt, ", ")?;
                     }
-                    write!(fmt, "{arg:?}")?;
+                    write!(fmt, "{:?}", arg.node)?;
                 }
                 write!(fmt, ")")
             }
@@ -984,7 +984,7 @@ impl<'tcx> TerminatorKind<'tcx> {
                     if index > 0 {
                         write!(fmt, ", ")?;
                     }
-                    write!(fmt, "{:?}", arg)?;
+                    write!(fmt, "{:?}", arg.node)?;
                 }
                 write!(fmt, ")")
             }
@@ -1197,8 +1197,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                         ty::tls::with(|tcx| {
                             let variant_def = &tcx.adt_def(adt_did).variant(variant);
                             let args = tcx.lift(args).expect("could not lift for printing");
-                            let name = FmtPrinter::print_string(tcx, Namespace::ValueNS, |cx| {
-                                cx.print_def_path(variant_def.def_id, args)
+                            let name = FmtPrinter::print_string(tcx, Namespace::ValueNS, |p| {
+                                p.print_def_path(variant_def.def_id, args)
                             })?;
 
                             match variant_def.ctor_kind() {
@@ -1473,9 +1473,9 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
             };
 
             let fmt_valtree = |cv: &ty::Value<'tcx>| {
-                let mut cx = FmtPrinter::new(self.tcx, Namespace::ValueNS);
-                cx.pretty_print_const_valtree(*cv, /*print_ty*/ true).unwrap();
-                cx.into_buffer()
+                let mut p = FmtPrinter::new(self.tcx, Namespace::ValueNS);
+                p.pretty_print_const_valtree(*cv, /*print_ty*/ true).unwrap();
+                p.into_buffer()
             };
 
             let val = match const_ {
@@ -1967,10 +1967,10 @@ fn pretty_print_const_value_tcx<'tcx>(
                             .expect("destructed mir constant of adt without variant idx");
                         let variant_def = &def.variant(variant_idx);
                         let args = tcx.lift(args).unwrap();
-                        let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-                        cx.print_alloc_ids = true;
-                        cx.print_value_path(variant_def.def_id, args)?;
-                        fmt.write_str(&cx.into_buffer())?;
+                        let mut p = FmtPrinter::new(tcx, Namespace::ValueNS);
+                        p.print_alloc_ids = true;
+                        p.print_value_path(variant_def.def_id, args)?;
+                        fmt.write_str(&p.into_buffer())?;
 
                         match variant_def.ctor_kind() {
                             Some(CtorKind::Const) => {}
@@ -2001,18 +2001,18 @@ fn pretty_print_const_value_tcx<'tcx>(
             }
         }
         (ConstValue::Scalar(scalar), _) => {
-            let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-            cx.print_alloc_ids = true;
+            let mut p = FmtPrinter::new(tcx, Namespace::ValueNS);
+            p.print_alloc_ids = true;
             let ty = tcx.lift(ty).unwrap();
-            cx.pretty_print_const_scalar(scalar, ty)?;
-            fmt.write_str(&cx.into_buffer())?;
+            p.pretty_print_const_scalar(scalar, ty)?;
+            fmt.write_str(&p.into_buffer())?;
             return Ok(());
         }
         (ConstValue::ZeroSized, ty::FnDef(d, s)) => {
-            let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-            cx.print_alloc_ids = true;
-            cx.print_value_path(*d, s)?;
-            fmt.write_str(&cx.into_buffer())?;
+            let mut p = FmtPrinter::new(tcx, Namespace::ValueNS);
+            p.print_alloc_ids = true;
+            p.print_value_path(*d, s)?;
+            fmt.write_str(&p.into_buffer())?;
             return Ok(());
         }
         // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b02433d2feb..a4589576594 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1178,11 +1178,10 @@ rustc_queries! {
 
     /// Return the live symbols in the crate for dead code check.
     ///
-    /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone) and
-    /// their respective impl (i.e., part of the derive macro)
+    /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone).
     query live_symbols_and_ignored_derived_traits(_: ()) -> &'tcx (
         LocalDefIdSet,
-        LocalDefIdMap<FxIndexSet<(DefId, DefId)>>
+        LocalDefIdMap<FxIndexSet<DefId>>,
     ) {
         arena_cache
         desc { "finding live symbols in crate" }
@@ -1390,8 +1389,11 @@ rustc_queries! {
         eval_always
         desc { "checking effective visibilities" }
     }
-    query check_private_in_public(_: ()) {
-        desc { "checking for private elements in public interfaces" }
+    query check_private_in_public(module_def_id: LocalModDefId) {
+        desc { |tcx|
+            "checking for private elements in public interfaces for {}",
+            describe_as_module(module_def_id, tcx)
+        }
     }
 
     query reachable_set(_: ()) -> &'tcx LocalDefIdSet {
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index fd1aa4042bc..614b6471f18 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -93,9 +93,9 @@ impl<'tcx> Const<'tcx> {
     pub fn new_bound(
         tcx: TyCtxt<'tcx>,
         debruijn: ty::DebruijnIndex,
-        var: ty::BoundVar,
+        bound_const: ty::BoundConst,
     ) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Bound(debruijn, var))
+        Const::new(tcx, ty::ConstKind::Bound(debruijn, bound_const))
     }
 
     #[inline]
@@ -168,12 +168,16 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
         Const::new_var(tcx, vid)
     }
 
-    fn new_bound(interner: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
-        Const::new_bound(interner, debruijn, var)
+    fn new_bound(
+        interner: TyCtxt<'tcx>,
+        debruijn: ty::DebruijnIndex,
+        bound_const: ty::BoundConst,
+    ) -> Self {
+        Const::new_bound(interner, debruijn, bound_const)
     }
 
     fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
-        Const::new_bound(tcx, debruijn, var)
+        Const::new_bound(tcx, debruijn, ty::BoundConst { var })
     }
 
     fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst) -> Self {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index f4ee3d7971c..db56082c71a 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -152,7 +152,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     type PlaceholderConst = ty::PlaceholderConst;
 
     type ParamConst = ty::ParamConst;
-    type BoundConst = ty::BoundVar;
+    type BoundConst = ty::BoundConst;
     type ValueConst = ty::Value<'tcx>;
     type ExprConst = ty::Expr<'tcx>;
     type ValTree = ty::ValTree<'tcx>;
@@ -1381,7 +1381,7 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
         let bodies = Default::default();
         let attrs = hir::AttributeMap::EMPTY;
 
-        let (opt_hash_including_bodies, _, _) =
+        let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
             self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
         let node = node.into();
         self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 13723874ad3..c24dc983d21 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -213,13 +213,13 @@ impl<'tcx> Ty<'tcx> {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    pub fn string_with_limit<T>(self, p: T, length_limit: usize) -> String
+    pub fn string_with_limit<T>(self, t: T, length_limit: usize) -> String
     where
         T: Copy + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>,
     {
         let mut type_limit = 50;
-        let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
-            self.lift(p).expect("could not lift for printing").print(cx)
+        let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |p| {
+            self.lift(t).expect("could not lift for printing").print(p)
         })
         .expect("could not write to `String`");
         if regular.len() <= length_limit {
@@ -229,16 +229,16 @@ impl<'tcx> TyCtxt<'tcx> {
         loop {
             // Look for the longest properly trimmed path that still fits in length_limit.
             short = with_forced_trimmed_paths!({
-                let mut cx = FmtPrinter::new_with_limit(
+                let mut p = FmtPrinter::new_with_limit(
                     self,
                     hir::def::Namespace::TypeNS,
                     rustc_session::Limit(type_limit),
                 );
-                self.lift(p)
+                self.lift(t)
                     .expect("could not lift for printing")
-                    .print(&mut cx)
+                    .print(&mut p)
                     .expect("could not print type");
-                cx.into_buffer()
+                p.into_buffer()
             });
             if short.len() <= length_limit || type_limit == 0 {
                 break;
@@ -252,12 +252,12 @@ impl<'tcx> TyCtxt<'tcx> {
     /// `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that keeps
     /// the existence of a "long type" anywhere in the diagnostic, so the note telling the user
     /// where we wrote the file to is only printed once.
-    pub fn short_string<T>(self, p: T, path: &mut Option<PathBuf>) -> String
+    pub fn short_string<T>(self, t: T, path: &mut Option<PathBuf>) -> String
     where
         T: Copy + Hash + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>,
     {
-        let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
-            self.lift(p).expect("could not lift for printing").print(cx)
+        let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |p| {
+            self.lift(t).expect("could not lift for printing").print(p)
         })
         .expect("could not write to `String`");
 
@@ -270,13 +270,13 @@ impl<'tcx> TyCtxt<'tcx> {
         if regular.len() <= width * 2 / 3 {
             return regular;
         }
-        let short = self.string_with_limit(p, length_limit);
+        let short = self.string_with_limit(t, length_limit);
         if regular == short {
             return regular;
         }
         // Ensure we create an unique file for the type passed in when we create a file.
         let mut s = DefaultHasher::new();
-        p.hash(&mut s);
+        t.hash(&mut s);
         let hash = s.finish();
         *path = Some(path.take().unwrap_or_else(|| {
             self.output_filenames(()).temp_path_for_diagnostic(&format!("long-type-{hash}.txt"))
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index b2057fa36d7..7d56ec1635f 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -3,7 +3,7 @@ use rustc_hir::def_id::DefId;
 use rustc_type_ir::data_structures::DelayedMap;
 
 use crate::ty::{
-    self, Binder, BoundTy, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    self, Binder, BoundConst, BoundTy, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
     TypeVisitableExt,
 };
 
@@ -60,7 +60,7 @@ where
 pub trait BoundVarReplacerDelegate<'tcx> {
     fn replace_region(&mut self, br: ty::BoundRegion) -> ty::Region<'tcx>;
     fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx>;
-    fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx>;
+    fn replace_const(&mut self, bc: ty::BoundConst) -> ty::Const<'tcx>;
 }
 
 /// A simple delegate taking 3 mutable functions. The used functions must
@@ -69,7 +69,7 @@ pub trait BoundVarReplacerDelegate<'tcx> {
 pub struct FnMutDelegate<'a, 'tcx> {
     pub regions: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
     pub types: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a),
-    pub consts: &'a mut (dyn FnMut(ty::BoundVar) -> ty::Const<'tcx> + 'a),
+    pub consts: &'a mut (dyn FnMut(ty::BoundConst) -> ty::Const<'tcx> + 'a),
 }
 
 impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> {
@@ -79,8 +79,8 @@ impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> {
     fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> {
         (self.types)(bt)
     }
-    fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
-        (self.consts)(bv)
+    fn replace_const(&mut self, bc: ty::BoundConst) -> ty::Const<'tcx> {
+        (self.consts)(bc)
     }
 }
 
@@ -300,7 +300,13 @@ impl<'tcx> TyCtxt<'tcx> {
                         ty::BoundTy { var: shift_bv(t.var), kind: t.kind },
                     )
                 },
-                consts: &mut |c| ty::Const::new_bound(self, ty::INNERMOST, shift_bv(c)),
+                consts: &mut |c| {
+                    ty::Const::new_bound(
+                        self,
+                        ty::INNERMOST,
+                        ty::BoundConst { var: shift_bv(c.var) },
+                    )
+                },
             },
         )
     }
@@ -343,12 +349,12 @@ impl<'tcx> TyCtxt<'tcx> {
                     .expect_ty();
                 Ty::new_bound(self.tcx, ty::INNERMOST, BoundTy { var, kind })
             }
-            fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
-                let entry = self.map.entry(bv);
+            fn replace_const(&mut self, bc: ty::BoundConst) -> ty::Const<'tcx> {
+                let entry = self.map.entry(bc.var);
                 let index = entry.index();
                 let var = ty::BoundVar::from_usize(index);
                 let () = entry.or_insert_with(|| ty::BoundVariableKind::Const).expect_const();
-                ty::Const::new_bound(self.tcx, ty::INNERMOST, var)
+                ty::Const::new_bound(self.tcx, ty::INNERMOST, BoundConst { var })
             }
         }
 
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 7d34d8df3f3..b02abb5ab43 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -96,14 +96,12 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
                 signature_parts_ty,
                 tupled_upvars_ty,
                 coroutine_captures_by_ref_ty,
-                coroutine_witness_ty,
             ] => ty::CoroutineClosureArgsParts {
                 parent_args,
                 closure_kind_ty: closure_kind_ty.expect_ty(),
                 signature_parts_ty: signature_parts_ty.expect_ty(),
                 tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
                 coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
-                coroutine_witness_ty: coroutine_witness_ty.expect_ty(),
             },
             _ => bug!("closure args missing synthetics"),
         }
@@ -111,23 +109,16 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
 
     fn split_coroutine_args(self) -> ty::CoroutineArgsParts<TyCtxt<'tcx>> {
         match self[..] {
-            [
-                ref parent_args @ ..,
-                kind_ty,
-                resume_ty,
-                yield_ty,
-                return_ty,
-                witness,
-                tupled_upvars_ty,
-            ] => ty::CoroutineArgsParts {
-                parent_args,
-                kind_ty: kind_ty.expect_ty(),
-                resume_ty: resume_ty.expect_ty(),
-                yield_ty: yield_ty.expect_ty(),
-                return_ty: return_ty.expect_ty(),
-                witness: witness.expect_ty(),
-                tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
-            },
+            [ref parent_args @ .., kind_ty, resume_ty, yield_ty, return_ty, tupled_upvars_ty] => {
+                ty::CoroutineArgsParts {
+                    parent_args,
+                    kind_ty: kind_ty.expect_ty(),
+                    resume_ty: resume_ty.expect_ty(),
+                    yield_ty: yield_ty.expect_ty(),
+                    return_ty: return_ty.expect_ty(),
+                    tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
+                }
+            }
             _ => bug!("coroutine args missing synthetics"),
         }
     }
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index eb35a952032..16873b6ee21 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -397,13 +397,13 @@ pub fn fmt_instance(
     ty::tls::with(|tcx| {
         let args = tcx.lift(instance.args).expect("could not lift for printing");
 
-        let mut cx = if let Some(type_length) = type_length {
+        let mut p = if let Some(type_length) = type_length {
             FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
         } else {
             FmtPrinter::new(tcx, Namespace::ValueNS)
         };
-        cx.print_def_path(instance.def_id(), args)?;
-        let s = cx.into_buffer();
+        p.print_def_path(instance.def_id(), args)?;
+        let s = p.into_buffer();
         f.write_str(&s)
     })?;
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index d07ecdaf3e4..0deb2482c6f 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -908,34 +908,43 @@ impl<'tcx> rustc_type_ir::inherent::PlaceholderLike<TyCtxt<'tcx>> for Placeholde
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
 #[derive(TyEncodable, TyDecodable)]
-pub struct BoundConst<'tcx> {
+pub struct BoundConst {
     pub var: BoundVar,
-    pub ty: Ty<'tcx>,
 }
 
-pub type PlaceholderConst = Placeholder<BoundVar>;
+impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundConst {
+    fn var(self) -> BoundVar {
+        self.var
+    }
+
+    fn assert_eq(self, var: ty::BoundVariableKind) {
+        var.expect_const()
+    }
+}
+
+pub type PlaceholderConst = Placeholder<BoundConst>;
 
 impl<'tcx> rustc_type_ir::inherent::PlaceholderLike<TyCtxt<'tcx>> for PlaceholderConst {
-    type Bound = BoundVar;
+    type Bound = BoundConst;
 
     fn universe(self) -> UniverseIndex {
         self.universe
     }
 
     fn var(self) -> BoundVar {
-        self.bound
+        self.bound.var
     }
 
     fn with_updated_universe(self, ui: UniverseIndex) -> Self {
         Placeholder { universe: ui, ..self }
     }
 
-    fn new(ui: UniverseIndex, bound: BoundVar) -> Self {
+    fn new(ui: UniverseIndex, bound: BoundConst) -> Self {
         Placeholder { universe: ui, bound }
     }
 
     fn new_anon(ui: UniverseIndex, var: BoundVar) -> Self {
-        Placeholder { universe: ui, bound: var }
+        Placeholder { universe: ui, bound: BoundConst { var } }
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 9172c5d3ab7..8a125c7fe28 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -18,7 +18,7 @@ use super::Lift;
 pub type PrintError = std::fmt::Error;
 
 pub trait Print<'tcx, P> {
-    fn print(&self, cx: &mut P) -> Result<(), PrintError>;
+    fn print(&self, p: &mut P) -> Result<(), PrintError>;
 }
 
 /// Interface for outputting user-facing "type-system entities"
@@ -88,7 +88,6 @@ pub trait Printer<'tcx>: Sized {
     fn path_append_impl(
         &mut self,
         print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
-        disambiguated_data: &DisambiguatedDefPathData,
         self_ty: Ty<'tcx>,
         trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError>;
@@ -148,7 +147,7 @@ pub trait Printer<'tcx>: Sized {
                                 && args.len() > parent_args.len()
                             {
                                 return self.path_generic_args(
-                                    |cx| cx.print_def_path(def_id, parent_args),
+                                    |p| p.print_def_path(def_id, parent_args),
                                     &args[..parent_args.len() + 1][..1],
                                 );
                             } else {
@@ -170,7 +169,7 @@ pub trait Printer<'tcx>: Sized {
                             if !generics.is_own_empty() && args.len() >= generics.count() {
                                 let args = generics.own_args_no_defaults(self.tcx(), args);
                                 return self.path_generic_args(
-                                    |cx| cx.print_def_path(def_id, parent_args),
+                                    |p| p.print_def_path(def_id, parent_args),
                                     args,
                                 );
                             }
@@ -186,16 +185,16 @@ pub trait Printer<'tcx>: Sized {
                 }
 
                 self.path_append(
-                    |cx: &mut Self| {
+                    |p: &mut Self| {
                         if trait_qualify_parent {
                             let trait_ref = ty::TraitRef::new(
-                                cx.tcx(),
+                                p.tcx(),
                                 parent_def_id,
                                 parent_args.iter().copied(),
                             );
-                            cx.path_qualified(trait_ref.self_ty(), Some(trait_ref))
+                            p.path_qualified(trait_ref.self_ty(), Some(trait_ref))
                         } else {
-                            cx.print_def_path(parent_def_id, parent_args)
+                            p.print_def_path(parent_def_id, parent_args)
                         }
                     },
                     &key.disambiguated_data,
@@ -236,12 +235,7 @@ pub trait Printer<'tcx>: Sized {
             // If the impl is not co-located with either self-type or
             // trait-type, then fallback to a format that identifies
             // the module more clearly.
-            self.path_append_impl(
-                |cx| cx.print_def_path(parent_def_id, &[]),
-                &key.disambiguated_data,
-                self_ty,
-                impl_trait_ref,
-            )
+            self.path_append_impl(|p| p.print_def_path(parent_def_id, &[]), self_ty, impl_trait_ref)
         } else {
             // Otherwise, try to give a good form that would be valid language
             // syntax. Preferably using associated item notation.
@@ -312,26 +306,26 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
 }
 
 impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'tcx> {
-    fn print(&self, cx: &mut P) -> Result<(), PrintError> {
-        cx.print_region(*self)
+    fn print(&self, p: &mut P) -> Result<(), PrintError> {
+        p.print_region(*self)
     }
 }
 
 impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> {
-    fn print(&self, cx: &mut P) -> Result<(), PrintError> {
-        cx.print_type(*self)
+    fn print(&self, p: &mut P) -> Result<(), PrintError> {
+        p.print_type(*self)
     }
 }
 
 impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
-    fn print(&self, cx: &mut P) -> Result<(), PrintError> {
-        cx.print_dyn_existential(self)
+    fn print(&self, p: &mut P) -> Result<(), PrintError> {
+        p.print_dyn_existential(self)
     }
 }
 
 impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Const<'tcx> {
-    fn print(&self, cx: &mut P) -> Result<(), PrintError> {
-        cx.print_const(*self)
+    fn print(&self, p: &mut P) -> Result<(), PrintError> {
+        p.print_const(*self)
     }
 }
 
@@ -351,9 +345,9 @@ where
 {
     fn print(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         ty::tls::with(|tcx| {
-            let mut cx = FmtPrinter::new(tcx, Namespace::TypeNS);
-            tcx.lift(*t).expect("could not lift for printing").print(&mut cx)?;
-            fmt.write_str(&cx.into_buffer())?;
+            let mut p = FmtPrinter::new(tcx, Namespace::TypeNS);
+            tcx.lift(*t).expect("could not lift for printing").print(&mut p)?;
+            fmt.write_str(&p.into_buffer())?;
             Ok(())
         })
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 5c44b10ba71..b381d62be47 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -29,33 +29,6 @@ use crate::ty::{
     TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
 };
 
-macro_rules! p {
-    (@$lit:literal) => {
-        write!(scoped_cx!(), $lit)?
-    };
-    (@write($($data:expr),+)) => {
-        write!(scoped_cx!(), $($data),+)?
-    };
-    (@print($x:expr)) => {
-        $x.print(scoped_cx!())?
-    };
-    (@$method:ident($($arg:expr),*)) => {
-        scoped_cx!().$method($($arg),*)?
-    };
-    ($($elem:tt $(($($args:tt)*))?),+) => {{
-        $(p!(@ $elem $(($($args)*))?);)+
-    }};
-}
-macro_rules! define_scoped_cx {
-    ($cx:ident) => {
-        macro_rules! scoped_cx {
-            () => {
-                $cx
-            };
-        }
-    };
-}
-
 thread_local! {
     static FORCE_IMPL_FILENAME_LINE: Cell<bool> = const { Cell::new(false) };
     static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = const { Cell::new(false) };
@@ -689,12 +662,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             }
         }
 
-        self.generic_delimiters(|cx| {
-            define_scoped_cx!(cx);
-
-            p!(print(self_ty));
+        self.generic_delimiters(|p| {
+            self_ty.print(p)?;
             if let Some(trait_ref) = trait_ref {
-                p!(" as ", print(trait_ref.print_only_trait_path()));
+                write!(p, " as ")?;
+                trait_ref.print_only_trait_path().print(p)?;
             }
             Ok(())
         })
@@ -708,121 +680,121 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
     ) -> Result<(), PrintError> {
         print_prefix(self)?;
 
-        self.generic_delimiters(|cx| {
-            define_scoped_cx!(cx);
-
-            p!("impl ");
+        self.generic_delimiters(|p| {
+            write!(p, "impl ")?;
             if let Some(trait_ref) = trait_ref {
-                p!(print(trait_ref.print_only_trait_path()), " for ");
+                trait_ref.print_only_trait_path().print(p)?;
+                write!(p, " for ")?;
             }
-            p!(print(self_ty));
+            self_ty.print(p)?;
 
             Ok(())
         })
     }
 
     fn pretty_print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
-        define_scoped_cx!(self);
-
         match *ty.kind() {
-            ty::Bool => p!("bool"),
-            ty::Char => p!("char"),
-            ty::Int(t) => p!(write("{}", t.name_str())),
-            ty::Uint(t) => p!(write("{}", t.name_str())),
-            ty::Float(t) => p!(write("{}", t.name_str())),
+            ty::Bool => write!(self, "bool")?,
+            ty::Char => write!(self, "char")?,
+            ty::Int(t) => write!(self, "{}", t.name_str())?,
+            ty::Uint(t) => write!(self, "{}", t.name_str())?,
+            ty::Float(t) => write!(self, "{}", t.name_str())?,
             ty::Pat(ty, pat) => {
-                p!("(", print(ty), ") is ", write("{pat:?}"))
+                write!(self, "(")?;
+                ty.print(self)?;
+                write!(self, ") is {pat:?}")?;
             }
             ty::RawPtr(ty, mutbl) => {
-                p!(write("*{} ", mutbl.ptr_str()));
-                p!(print(ty))
+                write!(self, "*{} ", mutbl.ptr_str())?;
+                ty.print(self)?;
             }
             ty::Ref(r, ty, mutbl) => {
-                p!("&");
+                write!(self, "&")?;
                 if self.should_print_region(r) {
-                    p!(print(r), " ");
+                    r.print(self)?;
+                    write!(self, " ")?;
                 }
-                p!(print(ty::TypeAndMut { ty, mutbl }))
+                ty::TypeAndMut { ty, mutbl }.print(self)?;
             }
-            ty::Never => p!("!"),
+            ty::Never => write!(self, "!")?,
             ty::Tuple(tys) => {
-                p!("(", comma_sep(tys.iter()));
+                write!(self, "(")?;
+                self.comma_sep(tys.iter())?;
                 if tys.len() == 1 {
-                    p!(",");
+                    write!(self, ",")?;
                 }
-                p!(")")
+                write!(self, ")")?;
             }
             ty::FnDef(def_id, args) => {
                 if with_reduced_queries() {
-                    p!(print_def_path(def_id, args));
+                    self.print_def_path(def_id, args)?;
                 } else {
                     let mut sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args);
                     if self.tcx().codegen_fn_attrs(def_id).safe_target_features {
-                        p!("#[target_features] ");
+                        write!(self, "#[target_features] ")?;
                         sig = sig.map_bound(|mut sig| {
                             sig.safety = hir::Safety::Safe;
                             sig
                         });
                     }
-                    p!(print(sig), " {{", print_value_path(def_id, args), "}}");
+                    sig.print(self)?;
+                    write!(self, " {{")?;
+                    self.print_value_path(def_id, args)?;
+                    write!(self, "}}")?;
                 }
             }
-            ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))),
+            ty::FnPtr(ref sig_tys, hdr) => sig_tys.with(hdr).print(self)?,
             ty::UnsafeBinder(ref bound_ty) => {
-                self.wrap_binder(bound_ty, WrapBinderMode::Unsafe, |ty, cx| {
-                    cx.pretty_print_type(*ty)
+                self.wrap_binder(bound_ty, WrapBinderMode::Unsafe, |ty, p| {
+                    p.pretty_print_type(*ty)
                 })?;
             }
             ty::Infer(infer_ty) => {
                 if self.should_print_verbose() {
-                    p!(write("{:?}", ty.kind()));
+                    write!(self, "{:?}", ty.kind())?;
                     return Ok(());
                 }
 
                 if let ty::TyVar(ty_vid) = infer_ty {
                     if let Some(name) = self.ty_infer_name(ty_vid) {
-                        p!(write("{}", name))
+                        write!(self, "{name}")?;
                     } else {
-                        p!(write("{}", infer_ty))
+                        write!(self, "{infer_ty}")?;
                     }
                 } else {
-                    p!(write("{}", infer_ty))
+                    write!(self, "{infer_ty}")?;
                 }
             }
-            ty::Error(_) => p!("{{type error}}"),
-            ty::Param(ref param_ty) => p!(print(param_ty)),
+            ty::Error(_) => write!(self, "{{type error}}")?,
+            ty::Param(ref param_ty) => param_ty.print(self)?,
             ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
                 ty::BoundTyKind::Anon => {
                     rustc_type_ir::debug_bound_var(self, debruijn, bound_ty.var)?
                 }
                 ty::BoundTyKind::Param(def_id) => match self.should_print_verbose() {
-                    true => p!(write("{:?}", ty.kind())),
-                    false => p!(write("{}", self.tcx().item_name(def_id))),
+                    true => write!(self, "{:?}", ty.kind())?,
+                    false => write!(self, "{}", self.tcx().item_name(def_id))?,
                 },
             },
-            ty::Adt(def, args) => {
-                p!(print_def_path(def.did(), args));
-            }
+            ty::Adt(def, args) => self.print_def_path(def.did(), args)?,
             ty::Dynamic(data, r, repr) => {
                 let print_r = self.should_print_region(r);
                 if print_r {
-                    p!("(");
+                    write!(self, "(")?;
                 }
                 match repr {
-                    ty::Dyn => p!("dyn "),
+                    ty::Dyn => write!(self, "dyn ")?,
                 }
-                p!(print(data));
+                data.print(self)?;
                 if print_r {
-                    p!(" + ", print(r), ")");
+                    write!(self, " + ")?;
+                    r.print(self)?;
+                    write!(self, ")")?;
                 }
             }
-            ty::Foreign(def_id) => {
-                p!(print_def_path(def_id, &[]));
-            }
-            ty::Alias(ty::Projection | ty::Inherent | ty::Free, ref data) => {
-                p!(print(data))
-            }
-            ty::Placeholder(placeholder) => p!(print(placeholder)),
+            ty::Foreign(def_id) => self.print_def_path(def_id, &[])?,
+            ty::Alias(ty::Projection | ty::Inherent | ty::Free, ref data) => data.print(self)?,
+            ty::Placeholder(placeholder) => placeholder.print(self)?,
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
                 // We use verbose printing in 'NO_QUERIES' mode, to
                 // avoid needing to call `predicates_of`. This should
@@ -834,7 +806,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 // example.]
                 if self.should_print_verbose() {
                     // FIXME(eddyb) print this with `print_def_path`.
-                    p!(write("Opaque({:?}, {})", def_id, args.print_as_list()));
+                    write!(self, "Opaque({:?}, {})", def_id, args.print_as_list())?;
                     return Ok(());
                 }
 
@@ -849,17 +821,17 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                             if d == def_id {
                                 // If the type alias directly starts with the `impl` of the
                                 // opaque type we're printing, then skip the `::{opaque#1}`.
-                                p!(print_def_path(parent, args));
+                                self.print_def_path(parent, args)?;
                                 return Ok(());
                             }
                         }
                         // Complex opaque type, e.g. `type Foo = (i32, impl Debug);`
-                        p!(print_def_path(def_id, args));
+                        self.print_def_path(def_id, args)?;
                         return Ok(());
                     }
                     _ => {
                         if with_reduced_queries() {
-                            p!(print_def_path(def_id, &[]));
+                            self.print_def_path(def_id, &[])?;
                             return Ok(());
                         } else {
                             return self.pretty_print_opaque_impl_type(def_id, args);
@@ -867,9 +839,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                     }
                 }
             }
-            ty::Str => p!("str"),
+            ty::Str => write!(self, "str")?,
             ty::Coroutine(did, args) => {
-                p!("{{");
+                write!(self, "{{")?;
                 let coroutine_kind = self.tcx().coroutine_kind(did).unwrap();
                 let should_print_movability = self.should_print_verbose()
                     || matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_));
@@ -877,12 +849,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 if should_print_movability {
                     match coroutine_kind.movability() {
                         hir::Movability::Movable => {}
-                        hir::Movability::Static => p!("static "),
+                        hir::Movability::Static => write!(self, "static ")?,
                     }
                 }
 
                 if !self.should_print_verbose() {
-                    p!(write("{}", coroutine_kind));
+                    write!(self, "{coroutine_kind}")?;
                     if coroutine_kind.is_fn_like() {
                         // If we are printing an `async fn` coroutine type, then give the path
                         // of the fn, instead of its span, because that will in most cases be
@@ -891,68 +863,71 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                         // This will look like:
                         //    {async fn body of some_fn()}
                         let did_of_the_fn_item = self.tcx().parent(did);
-                        p!(" of ", print_def_path(did_of_the_fn_item, args), "()");
+                        write!(self, " of ")?;
+                        self.print_def_path(did_of_the_fn_item, args)?;
+                        write!(self, "()")?;
                     } else if let Some(local_did) = did.as_local() {
                         let span = self.tcx().def_span(local_did);
-                        p!(write(
+                        write!(
+                            self,
                             "@{}",
                             // This may end up in stderr diagnostics but it may also be emitted
                             // into MIR. Hence we use the remapped path if available
                             self.tcx().sess.source_map().span_to_embeddable_string(span)
-                        ));
+                        )?;
                     } else {
-                        p!("@", print_def_path(did, args));
+                        write!(self, "@")?;
+                        self.print_def_path(did, args)?;
                     }
                 } else {
-                    p!(print_def_path(did, args));
-                    p!(
-                        " upvar_tys=",
-                        print(args.as_coroutine().tupled_upvars_ty()),
-                        " resume_ty=",
-                        print(args.as_coroutine().resume_ty()),
-                        " yield_ty=",
-                        print(args.as_coroutine().yield_ty()),
-                        " return_ty=",
-                        print(args.as_coroutine().return_ty()),
-                        " witness=",
-                        print(args.as_coroutine().witness())
-                    );
+                    self.print_def_path(did, args)?;
+                    write!(self, " upvar_tys=")?;
+                    args.as_coroutine().tupled_upvars_ty().print(self)?;
+                    write!(self, " resume_ty=")?;
+                    args.as_coroutine().resume_ty().print(self)?;
+                    write!(self, " yield_ty=")?;
+                    args.as_coroutine().yield_ty().print(self)?;
+                    write!(self, " return_ty=")?;
+                    args.as_coroutine().return_ty().print(self)?;
                 }
 
-                p!("}}")
+                write!(self, "}}")?
             }
             ty::CoroutineWitness(did, args) => {
-                p!(write("{{"));
+                write!(self, "{{")?;
                 if !self.tcx().sess.verbose_internals() {
-                    p!("coroutine witness");
+                    write!(self, "coroutine witness")?;
                     if let Some(did) = did.as_local() {
                         let span = self.tcx().def_span(did);
-                        p!(write(
+                        write!(
+                            self,
                             "@{}",
                             // This may end up in stderr diagnostics but it may also be emitted
                             // into MIR. Hence we use the remapped path if available
                             self.tcx().sess.source_map().span_to_embeddable_string(span)
-                        ));
+                        )?;
                     } else {
-                        p!(write("@"), print_def_path(did, args));
+                        write!(self, "@")?;
+                        self.print_def_path(did, args)?;
                     }
                 } else {
-                    p!(print_def_path(did, args));
+                    self.print_def_path(did, args)?;
                 }
 
-                p!("}}")
+                write!(self, "}}")?
             }
             ty::Closure(did, args) => {
-                p!(write("{{"));
+                write!(self, "{{")?;
                 if !self.should_print_verbose() {
-                    p!(write("closure"));
+                    write!(self, "closure")?;
                     if self.should_truncate() {
                         write!(self, "@...}}")?;
                         return Ok(());
                     } else {
                         if let Some(did) = did.as_local() {
                             if self.tcx().sess.opts.unstable_opts.span_free_formats {
-                                p!("@", print_def_path(did.to_def_id(), args));
+                                write!(self, "@")?;
+                                self.print_def_path(did.to_def_id(), args)?;
                             } else {
                                 let span = self.tcx().def_span(did);
                                 let preference = if with_forced_trimmed_paths() {
@@ -960,54 +935,56 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                                 } else {
                                     FileNameDisplayPreference::Remapped
                                 };
-                                p!(write(
+                                write!(
+                                    self,
                                     "@{}",
-                                    // This may end up in stderr diagnostics but it may also be emitted
-                                    // into MIR. Hence we use the remapped path if available
+                                    // This may end up in stderr diagnostics but it may also be
+                                    // emitted into MIR. Hence we use the remapped path if
+                                    // available
                                     self.tcx().sess.source_map().span_to_string(span, preference)
-                                ));
+                                )?;
                             }
                         } else {
-                            p!(write("@"), print_def_path(did, args));
+                            write!(self, "@")?;
+                            self.print_def_path(did, args)?;
                         }
                     }
                 } else {
-                    p!(print_def_path(did, args));
-                    p!(
-                        " closure_kind_ty=",
-                        print(args.as_closure().kind_ty()),
-                        " closure_sig_as_fn_ptr_ty=",
-                        print(args.as_closure().sig_as_fn_ptr_ty()),
-                        " upvar_tys=",
-                        print(args.as_closure().tupled_upvars_ty())
-                    );
+                    self.print_def_path(did, args)?;
+                    write!(self, " closure_kind_ty=")?;
+                    args.as_closure().kind_ty().print(self)?;
+                    write!(self, " closure_sig_as_fn_ptr_ty=")?;
+                    args.as_closure().sig_as_fn_ptr_ty().print(self)?;
+                    write!(self, " upvar_tys=")?;
+                    args.as_closure().tupled_upvars_ty().print(self)?;
                 }
-                p!("}}");
+                write!(self, "}}")?;
             }
             ty::CoroutineClosure(did, args) => {
-                p!(write("{{"));
+                write!(self, "{{")?;
                 if !self.should_print_verbose() {
                     match self.tcx().coroutine_kind(self.tcx().coroutine_for_closure(did)).unwrap()
                     {
                         hir::CoroutineKind::Desugared(
                             hir::CoroutineDesugaring::Async,
                             hir::CoroutineSource::Closure,
-                        ) => p!("async closure"),
+                        ) => write!(self, "async closure")?,
                         hir::CoroutineKind::Desugared(
                             hir::CoroutineDesugaring::AsyncGen,
                             hir::CoroutineSource::Closure,
-                        ) => p!("async gen closure"),
+                        ) => write!(self, "async gen closure")?,
                         hir::CoroutineKind::Desugared(
                             hir::CoroutineDesugaring::Gen,
                             hir::CoroutineSource::Closure,
-                        ) => p!("gen closure"),
+                        ) => write!(self, "gen closure")?,
                         _ => unreachable!(
                             "coroutine from coroutine-closure should have CoroutineSource::Closure"
                         ),
                     }
                     if let Some(did) = did.as_local() {
                         if self.tcx().sess.opts.unstable_opts.span_free_formats {
-                            p!("@", print_def_path(did.to_def_id(), args));
+                            write!(self, "@")?;
+                            self.print_def_path(did.to_def_id(), args)?;
                         } else {
                             let span = self.tcx().def_span(did);
                             let preference = if with_forced_trimmed_paths() {
@@ -1015,35 +992,43 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                             } else {
                                 FileNameDisplayPreference::Remapped
                             };
-                            p!(write(
+                            write!(
+                                self,
                                 "@{}",
                                 // This may end up in stderr diagnostics but it may also be emitted
                                 // into MIR. Hence we use the remapped path if available
                                 self.tcx().sess.source_map().span_to_string(span, preference)
-                            ));
+                            )?;
                         }
                     } else {
-                        p!(write("@"), print_def_path(did, args));
+                        write!(self, "@")?;
+                        self.print_def_path(did, args)?;
                     }
                 } else {
-                    p!(print_def_path(did, args));
-                    p!(
-                        " closure_kind_ty=",
-                        print(args.as_coroutine_closure().kind_ty()),
-                        " signature_parts_ty=",
-                        print(args.as_coroutine_closure().signature_parts_ty()),
-                        " upvar_tys=",
-                        print(args.as_coroutine_closure().tupled_upvars_ty()),
-                        " coroutine_captures_by_ref_ty=",
-                        print(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
-                        " coroutine_witness_ty=",
-                        print(args.as_coroutine_closure().coroutine_witness_ty())
-                    );
+                    self.print_def_path(did, args)?;
+                    write!(self, " closure_kind_ty=")?;
+                    args.as_coroutine_closure().kind_ty().print(self)?;
+                    write!(self, " signature_parts_ty=")?;
+                    args.as_coroutine_closure().signature_parts_ty().print(self)?;
+                    write!(self, " upvar_tys=")?;
+                    args.as_coroutine_closure().tupled_upvars_ty().print(self)?;
+                    write!(self, " coroutine_captures_by_ref_ty=")?;
+                    args.as_coroutine_closure().coroutine_captures_by_ref_ty().print(self)?;
                 }
-                p!("}}");
+                write!(self, "}}")?;
+            }
+            ty::Array(ty, sz) => {
+                write!(self, "[")?;
+                ty.print(self)?;
+                write!(self, "; ")?;
+                sz.print(self)?;
+                write!(self, "]")?;
+            }
+            ty::Slice(ty) => {
+                write!(self, "[")?;
+                ty.print(self)?;
+                write!(self, "]")?;
             }
-            ty::Array(ty, sz) => p!("[", print(ty), "; ", print(sz), "]"),
-            ty::Slice(ty) => p!("[", print(ty), "]"),
         }
 
         Ok(())
@@ -1141,25 +1126,25 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 self.wrap_binder(
                     &bound_args_and_self_ty,
                     WrapBinderMode::ForAll,
-                    |(args, _), cx| {
-                        define_scoped_cx!(cx);
-                        p!(write("{}", tcx.item_name(trait_def_id)));
-                        p!("(");
+                    |(args, _), p| {
+                        write!(p, "{}", tcx.item_name(trait_def_id))?;
+                        write!(p, "(")?;
 
                         for (idx, ty) in args.iter().enumerate() {
                             if idx > 0 {
-                                p!(", ");
+                                write!(p, ", ")?;
                             }
-                            p!(print(ty));
+                            ty.print(p)?;
                         }
 
-                        p!(")");
+                        write!(p, ")")?;
                         if let Some(ty) = return_ty.skip_binder().as_type() {
                             if !ty.is_unit() {
-                                p!(" -> ", print(return_ty));
+                                write!(p, " -> ")?;
+                                return_ty.print(p)?;
                             }
                         }
-                        p!(write("{}", if paren_needed { ")" } else { "" }));
+                        write!(p, "{}", if paren_needed { ")" } else { "" })?;
 
                         first = false;
                         Ok(())
@@ -1185,13 +1170,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         for (trait_pred, assoc_items) in traits {
             write!(self, "{}", if first { "" } else { " + " })?;
 
-            self.wrap_binder(&trait_pred, WrapBinderMode::ForAll, |trait_pred, cx| {
-                define_scoped_cx!(cx);
-
+            self.wrap_binder(&trait_pred, WrapBinderMode::ForAll, |trait_pred, p| {
                 if trait_pred.polarity == ty::PredicatePolarity::Negative {
-                    p!("!");
+                    write!(p, "!")?;
                 }
-                p!(print(trait_pred.trait_ref.print_only_trait_name()));
+                trait_pred.trait_ref.print_only_trait_name().print(p)?;
 
                 let generics = tcx.generics_of(trait_pred.def_id());
                 let own_args = generics.own_args_no_defaults(tcx, trait_pred.trait_ref.args);
@@ -1201,32 +1184,32 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
 
                     for ty in own_args {
                         if first {
-                            p!("<");
+                            write!(p, "<")?;
                             first = false;
                         } else {
-                            p!(", ");
+                            write!(p, ", ")?;
                         }
-                        p!(print(ty));
+                        ty.print(p)?;
                     }
 
                     for (assoc_item_def_id, term) in assoc_items {
                         if first {
-                            p!("<");
+                            write!(p, "<")?;
                             first = false;
                         } else {
-                            p!(", ");
+                            write!(p, ", ")?;
                         }
 
-                        p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name()));
+                        write!(p, "{} = ", tcx.associated_item(assoc_item_def_id).name())?;
 
                         match term.skip_binder().kind() {
-                            TermKind::Ty(ty) => p!(print(ty)),
-                            TermKind::Const(c) => p!(print(c)),
+                            TermKind::Ty(ty) => ty.print(p)?,
+                            TermKind::Const(c) => c.print(p)?,
                         };
                     }
 
                     if !first {
-                        p!(">");
+                        write!(p, ">")?;
                     }
                 }
 
@@ -1326,9 +1309,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
     ) -> Result<(), PrintError> {
         let def_key = self.tcx().def_key(alias_ty.def_id);
         self.path_generic_args(
-            |cx| {
-                cx.path_append(
-                    |cx| cx.path_qualified(alias_ty.self_ty(), None),
+            |p| {
+                p.path_append(
+                    |p| p.path_qualified(alias_ty.self_ty(), None),
                     &def_key.disambiguated_data,
                 )
             },
@@ -1392,23 +1375,22 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         let mut first = true;
 
         if let Some(bound_principal) = predicates.principal() {
-            self.wrap_binder(&bound_principal, WrapBinderMode::ForAll, |principal, cx| {
-                define_scoped_cx!(cx);
-                p!(print_def_path(principal.def_id, &[]));
+            self.wrap_binder(&bound_principal, WrapBinderMode::ForAll, |principal, p| {
+                p.print_def_path(principal.def_id, &[])?;
 
                 let mut resugared = false;
 
                 // Special-case `Fn(...) -> ...` and re-sugar it.
-                let fn_trait_kind = cx.tcx().fn_trait_kind_from_def_id(principal.def_id);
-                if !cx.should_print_verbose() && fn_trait_kind.is_some() {
+                let fn_trait_kind = p.tcx().fn_trait_kind_from_def_id(principal.def_id);
+                if !p.should_print_verbose() && fn_trait_kind.is_some() {
                     if let ty::Tuple(tys) = principal.args.type_at(0).kind() {
                         let mut projections = predicates.projection_bounds();
                         if let (Some(proj), None) = (projections.next(), projections.next()) {
-                            p!(pretty_fn_sig(
+                            p.pretty_fn_sig(
                                 tys,
                                 false,
-                                proj.skip_binder().term.as_type().expect("Return type was a const")
-                            ));
+                                proj.skip_binder().term.as_type().expect("Return type was a const"),
+                            )?;
                             resugared = true;
                         }
                     }
@@ -1418,18 +1400,18 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 // in order to place the projections inside the `<...>`.
                 if !resugared {
                     let principal_with_self =
-                        principal.with_self_ty(cx.tcx(), cx.tcx().types.trait_object_dummy_self);
+                        principal.with_self_ty(p.tcx(), p.tcx().types.trait_object_dummy_self);
 
-                    let args = cx
+                    let args = p
                         .tcx()
                         .generics_of(principal_with_self.def_id)
-                        .own_args_no_defaults(cx.tcx(), principal_with_self.args);
+                        .own_args_no_defaults(p.tcx(), principal_with_self.args);
 
                     let bound_principal_with_self = bound_principal
-                        .with_self_ty(cx.tcx(), cx.tcx().types.trait_object_dummy_self);
+                        .with_self_ty(p.tcx(), p.tcx().types.trait_object_dummy_self);
 
-                    let clause: ty::Clause<'tcx> = bound_principal_with_self.upcast(cx.tcx());
-                    let super_projections: Vec<_> = elaborate::elaborate(cx.tcx(), [clause])
+                    let clause: ty::Clause<'tcx> = bound_principal_with_self.upcast(p.tcx());
+                    let super_projections: Vec<_> = elaborate::elaborate(p.tcx(), [clause])
                         .filter_only_self()
                         .filter_map(|clause| clause.as_projection_clause())
                         .collect();
@@ -1440,15 +1422,15 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                             // Filter out projections that are implied by the super predicates.
                             let proj_is_implied = super_projections.iter().any(|&super_proj| {
                                 let super_proj = super_proj.map_bound(|super_proj| {
-                                    ty::ExistentialProjection::erase_self_ty(cx.tcx(), super_proj)
+                                    ty::ExistentialProjection::erase_self_ty(p.tcx(), super_proj)
                                 });
 
                                 // This function is sometimes called on types with erased and
                                 // anonymized regions, but the super projections can still
                                 // contain named regions. So we erase and anonymize everything
                                 // here to compare the types modulo regions below.
-                                let proj = cx.tcx().erase_regions(proj);
-                                let super_proj = cx.tcx().erase_regions(super_proj);
+                                let proj = p.tcx().erase_regions(proj);
+                                let super_proj = p.tcx().erase_regions(super_proj);
 
                                 proj == super_proj
                             });
@@ -1462,16 +1444,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                         .collect();
 
                     projections
-                        .sort_by_cached_key(|proj| cx.tcx().item_name(proj.def_id).to_string());
+                        .sort_by_cached_key(|proj| p.tcx().item_name(proj.def_id).to_string());
 
                     if !args.is_empty() || !projections.is_empty() {
-                        p!(generic_delimiters(|cx| {
-                            cx.comma_sep(args.iter().copied())?;
+                        p.generic_delimiters(|p| {
+                            p.comma_sep(args.iter().copied())?;
                             if !args.is_empty() && !projections.is_empty() {
-                                write!(cx, ", ")?;
+                                write!(p, ", ")?;
                             }
-                            cx.comma_sep(projections.iter().copied())
-                        }));
+                            p.comma_sep(projections.iter().copied())
+                        })?;
                     }
                 }
                 Ok(())
@@ -1480,11 +1462,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             first = false;
         }
 
-        define_scoped_cx!(self);
-
         // Builtin bounds.
         // FIXME(eddyb) avoid printing twice (needed to ensure
-        // that the auto traits are sorted *and* printed via cx).
+        // that the auto traits are sorted *and* printed via p).
         let mut auto_traits: Vec<_> = predicates.auto_traits().collect();
 
         // The auto traits come ordered by `DefPathHash`. While
@@ -1498,11 +1478,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
 
         for def_id in auto_traits {
             if !first {
-                p!(" + ");
+                write!(self, " + ")?;
             }
             first = false;
 
-            p!(print_def_path(def_id, &[]));
+            self.print_def_path(def_id, &[])?;
         }
 
         Ok(())
@@ -1514,18 +1494,18 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         c_variadic: bool,
         output: Ty<'tcx>,
     ) -> Result<(), PrintError> {
-        define_scoped_cx!(self);
-
-        p!("(", comma_sep(inputs.iter().copied()));
+        write!(self, "(")?;
+        self.comma_sep(inputs.iter().copied())?;
         if c_variadic {
             if !inputs.is_empty() {
-                p!(", ");
+                write!(self, ", ")?;
             }
-            p!("...");
+            write!(self, "...")?;
         }
-        p!(")");
+        write!(self, ")")?;
         if !output.is_unit() {
-            p!(" -> ", print(output));
+            write!(self, " -> ")?;
+            output.print(self)?;
         }
 
         Ok(())
@@ -1536,10 +1516,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         ct: ty::Const<'tcx>,
         print_ty: bool,
     ) -> Result<(), PrintError> {
-        define_scoped_cx!(self);
-
         if self.should_print_verbose() {
-            p!(write("{:?}", ct));
+            write!(self, "{ct:?}")?;
             return Ok(());
         }
 
@@ -1547,25 +1525,28 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
                 match self.tcx().def_kind(def) {
                     DefKind::Const | DefKind::AssocConst => {
-                        p!(print_value_path(def, args))
+                        self.print_value_path(def, args)?;
                     }
                     DefKind::AnonConst => {
                         if def.is_local()
                             && let span = self.tcx().def_span(def)
                             && let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
                         {
-                            p!(write("{}", snip))
+                            write!(self, "{snip}")?;
                         } else {
-                            // Do not call `print_value_path` as if a parent of this anon const is an impl it will
-                            // attempt to print out the impl trait ref i.e. `<T as Trait>::{constant#0}`. This would
-                            // cause printing to enter an infinite recursion if the anon const is in the self type i.e.
-                            // `impl<T: Default> Default for [T; 32 - 1 - 1 - 1] {`
-                            // where we would try to print `<[T; /* print `constant#0` again */] as Default>::{constant#0}`
-                            p!(write(
+                            // Do not call `print_value_path` as if a parent of this anon const is
+                            // an impl it will attempt to print out the impl trait ref i.e. `<T as
+                            // Trait>::{constant#0}`. This would cause printing to enter an
+                            // infinite recursion if the anon const is in the self type i.e.
+                            // `impl<T: Default> Default for [T; 32 - 1 - 1 - 1] {` where we would
+                            // try to print
+                            // `<[T; /* print constant#0 again */] as // Default>::{constant#0}`.
+                            write!(
+                                self,
                                 "{}::{}",
                                 self.tcx().crate_name(def.krate),
                                 self.tcx().def_path(def).to_string_no_crate_verbose()
-                            ))
+                            )?;
                         }
                     }
                     defkind => bug!("`{:?}` has unexpected defkind {:?}", ct, defkind),
@@ -1573,11 +1554,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             }
             ty::ConstKind::Infer(infer_ct) => match infer_ct {
                 ty::InferConst::Var(ct_vid) if let Some(name) = self.const_infer_name(ct_vid) => {
-                    p!(write("{}", name))
+                    write!(self, "{name}")?;
                 }
                 _ => write!(self, "_")?,
             },
-            ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
+            ty::ConstKind::Param(ParamConst { name, .. }) => write!(self, "{name}")?,
             ty::ConstKind::Value(cv) => {
                 return self.pretty_print_const_valtree(cv, print_ty);
             }
@@ -1585,11 +1566,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             ty::ConstKind::Bound(debruijn, bound_var) => {
                 rustc_type_ir::debug_bound_var(self, debruijn, bound_var)?
             }
-            ty::ConstKind::Placeholder(placeholder) => p!(write("{placeholder:?}")),
+            ty::ConstKind::Placeholder(placeholder) => write!(self, "{placeholder:?}")?,
             // FIXME(generic_const_exprs):
             // write out some legible representation of an abstract const?
             ty::ConstKind::Expr(expr) => self.pretty_print_const_expr(expr, print_ty)?,
-            ty::ConstKind::Error(_) => p!("{{const error}}"),
+            ty::ConstKind::Error(_) => write!(self, "{{const error}}")?,
         };
         Ok(())
     }
@@ -1599,7 +1580,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         expr: Expr<'tcx>,
         print_ty: bool,
     ) -> Result<(), PrintError> {
-        define_scoped_cx!(self);
         match expr.kind {
             ty::ExprKind::Binop(op) => {
                 let (_, _, c1, c2) = expr.binop_args();
@@ -1638,7 +1618,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                     |this| this.pretty_print_const(c1, print_ty),
                     lhs_parenthesized,
                 )?;
-                p!(write(" {formatted_op} "));
+                write!(self, " {formatted_op} ")?;
                 self.maybe_parenthesized(
                     |this| this.pretty_print_const(c2, print_ty),
                     rhs_parenthesized,
@@ -1661,7 +1641,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                     ty::ConstKind::Expr(_) => true,
                     _ => false,
                 };
-                p!(write("{formatted_op}"));
+                write!(self, "{formatted_op}")?;
                 self.maybe_parenthesized(
                     |this| this.pretty_print_const(ct, print_ty),
                     parenthesized,
@@ -1672,7 +1652,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
 
                 write!(self, "(")?;
                 self.pretty_print_const(fn_def, print_ty)?;
-                p!(")(", comma_sep(fn_args), ")");
+                write!(self, ")(")?;
+                self.comma_sep(fn_args)?;
+                write!(self, ")")?;
             }
             ty::ExprKind::Cast(kind) => {
                 let (_, value, to_ty) = expr.cast_args();
@@ -1722,8 +1704,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         ptr: Pointer,
         ty: Ty<'tcx>,
     ) -> Result<(), PrintError> {
-        define_scoped_cx!(self);
-
         let (prov, offset) = ptr.prov_and_relative_offset();
         match ty.kind() {
             // Byte strings (&[u8; N])
@@ -1738,19 +1718,19 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                             if let Ok(byte_str) =
                                 alloc.inner().get_bytes_strip_provenance(&self.tcx(), range)
                             {
-                                p!(pretty_print_byte_str(byte_str))
+                                self.pretty_print_byte_str(byte_str)?;
                             } else {
-                                p!("<too short allocation>")
+                                write!(self, "<too short allocation>")?;
                             }
                         }
                         // FIXME: for statics, vtables, and functions, we could in principle print more detail.
                         Some(GlobalAlloc::Static(def_id)) => {
-                            p!(write("<static({:?})>", def_id))
+                            write!(self, "<static({def_id:?})>")?;
                         }
-                        Some(GlobalAlloc::Function { .. }) => p!("<function>"),
-                        Some(GlobalAlloc::VTable(..)) => p!("<vtable>"),
-                        Some(GlobalAlloc::TypeId { .. }) => p!("<typeid>"),
-                        None => p!("<dangling pointer>"),
+                        Some(GlobalAlloc::Function { .. }) => write!(self, "<function>")?,
+                        Some(GlobalAlloc::VTable(..)) => write!(self, "<vtable>")?,
+                        Some(GlobalAlloc::TypeId { .. }) => write!(self, "<typeid>")?,
+                        None => write!(self, "<dangling pointer>")?,
                     }
                     return Ok(());
                 }
@@ -1782,40 +1762,38 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         ty: Ty<'tcx>,
         print_ty: bool,
     ) -> Result<(), PrintError> {
-        define_scoped_cx!(self);
-
         match ty.kind() {
             // Bool
-            ty::Bool if int == ScalarInt::FALSE => p!("false"),
-            ty::Bool if int == ScalarInt::TRUE => p!("true"),
+            ty::Bool if int == ScalarInt::FALSE => write!(self, "false")?,
+            ty::Bool if int == ScalarInt::TRUE => write!(self, "true")?,
             // Float
             ty::Float(fty) => match fty {
                 ty::FloatTy::F16 => {
                     let val = Half::try_from(int).unwrap();
-                    p!(write("{}{}f16", val, if val.is_finite() { "" } else { "_" }))
+                    write!(self, "{}{}f16", val, if val.is_finite() { "" } else { "_" })?;
                 }
                 ty::FloatTy::F32 => {
                     let val = Single::try_from(int).unwrap();
-                    p!(write("{}{}f32", val, if val.is_finite() { "" } else { "_" }))
+                    write!(self, "{}{}f32", val, if val.is_finite() { "" } else { "_" })?;
                 }
                 ty::FloatTy::F64 => {
                     let val = Double::try_from(int).unwrap();
-                    p!(write("{}{}f64", val, if val.is_finite() { "" } else { "_" }))
+                    write!(self, "{}{}f64", val, if val.is_finite() { "" } else { "_" })?;
                 }
                 ty::FloatTy::F128 => {
                     let val = Quad::try_from(int).unwrap();
-                    p!(write("{}{}f128", val, if val.is_finite() { "" } else { "_" }))
+                    write!(self, "{}{}f128", val, if val.is_finite() { "" } else { "_" })?;
                 }
             },
             // Int
             ty::Uint(_) | ty::Int(_) => {
                 let int =
                     ConstInt::new(int, matches!(ty.kind(), ty::Int(_)), ty.is_ptr_sized_integral());
-                if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) }
+                if print_ty { write!(self, "{int:#?}")? } else { write!(self, "{int:?}")? }
             }
             // Char
             ty::Char if char::try_from(int).is_ok() => {
-                p!(write("{:?}", char::try_from(int).unwrap()))
+                write!(self, "{:?}", char::try_from(int).unwrap())?;
             }
             // Pointer types
             ty::Ref(..) | ty::RawPtr(_, _) | ty::FnPtr(..) => {
@@ -1831,7 +1809,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             }
             ty::Pat(base_ty, pat) if self.tcx().validate_scalar_in_layout(int, ty) => {
                 self.pretty_print_const_scalar_int(int, *base_ty, print_ty)?;
-                p!(write(" is {pat:?}"));
+                write!(self, " is {pat:?}")?;
             }
             // Nontrivial types with scalar bit representation
             _ => {
@@ -1880,10 +1858,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         cv: ty::Value<'tcx>,
         print_ty: bool,
     ) -> Result<(), PrintError> {
-        define_scoped_cx!(self);
-
         if with_reduced_queries() || self.should_print_verbose() {
-            p!(write("ValTree({:?}: ", cv.valtree), print(cv.ty), ")");
+            write!(self, "ValTree({:?}: ", cv.valtree)?;
+            cv.ty.print(self)?;
+            write!(self, ")")?;
             return Ok(());
         }
 
@@ -1904,13 +1882,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                     let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
                         bug!("expected to convert valtree to raw bytes for type {:?}", cv.ty)
                     });
-                    p!(write("{:?}", String::from_utf8_lossy(bytes)));
+                    write!(self, "{:?}", String::from_utf8_lossy(bytes))?;
                     return Ok(());
                 }
                 _ => {
                     let cv = ty::Value { valtree: cv.valtree, ty: inner_ty };
-                    p!("&");
-                    p!(pretty_print_const_valtree(cv, print_ty));
+                    write!(self, "&")?;
+                    self.pretty_print_const_valtree(cv, print_ty)?;
                     return Ok(());
                 }
             },
@@ -1918,8 +1896,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
                     bug!("expected to convert valtree to raw bytes for type {:?}", t)
                 });
-                p!("*");
-                p!(pretty_print_byte_str(bytes));
+                write!(self, "*")?;
+                self.pretty_print_byte_str(bytes)?;
                 return Ok(());
             }
             // Aggregates, printed as array/tuple/struct/variant construction syntax.
@@ -1932,14 +1910,17 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 let fields = contents.fields.iter().copied();
                 match *cv.ty.kind() {
                     ty::Array(..) => {
-                        p!("[", comma_sep(fields), "]");
+                        write!(self, "[")?;
+                        self.comma_sep(fields)?;
+                        write!(self, "]")?;
                     }
                     ty::Tuple(..) => {
-                        p!("(", comma_sep(fields));
+                        write!(self, "(")?;
+                        self.comma_sep(fields)?;
                         if contents.fields.len() == 1 {
-                            p!(",");
+                            write!(self, ",")?;
                         }
-                        p!(")");
+                        write!(self, ")")?;
                     }
                     ty::Adt(def, _) if def.variants().is_empty() => {
                         self.typed_value(
@@ -1955,23 +1936,26 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                         let variant_idx =
                             contents.variant.expect("destructed const of adt without variant idx");
                         let variant_def = &def.variant(variant_idx);
-                        p!(print_value_path(variant_def.def_id, args));
+                        self.print_value_path(variant_def.def_id, args)?;
                         match variant_def.ctor_kind() {
                             Some(CtorKind::Const) => {}
                             Some(CtorKind::Fn) => {
-                                p!("(", comma_sep(fields), ")");
+                                write!(self, "(")?;
+                                self.comma_sep(fields)?;
+                                write!(self, ")")?;
                             }
                             None => {
-                                p!(" {{ ");
+                                write!(self, " {{ ")?;
                                 let mut first = true;
                                 for (field_def, field) in iter::zip(&variant_def.fields, fields) {
                                     if !first {
-                                        p!(", ");
+                                        write!(self, ", ")?;
                                     }
-                                    p!(write("{}: ", field_def.name), print(field));
+                                    write!(self, "{}: ", field_def.name)?;
+                                    field.print(self)?;
                                     first = false;
                                 }
-                                p!(" }}");
+                                write!(self, " }}")?;
                             }
                         }
                     }
@@ -1980,7 +1964,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 return Ok(());
             }
             (ty::ValTreeKind::Leaf(leaf), ty::Ref(_, inner_ty, _)) => {
-                p!(write("&"));
+                write!(self, "&")?;
                 return self.pretty_print_const_scalar_int(*leaf, inner_ty, print_ty);
             }
             (ty::ValTreeKind::Leaf(leaf), _) => {
@@ -1988,7 +1972,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             }
             (_, ty::FnDef(def_id, args)) => {
                 // Never allowed today, but we still encounter them in invalid const args.
-                p!(print_value_path(def_id, args));
+                self.print_value_path(def_id, args)?;
                 return Ok(());
             }
             // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
@@ -1998,12 +1982,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
 
         // fallback
         if cv.valtree.is_zst() {
-            p!(write("<ZST>"));
+            write!(self, "<ZST>")?;
         } else {
-            p!(write("{:?}", cv.valtree));
+            write!(self, "{:?}", cv.valtree)?;
         }
         if print_ty {
-            p!(": ", print(cv.ty));
+            write!(self, ": ")?;
+            cv.ty.print(self)?;
         }
         Ok(())
     }
@@ -2016,20 +2001,19 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
 
         write!(self, "impl ")?;
-        self.wrap_binder(&sig, WrapBinderMode::ForAll, |sig, cx| {
-            define_scoped_cx!(cx);
-
-            p!(write("{kind}("));
+        self.wrap_binder(&sig, WrapBinderMode::ForAll, |sig, p| {
+            write!(p, "{kind}(")?;
             for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
                 if i > 0 {
-                    p!(", ");
+                    write!(p, ", ")?;
                 }
-                p!(print(arg));
+                arg.print(p)?;
             }
-            p!(")");
+            write!(p, ")")?;
 
             if !sig.output().is_unit() {
-                p!(" -> ", print(sig.output()));
+                write!(p, " -> ")?;
+                sig.output().print(p)?;
             }
 
             Ok(())
@@ -2040,15 +2024,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         &mut self,
         constness: ty::BoundConstness,
     ) -> Result<(), PrintError> {
-        define_scoped_cx!(self);
-
         match constness {
-            ty::BoundConstness::Const => {
-                p!("const ");
-            }
-            ty::BoundConstness::Maybe => {
-                p!("[const] ");
-            }
+            ty::BoundConstness::Const => write!(self, "const ")?,
+            ty::BoundConstness::Maybe => write!(self, "[const] ")?,
         }
         Ok(())
     }
@@ -2065,10 +2043,10 @@ pub(crate) fn pretty_print_const<'tcx>(
 ) -> fmt::Result {
     ty::tls::with(|tcx| {
         let literal = tcx.lift(c).unwrap();
-        let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-        cx.print_alloc_ids = true;
-        cx.pretty_print_const(literal, print_types)?;
-        fmt.write_str(&cx.into_buffer())?;
+        let mut p = FmtPrinter::new(tcx, Namespace::ValueNS);
+        p.print_alloc_ids = true;
+        p.pretty_print_const(literal, print_types)?;
+        fmt.write_str(&p.into_buffer())?;
         Ok(())
     })
 }
@@ -2188,7 +2166,7 @@ impl<'t> TyCtxt<'t> {
         let ns = guess_def_namespace(self, def_id);
         debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns);
 
-        FmtPrinter::print_string(self, ns, |cx| cx.print_def_path(def_id, args)).unwrap()
+        FmtPrinter::print_string(self, ns, |p| p.print_def_path(def_id, args)).unwrap()
     }
 
     pub fn value_path_str_with_args(
@@ -2200,7 +2178,7 @@ impl<'t> TyCtxt<'t> {
         let ns = guess_def_namespace(self, def_id);
         debug!("value_path_str: def_id={:?}, ns={:?}", def_id, ns);
 
-        FmtPrinter::print_string(self, ns, |cx| cx.print_value_path(def_id, args)).unwrap()
+        FmtPrinter::print_string(self, ns, |p| p.print_value_path(def_id, args)).unwrap()
     }
 }
 
@@ -2362,15 +2340,14 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
     fn path_append_impl(
         &mut self,
         print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
-        _disambiguated_data: &DisambiguatedDefPathData,
         self_ty: Ty<'tcx>,
         trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError> {
         self.pretty_path_append_impl(
-            |cx| {
-                print_prefix(cx)?;
-                if !cx.empty_path {
-                    write!(cx, "::")?;
+            |p| {
+                print_prefix(p)?;
+                if !p.empty_path {
+                    write!(p, "::")?;
                 }
 
                 Ok(())
@@ -2424,7 +2401,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
             if self.in_value {
                 write!(self, "::")?;
             }
-            self.generic_delimiters(|cx| cx.comma_sep(args.iter().copied()))
+            self.generic_delimiters(|p| p.comma_sep(args.iter().copied()))
         } else {
             Ok(())
         }
@@ -2460,7 +2437,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
     where
         T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
     {
-        self.pretty_print_in_binder(value)
+        self.wrap_binder(value, WrapBinderMode::ForAll, |new_value, this| new_value.print(this))
     }
 
     fn wrap_binder<T, C: FnOnce(&T, &mut Self) -> Result<(), PrintError>>(
@@ -2472,7 +2449,12 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        self.pretty_wrap_binder(value, mode, f)
+        let old_region_index = self.region_index;
+        let (new_value, _) = self.name_all_regions(value, mode)?;
+        f(&new_value, self)?;
+        self.region_index = old_region_index;
+        self.binder_depth -= 1;
+        Ok(())
     }
 
     fn typed_value(
@@ -2556,11 +2538,10 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
         ty: Ty<'tcx>,
     ) -> Result<(), PrintError> {
         let print = |this: &mut Self| {
-            define_scoped_cx!(this);
             if this.print_alloc_ids {
-                p!(write("{:?}", p));
+                write!(this, "{p:?}")?;
             } else {
-                p!("&_");
+                write!(this, "&_")?;
             }
             Ok(())
         };
@@ -2571,17 +2552,15 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
 // HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
 impl<'tcx> FmtPrinter<'_, 'tcx> {
     pub fn pretty_print_region(&mut self, region: ty::Region<'tcx>) -> Result<(), fmt::Error> {
-        define_scoped_cx!(self);
-
         // Watch out for region highlights.
         let highlight = self.region_highlight_mode;
         if let Some(n) = highlight.region_highlighted(region) {
-            p!(write("'{}", n));
+            write!(self, "'{n}")?;
             return Ok(());
         }
 
         if self.should_print_verbose() {
-            p!(write("{:?}", region));
+            write!(self, "{region:?}")?;
             return Ok(());
         }
 
@@ -2593,12 +2572,12 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         // `explain_region()` or `note_and_explain_region()`.
         match region.kind() {
             ty::ReEarlyParam(data) => {
-                p!(write("{}", data.name));
+                write!(self, "{}", data.name)?;
                 return Ok(());
             }
             ty::ReLateParam(ty::LateParamRegion { kind, .. }) => {
                 if let Some(name) = kind.get_name(self.tcx) {
-                    p!(write("{}", name));
+                    write!(self, "{name}")?;
                     return Ok(());
                 }
             }
@@ -2607,31 +2586,31 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                 bound: ty::BoundRegion { kind: br, .. }, ..
             }) => {
                 if let Some(name) = br.get_name(self.tcx) {
-                    p!(write("{}", name));
+                    write!(self, "{name}")?;
                     return Ok(());
                 }
 
                 if let Some((region, counter)) = highlight.highlight_bound_region {
                     if br == region {
-                        p!(write("'{}", counter));
+                        write!(self, "'{counter}")?;
                         return Ok(());
                     }
                 }
             }
             ty::ReVar(region_vid) if identify_regions => {
-                p!(write("{:?}", region_vid));
+                write!(self, "{region_vid:?}")?;
                 return Ok(());
             }
             ty::ReVar(_) => {}
             ty::ReErased => {}
             ty::ReError(_) => {}
             ty::ReStatic => {
-                p!("'static");
+                write!(self, "'static")?;
                 return Ok(());
             }
         }
 
-        p!("'_");
+        write!(self, "'_")?;
 
         Ok(())
     }
@@ -2749,17 +2728,17 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         debug!("self.used_region_names: {:?}", self.used_region_names);
 
         let mut empty = true;
-        let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
+        let mut start_or_continue = |p: &mut Self, start: &str, cont: &str| {
             let w = if empty {
                 empty = false;
                 start
             } else {
                 cont
             };
-            let _ = write!(cx, "{w}");
+            let _ = write!(p, "{w}");
         };
-        let do_continue = |cx: &mut Self, cont: Symbol| {
-            let _ = write!(cx, "{cont}");
+        let do_continue = |p: &mut Self, cont: Symbol| {
+            let _ = write!(p, "{cont}");
         };
 
         let possible_names = ('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}")));
@@ -2859,38 +2838,6 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         Ok((new_value, map))
     }
 
-    pub fn pretty_print_in_binder<T>(
-        &mut self,
-        value: &ty::Binder<'tcx, T>,
-    ) -> Result<(), fmt::Error>
-    where
-        T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
-    {
-        let old_region_index = self.region_index;
-        let (new_value, _) = self.name_all_regions(value, WrapBinderMode::ForAll)?;
-        new_value.print(self)?;
-        self.region_index = old_region_index;
-        self.binder_depth -= 1;
-        Ok(())
-    }
-
-    pub fn pretty_wrap_binder<T, C: FnOnce(&T, &mut Self) -> Result<(), fmt::Error>>(
-        &mut self,
-        value: &ty::Binder<'tcx, T>,
-        mode: WrapBinderMode,
-        f: C,
-    ) -> Result<(), fmt::Error>
-    where
-        T: TypeFoldable<TyCtxt<'tcx>>,
-    {
-        let old_region_index = self.region_index;
-        let (new_value, _) = self.name_all_regions(value, mode)?;
-        f(&new_value, self)?;
-        self.region_index = old_region_index;
-        self.binder_depth -= 1;
-        Ok(())
-    }
-
     fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
@@ -2944,8 +2891,8 @@ impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T>
 where
     T: Print<'tcx, P> + TypeFoldable<TyCtxt<'tcx>>,
 {
-    fn print(&self, cx: &mut P) -> Result<(), PrintError> {
-        cx.print_in_binder(self)
+    fn print(&self, p: &mut P) -> Result<(), PrintError> {
+        p.print_in_binder(self)
     }
 }
 
@@ -2953,9 +2900,10 @@ impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<'
 where
     T: Print<'tcx, P>,
 {
-    fn print(&self, cx: &mut P) -> Result<(), PrintError> {
-        define_scoped_cx!(cx);
-        p!(print(self.0), ": ", print(self.1));
+    fn print(&self, p: &mut P) -> Result<(), PrintError> {
+        self.0.print(p)?;
+        write!(p, ": ")?;
+        self.1.print(p)?;
         Ok(())
     }
 }
@@ -3094,11 +3042,11 @@ macro_rules! forward_display_to_print {
         $(#[allow(unused_lifetimes)] impl<'tcx> fmt::Display for $ty {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 ty::tls::with(|tcx| {
-                    let mut cx = FmtPrinter::new(tcx, Namespace::TypeNS);
+                    let mut p = FmtPrinter::new(tcx, Namespace::TypeNS);
                     tcx.lift(*self)
                         .expect("could not lift for printing")
-                        .print(&mut cx)?;
-                    f.write_str(&cx.into_buffer())?;
+                        .print(&mut p)?;
+                    f.write_str(&p.into_buffer())?;
                     Ok(())
                 })
             }
@@ -3107,10 +3055,9 @@ macro_rules! forward_display_to_print {
 }
 
 macro_rules! define_print {
-    (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
+    (($self:ident, $p:ident): $($ty:ty $print:block)+) => {
         $(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
-            fn print(&$self, $cx: &mut P) -> Result<(), PrintError> {
-                define_scoped_cx!($cx);
+            fn print(&$self, $p: &mut P) -> Result<(), PrintError> {
                 let _: () = $print;
                 Ok(())
             }
@@ -3119,8 +3066,8 @@ macro_rules! define_print {
 }
 
 macro_rules! define_print_and_forward_display {
-    (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
-        define_print!(($self, $cx): $($ty $print)*);
+    (($self:ident, $p:ident): $($ty:ty $print:block)+) => {
+        define_print!(($self, $p): $($ty $print)*);
         forward_display_to_print!($($ty),+);
     };
 }
@@ -3133,37 +3080,38 @@ forward_display_to_print! {
 }
 
 define_print! {
-    (self, cx):
+    (self, p):
 
     ty::FnSig<'tcx> {
-        p!(write("{}", self.safety.prefix_str()));
+        write!(p, "{}", self.safety.prefix_str())?;
 
         if self.abi != ExternAbi::Rust {
-            p!(write("extern {} ", self.abi));
+            write!(p, "extern {} ", self.abi)?;
         }
 
-        p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
+        write!(p, "fn")?;
+        p.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())?;
     }
 
     ty::TraitRef<'tcx> {
-        p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
+        write!(p, "<{} as {}>", self.self_ty(), self.print_only_trait_path())?;
     }
 
     ty::AliasTy<'tcx> {
         let alias_term: ty::AliasTerm<'tcx> = (*self).into();
-        p!(print(alias_term))
+        alias_term.print(p)?;
     }
 
     ty::AliasTerm<'tcx> {
-        match self.kind(cx.tcx()) {
-            ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => p!(pretty_print_inherent_projection(*self)),
+        match self.kind(p.tcx()) {
+            ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => p.pretty_print_inherent_projection(*self)?,
             ty::AliasTermKind::ProjectionTy => {
-                if !(cx.should_print_verbose() || with_reduced_queries())
-                    && cx.tcx().is_impl_trait_in_trait(self.def_id)
+                if !(p.should_print_verbose() || with_reduced_queries())
+                    && p.tcx().is_impl_trait_in_trait(self.def_id)
                 {
-                    p!(pretty_print_rpitit(self.def_id, self.args))
+                    p.pretty_print_rpitit(self.def_id, self.args)?;
                 } else {
-                    p!(print_def_path(self.def_id, self.args));
+                    p.print_def_path(self.def_id, self.args)?;
                 }
             }
             ty::AliasTermKind::FreeTy
@@ -3171,17 +3119,18 @@ define_print! {
             | ty::AliasTermKind::OpaqueTy
             | ty::AliasTermKind::UnevaluatedConst
             | ty::AliasTermKind::ProjectionConst => {
-                p!(print_def_path(self.def_id, self.args));
+                p.print_def_path(self.def_id, self.args)?;
             }
         }
     }
 
     ty::TraitPredicate<'tcx> {
-        p!(print(self.trait_ref.self_ty()), ": ");
+        self.trait_ref.self_ty().print(p)?;
+        write!(p, ": ")?;
         if let ty::PredicatePolarity::Negative = self.polarity {
-            p!("!");
+            write!(p, "!")?;
         }
-        p!(print(self.trait_ref.print_trait_sugared()))
+        self.trait_ref.print_trait_sugared().print(p)?;
     }
 
     ty::HostEffectPredicate<'tcx> {
@@ -3189,196 +3138,223 @@ define_print! {
             ty::BoundConstness::Const => { "const" }
             ty::BoundConstness::Maybe => { "[const]" }
         };
-        p!(print(self.trait_ref.self_ty()), ": {constness} ");
-        p!(print(self.trait_ref.print_trait_sugared()))
+        self.trait_ref.self_ty().print(p)?;
+        write!(p, ": {constness} ")?;
+        self.trait_ref.print_trait_sugared().print(p)?;
     }
 
     ty::TypeAndMut<'tcx> {
-        p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
+        write!(p, "{}", self.mutbl.prefix_str())?;
+        self.ty.print(p)?;
     }
 
     ty::ClauseKind<'tcx> {
         match *self {
-            ty::ClauseKind::Trait(ref data) => {
-                p!(print(data))
-            }
-            ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)),
-            ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)),
-            ty::ClauseKind::Projection(predicate) => p!(print(predicate)),
-            ty::ClauseKind::HostEffect(predicate) => p!(print(predicate)),
+            ty::ClauseKind::Trait(ref data) => data.print(p)?,
+            ty::ClauseKind::RegionOutlives(predicate) => predicate.print(p)?,
+            ty::ClauseKind::TypeOutlives(predicate) => predicate.print(p)?,
+            ty::ClauseKind::Projection(predicate) => predicate.print(p)?,
+            ty::ClauseKind::HostEffect(predicate) => predicate.print(p)?,
             ty::ClauseKind::ConstArgHasType(ct, ty) => {
-                p!("the constant `", print(ct), "` has type `", print(ty), "`")
+                write!(p, "the constant `")?;
+                ct.print(p)?;
+                write!(p, "` has type `")?;
+                ty.print(p)?;
+                write!(p, "`")?;
             },
-            ty::ClauseKind::WellFormed(term) => p!(print(term), " well-formed"),
+            ty::ClauseKind::WellFormed(term) => {
+                term.print(p)?;
+                write!(p, " well-formed")?;
+            }
             ty::ClauseKind::ConstEvaluatable(ct) => {
-                p!("the constant `", print(ct), "` can be evaluated")
+                write!(p, "the constant `")?;
+                ct.print(p)?;
+                write!(p, "` can be evaluated")?;
+            }
+            ty::ClauseKind::UnstableFeature(symbol) => {
+                write!(p, "unstable feature: ")?;
+                write!(p, "`{symbol}`")?;
             }
-            ty::ClauseKind::UnstableFeature(symbol) => p!("unstable feature: ", write("`{}`", symbol)),
         }
     }
 
     ty::PredicateKind<'tcx> {
         match *self {
-            ty::PredicateKind::Clause(data) => {
-                p!(print(data))
-            }
-            ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
-            ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
+            ty::PredicateKind::Clause(data) => data.print(p)?,
+            ty::PredicateKind::Subtype(predicate) => predicate.print(p)?,
+            ty::PredicateKind::Coerce(predicate) => predicate.print(p)?,
             ty::PredicateKind::DynCompatible(trait_def_id) => {
-                p!("the trait `", print_def_path(trait_def_id, &[]), "` is dyn-compatible")
+                write!(p, "the trait `")?;
+                p.print_def_path(trait_def_id, &[])?;
+                write!(p, "` is dyn-compatible")?;
             }
             ty::PredicateKind::ConstEquate(c1, c2) => {
-                p!("the constant `", print(c1), "` equals `", print(c2), "`")
+                write!(p, "the constant `")?;
+                c1.print(p)?;
+                write!(p, "` equals `")?;
+                c2.print(p)?;
+                write!(p, "`")?;
+            }
+            ty::PredicateKind::Ambiguous => write!(p, "ambiguous")?,
+            ty::PredicateKind::NormalizesTo(data) => data.print(p)?,
+            ty::PredicateKind::AliasRelate(t1, t2, dir) => {
+                t1.print(p)?;
+                write!(p, " {dir} ")?;
+                t2.print(p)?;
             }
-            ty::PredicateKind::Ambiguous => p!("ambiguous"),
-            ty::PredicateKind::NormalizesTo(data) => p!(print(data)),
-            ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)),
         }
     }
 
     ty::ExistentialPredicate<'tcx> {
         match *self {
-            ty::ExistentialPredicate::Trait(x) => p!(print(x)),
-            ty::ExistentialPredicate::Projection(x) => p!(print(x)),
-            ty::ExistentialPredicate::AutoTrait(def_id) => {
-                p!(print_def_path(def_id, &[]));
-            }
+            ty::ExistentialPredicate::Trait(x) => x.print(p)?,
+            ty::ExistentialPredicate::Projection(x) => x.print(p)?,
+            ty::ExistentialPredicate::AutoTrait(def_id) => p.print_def_path(def_id, &[])?,
         }
     }
 
     ty::ExistentialTraitRef<'tcx> {
         // Use a type that can't appear in defaults of type parameters.
-        let dummy_self = Ty::new_fresh(cx.tcx(), 0);
-        let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
-        p!(print(trait_ref.print_only_trait_path()))
+        let dummy_self = Ty::new_fresh(p.tcx(), 0);
+        let trait_ref = self.with_self_ty(p.tcx(), dummy_self);
+        trait_ref.print_only_trait_path().print(p)?;
     }
 
     ty::ExistentialProjection<'tcx> {
-        let name = cx.tcx().associated_item(self.def_id).name();
+        let name = p.tcx().associated_item(self.def_id).name();
         // The args don't contain the self ty (as it has been erased) but the corresp.
         // generics do as the trait always has a self ty param. We need to offset.
-        let args = &self.args[cx.tcx().generics_of(self.def_id).parent_count - 1..];
-        p!(path_generic_args(|cx| write!(cx, "{name}"), args), " = ", print(self.term))
+        let args = &self.args[p.tcx().generics_of(self.def_id).parent_count - 1..];
+        p.path_generic_args(|p| write!(p, "{name}"), args)?;
+        write!(p, " = ")?;
+        self.term.print(p)?;
     }
 
     ty::ProjectionPredicate<'tcx> {
-        p!(print(self.projection_term), " == ");
-        cx.reset_type_limit();
-        p!(print(self.term))
+        self.projection_term.print(p)?;
+        write!(p, " == ")?;
+        p.reset_type_limit();
+        self.term.print(p)?;
     }
 
     ty::SubtypePredicate<'tcx> {
-        p!(print(self.a), " <: ");
-        cx.reset_type_limit();
-        p!(print(self.b))
+        self.a.print(p)?;
+        write!(p, " <: ")?;
+        p.reset_type_limit();
+        self.b.print(p)?;
     }
 
     ty::CoercePredicate<'tcx> {
-        p!(print(self.a), " -> ");
-        cx.reset_type_limit();
-        p!(print(self.b))
+        self.a.print(p)?;
+        write!(p, " -> ")?;
+        p.reset_type_limit();
+        self.b.print(p)?;
     }
 
     ty::NormalizesTo<'tcx> {
-        p!(print(self.alias), " normalizes-to ");
-        cx.reset_type_limit();
-        p!(print(self.term))
+        self.alias.print(p)?;
+        write!(p, " normalizes-to ")?;
+        p.reset_type_limit();
+        self.term.print(p)?;
     }
 }
 
 define_print_and_forward_display! {
-    (self, cx):
+    (self, p):
 
     &'tcx ty::List<Ty<'tcx>> {
-        p!("{{", comma_sep(self.iter()), "}}")
+        write!(p, "{{")?;
+        p.comma_sep(self.iter())?;
+        write!(p, "}}")?;
     }
 
     TraitRefPrintOnlyTraitPath<'tcx> {
-        p!(print_def_path(self.0.def_id, self.0.args));
+        p.print_def_path(self.0.def_id, self.0.args)?;
     }
 
     TraitRefPrintSugared<'tcx> {
         if !with_reduced_queries()
-            && cx.tcx().trait_def(self.0.def_id).paren_sugar
+            && p.tcx().trait_def(self.0.def_id).paren_sugar
             && let ty::Tuple(args) = self.0.args.type_at(1).kind()
         {
-            p!(write("{}", cx.tcx().item_name(self.0.def_id)), "(");
+            write!(p, "{}(", p.tcx().item_name(self.0.def_id))?;
             for (i, arg) in args.iter().enumerate() {
                 if i > 0 {
-                    p!(", ");
+                    write!(p, ", ")?;
                 }
-                p!(print(arg));
+                arg.print(p)?;
             }
-            p!(")");
+            write!(p, ")")?;
         } else {
-            p!(print_def_path(self.0.def_id, self.0.args));
+            p.print_def_path(self.0.def_id, self.0.args)?;
         }
     }
 
     TraitRefPrintOnlyTraitName<'tcx> {
-        p!(print_def_path(self.0.def_id, &[]));
+        p.print_def_path(self.0.def_id, &[])?;
     }
 
     TraitPredPrintModifiersAndPath<'tcx> {
         if let ty::PredicatePolarity::Negative = self.0.polarity {
-            p!("!")
+            write!(p, "!")?;
         }
-        p!(print(self.0.trait_ref.print_trait_sugared()));
+        self.0.trait_ref.print_trait_sugared().print(p)?;
     }
 
     TraitPredPrintWithBoundConstness<'tcx> {
-        p!(print(self.0.trait_ref.self_ty()), ": ");
+        self.0.trait_ref.self_ty().print(p)?;
+        write!(p, ": ")?;
         if let Some(constness) = self.1 {
-            p!(pretty_print_bound_constness(constness));
+            p.pretty_print_bound_constness(constness)?;
         }
         if let ty::PredicatePolarity::Negative = self.0.polarity {
-            p!("!");
+            write!(p, "!")?;
         }
-        p!(print(self.0.trait_ref.print_trait_sugared()))
+        self.0.trait_ref.print_trait_sugared().print(p)?;
     }
 
     PrintClosureAsImpl<'tcx> {
-        p!(pretty_closure_as_impl(self.closure))
+        p.pretty_closure_as_impl(self.closure)?;
     }
 
     ty::ParamTy {
-        p!(write("{}", self.name))
+        write!(p, "{}", self.name)?;
     }
 
     ty::PlaceholderType {
         match self.bound.kind {
-            ty::BoundTyKind::Anon => p!(write("{self:?}")),
-            ty::BoundTyKind::Param(def_id) => match cx.should_print_verbose() {
-                true => p!(write("{self:?}")),
-                false => p!(write("{}", cx.tcx().item_name(def_id))),
+            ty::BoundTyKind::Anon => write!(p, "{self:?}")?,
+            ty::BoundTyKind::Param(def_id) => match p.should_print_verbose() {
+                true => write!(p, "{self:?}")?,
+                false => write!(p, "{}", p.tcx().item_name(def_id))?,
             },
         }
     }
 
     ty::ParamConst {
-        p!(write("{}", self.name))
+        write!(p, "{}", self.name)?;
     }
 
     ty::Term<'tcx> {
       match self.kind() {
-        ty::TermKind::Ty(ty) => p!(print(ty)),
-        ty::TermKind::Const(c) => p!(print(c)),
+        ty::TermKind::Ty(ty) => ty.print(p)?,
+        ty::TermKind::Const(c) => c.print(p)?,
       }
     }
 
     ty::Predicate<'tcx> {
-        p!(print(self.kind()))
+        self.kind().print(p)?;
     }
 
     ty::Clause<'tcx> {
-        p!(print(self.kind()))
+        self.kind().print(p)?;
     }
 
     GenericArg<'tcx> {
         match self.kind() {
-            GenericArgKind::Lifetime(lt) => p!(print(lt)),
-            GenericArgKind::Type(ty) => p!(print(ty)),
-            GenericArgKind::Const(ct) => p!(print(ct)),
+            GenericArgKind::Lifetime(lt) => lt.print(p)?,
+            GenericArgKind::Type(ty) => ty.print(p)?,
+            GenericArgKind::Const(ct) => ct.print(p)?,
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index a5fdce93e4b..0e2aff6f9bd 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -25,8 +25,8 @@ impl fmt::Debug for ty::TraitDef {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         ty::tls::with(|tcx| {
             with_no_trimmed_paths!({
-                let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
-                    cx.print_def_path(self.def_id, &[])
+                let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |p| {
+                    p.print_def_path(self.def_id, &[])
                 })?;
                 f.write_str(&s)
             })
@@ -38,8 +38,8 @@ impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         ty::tls::with(|tcx| {
             with_no_trimmed_paths!({
-                let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
-                    cx.print_def_path(self.did(), &[])
+                let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |p| {
+                    p.print_def_path(self.did(), &[])
                 })?;
                 f.write_str(&s)
             })
@@ -170,9 +170,9 @@ impl<'tcx> fmt::Debug for ty::Const<'tcx> {
         if let ConstKind::Value(cv) = self.kind() {
             return ty::tls::with(move |tcx| {
                 let cv = tcx.lift(cv).unwrap();
-                let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-                cx.pretty_print_const_valtree(cv, /*print_ty*/ true)?;
-                f.write_str(&cx.into_buffer())
+                let mut p = FmtPrinter::new(tcx, Namespace::ValueNS);
+                p.pretty_print_const_valtree(cv, /*print_ty*/ true)?;
+                f.write_str(&p.into_buffer())
             });
         }
         // Fall back to something verbose.
@@ -232,6 +232,7 @@ TrivialLiftImpls! {
     crate::mir::Promoted,
     crate::mir::interpret::AllocId,
     crate::mir::interpret::Scalar,
+    crate::ty::ParamConst,
     rustc_abi::ExternAbi,
     rustc_abi::Size,
     rustc_hir::Safety,
@@ -271,10 +272,6 @@ TrivialTypeTraversalImpls! {
     crate::ty::AssocItem,
     crate::ty::AssocKind,
     crate::ty::BoundRegion,
-    crate::ty::BoundVar,
-    crate::ty::InferConst,
-    crate::ty::Placeholder<crate::ty::BoundRegion>,
-    crate::ty::Placeholder<ty::BoundVar>,
     crate::ty::UserTypeAnnotationIndex,
     crate::ty::ValTree<'tcx>,
     crate::ty::abstract_const::NotConstEvaluatable,
@@ -302,9 +299,8 @@ TrivialTypeTraversalImpls! {
 // interners).
 TrivialTypeTraversalAndLiftImpls! {
     // tidy-alphabetical-start
-    crate::ty::ParamConst,
     crate::ty::ParamTy,
-    crate::ty::Placeholder<crate::ty::BoundTy>,
+    crate::ty::PlaceholderType,
     crate::ty::instance::ReifyReason,
     rustc_hir::def_id::DefId,
     // tidy-alphabetical-end
@@ -673,30 +669,30 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
         folder: &mut F,
     ) -> Result<Self, F::Error> {
         let kind = match self.kind() {
-            ConstKind::Param(p) => ConstKind::Param(p.try_fold_with(folder)?),
-            ConstKind::Infer(i) => ConstKind::Infer(i.try_fold_with(folder)?),
-            ConstKind::Bound(d, b) => {
-                ConstKind::Bound(d.try_fold_with(folder)?, b.try_fold_with(folder)?)
-            }
-            ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?),
             ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?),
             ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?),
-            ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
             ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
+
+            ConstKind::Param(_)
+            | ConstKind::Infer(_)
+            | ConstKind::Bound(..)
+            | ConstKind::Placeholder(_)
+            | ConstKind::Error(_) => return Ok(self),
         };
         if kind != self.kind() { Ok(folder.cx().mk_ct_from_kind(kind)) } else { Ok(self) }
     }
 
     fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
         let kind = match self.kind() {
-            ConstKind::Param(p) => ConstKind::Param(p.fold_with(folder)),
-            ConstKind::Infer(i) => ConstKind::Infer(i.fold_with(folder)),
-            ConstKind::Bound(d, b) => ConstKind::Bound(d.fold_with(folder), b.fold_with(folder)),
-            ConstKind::Placeholder(p) => ConstKind::Placeholder(p.fold_with(folder)),
             ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.fold_with(folder)),
             ConstKind::Value(v) => ConstKind::Value(v.fold_with(folder)),
-            ConstKind::Error(e) => ConstKind::Error(e.fold_with(folder)),
             ConstKind::Expr(e) => ConstKind::Expr(e.fold_with(folder)),
+
+            ConstKind::Param(_)
+            | ConstKind::Infer(_)
+            | ConstKind::Bound(..)
+            | ConstKind::Placeholder(_)
+            | ConstKind::Error(_) => return self,
         };
         if kind != self.kind() { folder.cx().mk_ct_from_kind(kind) } else { self }
     }
@@ -705,17 +701,15 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
 impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
     fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
         match self.kind() {
-            ConstKind::Param(p) => p.visit_with(visitor),
-            ConstKind::Infer(i) => i.visit_with(visitor),
-            ConstKind::Bound(d, b) => {
-                try_visit!(d.visit_with(visitor));
-                b.visit_with(visitor)
-            }
-            ConstKind::Placeholder(p) => p.visit_with(visitor),
             ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
             ConstKind::Value(v) => v.visit_with(visitor),
-            ConstKind::Error(e) => e.visit_with(visitor),
             ConstKind::Expr(e) => e.visit_with(visitor),
+            ConstKind::Error(e) => e.visit_with(visitor),
+
+            ConstKind::Param(_)
+            | ConstKind::Infer(_)
+            | ConstKind::Bound(..)
+            | ConstKind::Placeholder(_) => V::Result::output(),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 746b429a380..72474a60566 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -403,12 +403,6 @@ pub enum BoundTyKind {
     Param(DefId),
 }
 
-impl From<BoundVar> for BoundTy {
-    fn from(var: BoundVar) -> Self {
-        BoundTy { var, kind: BoundTyKind::Anon }
-    }
-}
-
 /// Constructors for `Ty`
 impl<'tcx> Ty<'tcx> {
     /// Avoid using this in favour of more specific `new_*` methods, where possible.
@@ -1462,7 +1456,7 @@ impl<'tcx> Ty<'tcx> {
         }
     }
 
-    /// Returns the type and mutability of `*ty`.
+    /// Returns the type of `*ty`.
     ///
     /// The parameter `explicit` indicates if this is an *explicit* dereference.
     /// Some types -- notably raw ptrs -- can only be dereferenced explicitly.
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 88583407d25..6b187c5325a 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -789,10 +789,10 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
                         },
 
                         GenericArgKind::Lifetime(r) => match r.kind() {
-                            ty::ReBound(debruijn, br) => {
+                            ty::ReBound(debruijn, b) => {
                                 // We only allow a `ty::INNERMOST` index in generic parameters.
                                 assert_eq!(debruijn, ty::INNERMOST);
-                                cvar == br.var
+                                cvar == b.var
                             }
                             _ => false,
                         },
@@ -801,7 +801,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
                             ty::ConstKind::Bound(debruijn, b) => {
                                 // We only allow a `ty::INNERMOST` index in generic parameters.
                                 assert_eq!(debruijn, ty::INNERMOST);
-                                cvar == b
+                                cvar == b.var
                             }
                             _ => false,
                         },
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index abfe8eb66dd..287639de663 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -87,7 +87,7 @@ mir_build_confused = missing patterns are not covered because `{$variable}` is i
 mir_build_const_continue_bad_const = could not determine the target branch for this `#[const_continue]`
     .label = this value is too generic
 
-mir_build_const_continue_missing_value = a `#[const_continue]` must break to a label with a value
+mir_build_const_continue_missing_label_or_value = a `#[const_continue]` must break to a label with a value
 
 mir_build_const_continue_not_const = could not determine the target branch for this `#[const_continue]`
     .help = try extracting the expression into a `const` item
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs
index 982e7aa8246..6a422223990 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs
@@ -57,7 +57,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// ```
     /// #![feature(unsized_fn_params)]
     /// # use core::fmt::Debug;
-    /// fn foo(_p: dyn Debug) { /* ... */ }
+    /// fn foo(_p: dyn Debug) {
+    ///     /* ... */
+    /// }
     ///
     /// fn bar(box_p: Box<dyn Debug>) { foo(*box_p); }
     /// ```
diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs
index 18db8c1debb..b4c8b20e50f 100644
--- a/compiler/rustc_mir_build/src/check_tail_calls.rs
+++ b/compiler/rustc_mir_build/src/check_tail_calls.rs
@@ -89,22 +89,39 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
             self.report_op(ty, args, fn_span, expr);
         }
 
-        // Closures in thir look something akin to
-        // `for<'a> extern "rust-call" fn(&'a [closure@...], ()) -> <[closure@...] as FnOnce<()>>::Output {<[closure@...] as Fn<()>>::call}`
-        // So we have to check for them in this weird way...
         if let &ty::FnDef(did, args) = ty.kind() {
+            // Closures in thir look something akin to
+            // `for<'a> extern "rust-call" fn(&'a [closure@...], ()) -> <[closure@...] as FnOnce<()>>::Output {<[closure@...] as Fn<()>>::call}`
+            // So we have to check for them in this weird way...
             let parent = self.tcx.parent(did);
             if self.tcx.fn_trait_kind_from_def_id(parent).is_some()
-                && args.first().and_then(|arg| arg.as_type()).is_some_and(Ty::is_closure)
+                && let Some(this) = args.first()
+                && let Some(this) = this.as_type()
             {
-                self.report_calling_closure(&self.thir[fun], args[1].as_type().unwrap(), expr);
+                if this.is_closure() {
+                    self.report_calling_closure(&self.thir[fun], args[1].as_type().unwrap(), expr);
+                } else {
+                    // This can happen when tail calling `Box` that wraps a function
+                    self.report_nonfn_callee(fn_span, self.thir[fun].span, this);
+                }
 
                 // Tail calling is likely to cause unrelated errors (ABI, argument mismatches),
                 // skip them, producing an error about calling a closure is enough.
                 return;
             };
+
+            if self.tcx.intrinsic(did).is_some() {
+                self.report_calling_intrinsic(expr);
+            }
         }
 
+        let (ty::FnDef(..) | ty::FnPtr(..)) = ty.kind() else {
+            self.report_nonfn_callee(fn_span, self.thir[fun].span, ty);
+
+            // `fn_sig` below panics otherwise
+            return;
+        };
+
         // Erase regions since tail calls don't care about lifetimes
         let callee_sig =
             self.tcx.normalize_erasing_late_bound_regions(self.typing_env, ty.fn_sig(self.tcx));
@@ -280,6 +297,50 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
         self.found_errors = Err(err);
     }
 
+    fn report_calling_intrinsic(&mut self, expr: &Expr<'_>) {
+        let err = self
+            .tcx
+            .dcx()
+            .struct_span_err(expr.span, "tail calling intrinsics is not allowed")
+            .emit();
+
+        self.found_errors = Err(err);
+    }
+
+    fn report_nonfn_callee(&mut self, call_sp: Span, fun_sp: Span, ty: Ty<'_>) {
+        let mut err = self
+            .tcx
+            .dcx()
+            .struct_span_err(
+                call_sp,
+                "tail calls can only be performed with function definitions or pointers",
+            )
+            .with_note(format!("callee has type `{ty}`"));
+
+        let mut ty = ty;
+        let mut refs = 0;
+        while ty.is_box() || ty.is_ref() {
+            ty = ty.builtin_deref(false).unwrap();
+            refs += 1;
+        }
+
+        if refs > 0 && ty.is_fn() {
+            let thing = if ty.is_fn_ptr() { "pointer" } else { "definition" };
+
+            let derefs =
+                std::iter::once('(').chain(std::iter::repeat_n('*', refs)).collect::<String>();
+
+            err.multipart_suggestion(
+                format!("consider dereferencing the expression to get a function {thing}"),
+                vec![(fun_sp.shrink_to_lo(), derefs), (fun_sp.shrink_to_hi(), ")".to_owned())],
+                Applicability::MachineApplicable,
+            );
+        }
+
+        let err = err.emit();
+        self.found_errors = Err(err);
+    }
+
     fn report_abi_mismatch(&mut self, sp: Span, caller_abi: ExternAbi, callee_abi: ExternAbi) {
         let err = self
             .tcx
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index f1fbd5c4a49..1a52c6c85cb 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -1254,8 +1254,8 @@ pub(crate) struct ConstContinueBadConst {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_const_continue_missing_value)]
-pub(crate) struct ConstContinueMissingValue {
+#[diag(mir_build_const_continue_missing_label_or_value)]
+pub(crate) struct ConstContinueMissingLabelOrValue {
     #[primary_span]
     pub span: Span,
 }
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index a0d3913c159..81b0e21a5f5 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -852,9 +852,9 @@ impl<'tcx> ThirBuildCx<'tcx> {
                 if find_attr!(self.tcx.hir_attrs(expr.hir_id), AttributeKind::ConstContinue(_)) {
                     match dest.target_id {
                         Ok(target_id) => {
-                            let Some(value) = value else {
+                            let (Some(value), Some(_)) = (value, dest.label) else {
                                 let span = expr.span;
-                                self.tcx.dcx().emit_fatal(ConstContinueMissingValue { span })
+                                self.tcx.dcx().emit_fatal(ConstContinueMissingLabelOrValue { span })
                             };
 
                             ExprKind::ConstContinue {
diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
index 117525eb777..5937d68f389 100644
--- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
@@ -108,6 +108,7 @@ impl<'tcx> MaybePlacesSwitchIntData<'tcx> {
 ///
 /// ```rust
 /// struct S;
+/// #[rustfmt::skip]
 /// fn foo(pred: bool) {                        // maybe-init:
 ///                                             // {}
 ///     let a = S; let mut b = S; let c; let d; // {a, b}
@@ -197,6 +198,7 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
 ///
 /// ```rust
 /// struct S;
+/// #[rustfmt::skip]
 /// fn foo(pred: bool) {                        // maybe-uninit:
 ///                                             // {a, b, c, d}
 ///     let a = S; let mut b = S; let c; let d; // {      c, d}
@@ -289,6 +291,7 @@ impl<'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
 ///
 /// ```rust
 /// struct S;
+/// #[rustfmt::skip]
 /// fn foo(pred: bool) {                        // ever-init:
 ///                                             // {          }
 ///     let a = S; let mut b = S; let c; let d; // {a, b      }
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
index b4b4d0416fb..b0e24cf2bdb 100644
--- a/compiler/rustc_mir_transform/src/coverage/mappings.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -10,7 +10,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 
 use crate::coverage::ExtractedHirInfo;
-use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
+use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
 use crate::coverage::spans::extract_refined_covspans;
 use crate::coverage::unexpand::unexpand_into_body_span;
 use crate::errors::MCDCExceedsTestVectorLimit;
@@ -82,22 +82,8 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
     let mut mcdc_degraded_branches = vec![];
     let mut mcdc_mappings = vec![];
 
-    if hir_info.is_async_fn || tcx.sess.coverage_no_mir_spans() {
-        // An async function desugars into a function that returns a future,
-        // with the user code wrapped in a closure. Any spans in the desugared
-        // outer function will be unhelpful, so just keep the signature span
-        // and ignore all of the spans in the MIR body.
-        //
-        // When debugging flag `-Zcoverage-options=no-mir-spans` is set, we need
-        // to give the same treatment to _all_ functions, because `llvm-cov`
-        // seems to ignore functions that don't have any ordinary code spans.
-        if let Some(span) = hir_info.fn_sig_span {
-            code_mappings.push(CodeMapping { span, bcb: START_BCB });
-        }
-    } else {
-        // Extract coverage spans from MIR statements/terminators as normal.
-        extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut code_mappings);
-    }
+    // Extract ordinary code mappings from MIR statement/terminator spans.
+    extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut code_mappings);
 
     branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph));
 
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index ddeae093df5..0ee42abb195 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,5 +1,6 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir;
+use rustc_middle::mir::coverage::START_BCB;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::source_map::SourceMap;
 use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span};
@@ -16,8 +17,19 @@ pub(super) fn extract_refined_covspans<'tcx>(
     mir_body: &mir::Body<'tcx>,
     hir_info: &ExtractedHirInfo,
     graph: &CoverageGraph,
-    code_mappings: &mut impl Extend<mappings::CodeMapping>,
+    code_mappings: &mut Vec<mappings::CodeMapping>,
 ) {
+    if hir_info.is_async_fn {
+        // An async function desugars into a function that returns a future,
+        // with the user code wrapped in a closure. Any spans in the desugared
+        // outer function will be unhelpful, so just keep the signature span
+        // and ignore all of the spans in the MIR body.
+        if let Some(span) = hir_info.fn_sig_span {
+            code_mappings.push(mappings::CodeMapping { span, bcb: START_BCB });
+        }
+        return;
+    }
+
     let &ExtractedHirInfo { body_span, .. } = hir_info;
 
     let raw_spans = from_mir::extract_raw_spans_from_mir(mir_body, graph);
diff --git a/compiler/rustc_mir_transform/src/ctfe_limit.rs b/compiler/rustc_mir_transform/src/ctfe_limit.rs
index fb17cca30f4..ac46336b834 100644
--- a/compiler/rustc_mir_transform/src/ctfe_limit.rs
+++ b/compiler/rustc_mir_transform/src/ctfe_limit.rs
@@ -18,7 +18,7 @@ impl<'tcx> crate::MirPass<'tcx> for CtfeLimit {
             .basic_blocks
             .iter_enumerated()
             .filter_map(|(node, node_data)| {
-                if matches!(node_data.terminator().kind, TerminatorKind::Call { .. })
+                if matches!(node_data.terminator().kind, TerminatorKind::Call { .. } | TerminatorKind::TailCall { .. })
                     // Back edges in a CFG indicate loops
                     || has_back_edge(doms, node, node_data)
                 {
diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs
index df4853c1dcb..4f3c53d761f 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drop.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs
@@ -611,6 +611,7 @@ where
     ///
     /// For example, with 3 fields, the drop ladder is
     ///
+    /// ```text
     /// .d0:
     ///     ELAB(drop location.0 [target=.d1, unwind=.c1])
     /// .d1:
@@ -621,8 +622,10 @@ where
     ///     ELAB(drop location.1 [target=.c2])
     /// .c2:
     ///     ELAB(drop location.2 [target=`self.unwind`])
+    /// ```
     ///
     /// For possible-async drops in coroutines we also need dropline ladder
+    /// ```text
     /// .d0 (mainline):
     ///     ELAB(drop location.0 [target=.d1, unwind=.c1, drop=.e1])
     /// .d1 (mainline):
@@ -637,6 +640,7 @@ where
     ///     ELAB(drop location.1 [target=.e2, unwind=.c2])
     /// .e2 (dropline):
     ///     ELAB(drop location.2 [target=`self.drop`, unwind=`self.unwind`])
+    /// ```
     ///
     /// NOTE: this does not clear the master drop flag, so you need
     /// to point succ/unwind on a `drop_ladder_bottom`.
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index b2d40146348..231fb3e2964 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -21,7 +21,7 @@ use crate::delegate::SolverDelegate;
 use crate::solve::inspect::ProbeKind;
 use crate::solve::{
     BuiltinImplSource, CandidateSource, CanonicalResponse, Certainty, EvalCtxt, Goal, GoalSource,
-    MaybeCause, NoSolution, ParamEnvSource, QueryResult,
+    MaybeCause, NoSolution, ParamEnvSource, QueryResult, has_no_inference_or_external_constraints,
 };
 
 enum AliasBoundKind {
@@ -50,7 +50,7 @@ where
 
     fn trait_ref(self, cx: I) -> ty::TraitRef<I>;
 
-    fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self;
+    fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self;
 
     fn trait_def_id(self, cx: I) -> I::DefId;
 
@@ -376,8 +376,8 @@ where
             return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
         }
 
-        let goal: Goal<I, G> =
-            goal.with(self.cx(), goal.predicate.with_self_ty(self.cx(), normalized_self_ty));
+        let goal: Goal<I, G> = goal
+            .with(self.cx(), goal.predicate.with_replaced_self_ty(self.cx(), normalized_self_ty));
         // Vars that show up in the rest of the goal substs may have been constrained by
         // normalizing the self type as well, since type variables are not uniquified.
         let goal = self.resolve_vars_if_possible(goal);
@@ -395,9 +395,30 @@ where
 
         match assemble_from {
             AssembleCandidatesFrom::All => {
-                self.assemble_impl_candidates(goal, &mut candidates);
                 self.assemble_builtin_impl_candidates(goal, &mut candidates);
-                self.assemble_object_bound_candidates(goal, &mut candidates);
+                // For performance we only assemble impls if there are no candidates
+                // which would shadow them. This is necessary to avoid hangs in rayon,
+                // see trait-system-refactor-initiative#109 for more details.
+                //
+                // We always assemble builtin impls as trivial builtin impls have a higher
+                // priority than where-clauses.
+                //
+                // We only do this if any such candidate applies without any constraints
+                // as we may want to weaken inference guidance in the future and don't want
+                // to worry about causing major performance regressions when doing so.
+                // See trait-system-refactor-initiative#226 for some ideas here.
+                if TypingMode::Coherence == self.typing_mode()
+                    || !candidates.iter().any(|c| {
+                        matches!(
+                            c.source,
+                            CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)
+                                | CandidateSource::AliasBound
+                        ) && has_no_inference_or_external_constraints(c.result)
+                    })
+                {
+                    self.assemble_impl_candidates(goal, &mut candidates);
+                    self.assemble_object_bound_candidates(goal, &mut candidates);
+                }
             }
             AssembleCandidatesFrom::EnvAndBounds => {}
         }
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 c0bebdf6fb6..faa86734d08 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
@@ -75,9 +75,16 @@ where
             Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()]))
         }
 
-        ty::Coroutine(_, args) => {
+        ty::Coroutine(def_id, args) => {
             let coroutine_args = args.as_coroutine();
-            Ok(ty::Binder::dummy(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()]))
+            Ok(ty::Binder::dummy(vec![
+                coroutine_args.tupled_upvars_ty(),
+                Ty::new_coroutine_witness(
+                    ecx.cx(),
+                    def_id,
+                    ecx.cx().mk_args(coroutine_args.parent_args().as_slice()),
+                ),
+            ]))
         }
 
         ty::CoroutineWitness(def_id, args) => Ok(ecx
@@ -245,7 +252,14 @@ where
             Movability::Movable => {
                 if ecx.cx().features().coroutine_clone() {
                     let coroutine = args.as_coroutine();
-                    Ok(ty::Binder::dummy(vec![coroutine.tupled_upvars_ty(), coroutine.witness()]))
+                    Ok(ty::Binder::dummy(vec![
+                        coroutine.tupled_upvars_ty(),
+                        Ty::new_coroutine_witness(
+                            ecx.cx(),
+                            def_id,
+                            ecx.cx().mk_args(coroutine.parent_args().as_slice()),
+                        ),
+                    ]))
                 } else {
                     Err(NoSolution)
                 }
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 61f3f9367f0..9a22bf58c03 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -29,8 +29,8 @@ where
         self.trait_ref
     }
 
-    fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
-        self.with_self_ty(cx, self_ty)
+    fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
+        self.with_replaced_self_ty(cx, self_ty)
     }
 
     fn trait_def_id(self, _: I) -> I::DefId {
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 1e0a90eb2ee..93434dce79f 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
@@ -99,8 +99,8 @@ where
         self.alias.trait_ref(cx)
     }
 
-    fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
-        self.with_self_ty(cx, self_ty)
+    fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
+        self.with_replaced_self_ty(cx, self_ty)
     }
 
     fn trait_def_id(self, cx: I) -> I::DefId {
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 650b85d99d2..f760c2c07ff 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -33,8 +33,8 @@ where
         self.trait_ref
     }
 
-    fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
-        self.with_self_ty(cx, self_ty)
+    fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
+        self.with_replaced_self_ty(cx, self_ty)
     }
 
     fn trait_def_id(self, _: I) -> I::DefId {
@@ -229,7 +229,7 @@ where
         }
 
         // We need to make sure to stall any coroutines we are inferring to avoid query cycles.
-        if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
+        if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
             return cand;
         }
 
@@ -294,7 +294,7 @@ where
         }
 
         // We need to make sure to stall any coroutines we are inferring to avoid query cycles.
-        if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
+        if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
             return cand;
         }
 
@@ -1263,7 +1263,9 @@ where
             let goals =
                 ecx.enter_forall(constituent_tys(ecx, goal.predicate.self_ty())?, |ecx, tys| {
                     tys.into_iter()
-                        .map(|ty| goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty)))
+                        .map(|ty| {
+                            goal.with(ecx.cx(), goal.predicate.with_replaced_self_ty(ecx.cx(), ty))
+                        })
                         .collect::<Vec<_>>()
                 });
             ecx.add_goals(GoalSource::ImplWhereBound, goals);
@@ -1432,11 +1434,8 @@ where
         self.merge_trait_candidates(candidates)
     }
 
-    fn try_stall_coroutine_witness(
-        &mut self,
-        self_ty: I::Ty,
-    ) -> Option<Result<Candidate<I>, NoSolution>> {
-        if let ty::CoroutineWitness(def_id, _) = self_ty.kind() {
+    fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option<Result<Candidate<I>, NoSolution>> {
+        if let ty::Coroutine(def_id, _) = self_ty.kind() {
             match self.typing_mode() {
                 TypingMode::Analysis {
                     defining_opaque_types_and_generators: stalled_generators,
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index ede74bdc0df..2663d5fe99c 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -289,8 +289,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     | AttributeKind::MacroTransparency(_)
                     | AttributeKind::Pointee(..)
                     | AttributeKind::Dummy
-                    | AttributeKind::RustcBuiltinMacro { .. }
-                    | AttributeKind::OmitGdbPrettyPrinterSection,
+                    | AttributeKind::RustcBuiltinMacro { .. },
                 ) => { /* do nothing  */ }
                 Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
                     self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index a90d1af87ca..fa9d0c7b1b7 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -5,7 +5,6 @@
 
 use std::mem;
 
-use hir::ItemKind;
 use hir::def_id::{LocalDefIdMap, LocalDefIdSet};
 use rustc_abi::FieldIdx;
 use rustc_data_structures::fx::FxIndexSet;
@@ -14,7 +13,7 @@ use rustc_errors::MultiSpan;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{self as hir, ImplItem, ImplItemKind, Node, PatKind, QPath, TyKind};
+use rustc_hir::{self as hir, Node, PatKind, QPath};
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::privacy::Level;
 use rustc_middle::query::Providers;
@@ -28,37 +27,43 @@ use crate::errors::{
     ChangeFields, IgnoredDerivedImpls, MultipleDeadCodes, ParentInfo, UselessAssignment,
 };
 
-// Any local node that may call something in its body block should be
-// explored. For example, if it's a live Node::Item that is a
-// function, then we should explore its block to check for codes that
-// may need to be marked as live.
+/// Any local definition that may call something in its body block should be explored. For example,
+/// if it's a live function, then we should explore its block to check for codes that may need to
+/// be marked as live.
 fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
-    matches!(
-        tcx.hir_node_by_def_id(def_id),
-        Node::Item(..)
-            | Node::ImplItem(..)
-            | Node::ForeignItem(..)
-            | Node::TraitItem(..)
-            | Node::Variant(..)
-            | Node::AnonConst(..)
-            | Node::OpaqueTy(..)
-    )
-}
-
-/// Returns the local def id of the ADT if the given ty refers to a local one.
-fn local_adt_def_of_ty<'tcx>(ty: &hir::Ty<'tcx>) -> Option<LocalDefId> {
-    match ty.kind {
-        TyKind::Path(QPath::Resolved(_, path)) => {
-            if let Res::Def(def_kind, def_id) = path.res
-                && let Some(local_def_id) = def_id.as_local()
-                && matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
-            {
-                Some(local_def_id)
-            } else {
-                None
-            }
-        }
-        _ => None,
+    match tcx.def_kind(def_id) {
+        DefKind::Mod
+        | DefKind::Struct
+        | DefKind::Union
+        | DefKind::Enum
+        | DefKind::Variant
+        | DefKind::Trait
+        | DefKind::TyAlias
+        | DefKind::ForeignTy
+        | DefKind::TraitAlias
+        | DefKind::AssocTy
+        | DefKind::Fn
+        | DefKind::Const
+        | DefKind::Static { .. }
+        | DefKind::AssocFn
+        | DefKind::AssocConst
+        | DefKind::Macro(_)
+        | DefKind::GlobalAsm
+        | DefKind::Impl { .. }
+        | DefKind::OpaqueTy
+        | DefKind::AnonConst
+        | DefKind::InlineConst
+        | DefKind::ExternCrate
+        | DefKind::Use
+        | DefKind::Ctor(..)
+        | DefKind::ForeignMod => true,
+
+        DefKind::TyParam
+        | DefKind::ConstParam
+        | DefKind::Field
+        | DefKind::LifetimeParam
+        | DefKind::Closure
+        | DefKind::SyntheticCoroutineBody => false,
     }
 }
 
@@ -74,17 +79,16 @@ struct MarkSymbolVisitor<'tcx> {
     worklist: Vec<(LocalDefId, ComesFromAllowExpect)>,
     tcx: TyCtxt<'tcx>,
     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
+    scanned: UnordSet<(LocalDefId, ComesFromAllowExpect)>,
     live_symbols: LocalDefIdSet,
     repr_unconditionally_treats_fields_as_live: bool,
     repr_has_repr_simd: bool,
     in_pat: bool,
     ignore_variant_stack: Vec<DefId>,
-    // maps from tuple struct constructors to tuple struct items
-    struct_constructors: LocalDefIdMap<LocalDefId>,
     // maps from ADTs to ignored derived traits (e.g. Debug and Clone)
     // and the span of their respective impl (i.e., part of the derive
     // macro)
-    ignored_derived_traits: LocalDefIdMap<FxIndexSet<(DefId, DefId)>>,
+    ignored_derived_traits: LocalDefIdMap<FxIndexSet<DefId>>,
 }
 
 impl<'tcx> MarkSymbolVisitor<'tcx> {
@@ -99,7 +103,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
 
     fn check_def_id(&mut self, def_id: DefId) {
         if let Some(def_id) = def_id.as_local() {
-            if should_explore(self.tcx, def_id) || self.struct_constructors.contains_key(&def_id) {
+            if should_explore(self.tcx, def_id) {
                 self.worklist.push((def_id, ComesFromAllowExpect::No));
             }
             self.live_symbols.insert(def_id);
@@ -318,13 +322,12 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     }
 
     fn mark_live_symbols(&mut self) {
-        let mut scanned = UnordSet::default();
         while let Some(work) = self.worklist.pop() {
-            if !scanned.insert(work) {
+            if !self.scanned.insert(work) {
                 continue;
             }
 
-            let (id, comes_from_allow_expect) = work;
+            let (mut id, comes_from_allow_expect) = work;
 
             // Avoid accessing the HIR for the synthesized associated type generated for RPITITs.
             if self.tcx.is_impl_trait_in_trait(id.to_def_id()) {
@@ -332,9 +335,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 continue;
             }
 
-            // in the case of tuple struct constructors we want to check the item, not the generated
-            // tuple struct constructor function
-            let id = self.struct_constructors.get(&id).copied().unwrap_or(id);
+            // in the case of tuple struct constructors we want to check the item,
+            // not the generated tuple struct constructor function
+            if let DefKind::Ctor(..) = self.tcx.def_kind(id) {
+                id = self.tcx.local_parent(id);
+            }
 
             // When using `#[allow]` or `#[expect]` of `dead_code`, we do a QOL improvement
             // by declaring fn calls, statics, ... within said items as live, as well as
@@ -380,10 +385,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
                     && let Some(adt_def_id) = adt_def.did().as_local()
                 {
-                    self.ignored_derived_traits
-                        .entry(adt_def_id)
-                        .or_default()
-                        .insert((trait_of, impl_of));
+                    self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_of);
                 }
                 return true;
             }
@@ -478,24 +480,24 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     /// `local_def_id` points to an impl or an impl item,
     /// both impl and impl item that may be passed to this function are of a trait,
     /// and added into the unsolved_items during `create_and_seed_worklist`
-    fn check_impl_or_impl_item_live(
-        &mut self,
-        impl_id: hir::ItemId,
-        local_def_id: LocalDefId,
-    ) -> bool {
-        let trait_def_id = match self.tcx.def_kind(local_def_id) {
+    fn check_impl_or_impl_item_live(&mut self, local_def_id: LocalDefId) -> bool {
+        let (impl_block_id, trait_def_id) = match self.tcx.def_kind(local_def_id) {
             // assoc impl items of traits are live if the corresponding trait items are live
-            DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => self
-                .tcx
-                .associated_item(local_def_id)
-                .trait_item_def_id
-                .and_then(|def_id| def_id.as_local()),
+            DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => (
+                self.tcx.local_parent(local_def_id),
+                self.tcx
+                    .associated_item(local_def_id)
+                    .trait_item_def_id
+                    .and_then(|def_id| def_id.as_local()),
+            ),
             // impl items are live if the corresponding traits are live
-            DefKind::Impl { of_trait: true } => self
-                .tcx
-                .impl_trait_ref(impl_id.owner_id.def_id)
-                .and_then(|trait_ref| trait_ref.skip_binder().def_id.as_local()),
-            _ => None,
+            DefKind::Impl { of_trait: true } => (
+                local_def_id,
+                self.tcx
+                    .impl_trait_ref(local_def_id)
+                    .and_then(|trait_ref| trait_ref.skip_binder().def_id.as_local()),
+            ),
+            _ => bug!(),
         };
 
         if let Some(trait_def_id) = trait_def_id
@@ -505,9 +507,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         }
 
         // The impl or impl item is used if the corresponding trait or trait item is used and the ty is used.
-        if let Some(local_def_id) =
-            local_adt_def_of_ty(self.tcx.hir_item(impl_id).expect_impl().self_ty)
-            && !self.live_symbols.contains(&local_def_id)
+        if let ty::Adt(adt, _) = self.tcx.type_of(impl_block_id).instantiate_identity().kind()
+            && let Some(adt_def_id) = adt.did().as_local()
+            && !self.live_symbols.contains(&adt_def_id)
         {
             return false;
         }
@@ -714,139 +716,86 @@ fn has_allow_dead_code_or_lang_attr(
     }
 }
 
-// These check_* functions seeds items that
-//   1) We want to explicitly consider as live:
-//     * Item annotated with #[allow(dead_code)]
-//         - This is done so that if we want to suppress warnings for a
-//           group of dead functions, we only have to annotate the "root".
-//           For example, if both `f` and `g` are dead and `f` calls `g`,
-//           then annotating `f` with `#[allow(dead_code)]` will suppress
-//           warning for both `f` and `g`.
-//     * Item annotated with #[lang=".."]
-//         - This is because lang items are always callable from elsewhere.
-//   or
-//   2) We are not sure to be live or not
-//     * Implementations of traits and trait methods
-fn check_item<'tcx>(
+/// Examine the given definition and record it in the worklist if it should be considered live.
+///
+/// We want to explicitly consider as live:
+/// * Item annotated with #[allow(dead_code)]
+///       This is done so that if we want to suppress warnings for a
+///       group of dead functions, we only have to annotate the "root".
+///       For example, if both `f` and `g` are dead and `f` calls `g`,
+///       then annotating `f` with `#[allow(dead_code)]` will suppress
+///       warning for both `f` and `g`.
+///
+/// * Item annotated with #[lang=".."]
+///       Lang items are always callable from elsewhere.
+///
+/// For trait methods and implementations of traits, we are not certain that the definitions are
+/// live at this stage. We record them in `unsolved_items` for later examination.
+fn maybe_record_as_seed<'tcx>(
     tcx: TyCtxt<'tcx>,
+    owner_id: hir::OwnerId,
     worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>,
-    struct_constructors: &mut LocalDefIdMap<LocalDefId>,
-    unsolved_items: &mut Vec<(hir::ItemId, LocalDefId)>,
-    id: hir::ItemId,
+    unsolved_items: &mut Vec<LocalDefId>,
 ) {
-    let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id);
+    let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, owner_id.def_id);
     if let Some(comes_from_allow) = allow_dead_code {
-        worklist.push((id.owner_id.def_id, comes_from_allow));
+        worklist.push((owner_id.def_id, comes_from_allow));
     }
 
-    match tcx.def_kind(id.owner_id) {
+    match tcx.def_kind(owner_id) {
         DefKind::Enum => {
-            let item = tcx.hir_item(id);
-            if let hir::ItemKind::Enum(_, _, ref enum_def) = item.kind {
-                if let Some(comes_from_allow) = allow_dead_code {
-                    worklist.extend(
-                        enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)),
-                    );
-                }
-
-                for variant in enum_def.variants {
-                    if let Some(ctor_def_id) = variant.data.ctor_def_id() {
-                        struct_constructors.insert(ctor_def_id, variant.def_id);
-                    }
-                }
+            if let Some(comes_from_allow) = allow_dead_code {
+                let adt = tcx.adt_def(owner_id);
+                worklist.extend(
+                    adt.variants()
+                        .iter()
+                        .map(|variant| (variant.def_id.expect_local(), comes_from_allow)),
+                );
             }
         }
-        DefKind::Impl { of_trait } => {
-            if let Some(comes_from_allow) =
-                has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id)
-            {
-                worklist.push((id.owner_id.def_id, comes_from_allow));
-            } else if of_trait {
-                unsolved_items.push((id, id.owner_id.def_id));
-            }
-
-            for def_id in tcx.associated_item_def_ids(id.owner_id) {
-                let local_def_id = def_id.expect_local();
-
-                if let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, local_def_id)
-                {
-                    worklist.push((local_def_id, comes_from_allow));
-                } else if of_trait {
-                    // We only care about associated items of traits,
-                    // because they cannot be visited directly,
-                    // so we later mark them as live if their corresponding traits
-                    // or trait items and self types are both live,
-                    // but inherent associated items can be visited and marked directly.
-                    unsolved_items.push((id, local_def_id));
+        DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy => {
+            if allow_dead_code.is_none() {
+                let parent = tcx.local_parent(owner_id.def_id);
+                match tcx.def_kind(parent) {
+                    DefKind::Impl { of_trait: false } | DefKind::Trait => {}
+                    DefKind::Impl { of_trait: true } => {
+                        // We only care about associated items of traits,
+                        // because they cannot be visited directly,
+                        // so we later mark them as live if their corresponding traits
+                        // or trait items and self types are both live,
+                        // but inherent associated items can be visited and marked directly.
+                        unsolved_items.push(owner_id.def_id);
+                    }
+                    _ => bug!(),
                 }
             }
         }
-        DefKind::Struct => {
-            let item = tcx.hir_item(id);
-            if let hir::ItemKind::Struct(_, _, ref variant_data) = item.kind
-                && let Some(ctor_def_id) = variant_data.ctor_def_id()
-            {
-                struct_constructors.insert(ctor_def_id, item.owner_id.def_id);
+        DefKind::Impl { of_trait: true } => {
+            if allow_dead_code.is_none() {
+                unsolved_items.push(owner_id.def_id);
             }
         }
         DefKind::GlobalAsm => {
             // global_asm! is always live.
-            worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No));
+            worklist.push((owner_id.def_id, ComesFromAllowExpect::No));
         }
         DefKind::Const => {
-            let item = tcx.hir_item(id);
-            if let hir::ItemKind::Const(ident, ..) = item.kind
-                && ident.name == kw::Underscore
-            {
+            if tcx.item_name(owner_id.def_id) == kw::Underscore {
                 // `const _` is always live, as that syntax only exists for the side effects
                 // of type checking and evaluating the constant expression, and marking them
                 // as dead code would defeat that purpose.
-                worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No));
+                worklist.push((owner_id.def_id, ComesFromAllowExpect::No));
             }
         }
         _ => {}
     }
 }
 
-fn check_trait_item(
-    tcx: TyCtxt<'_>,
-    worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>,
-    id: hir::TraitItemId,
-) {
-    use hir::TraitItemKind::{Const, Fn, Type};
-
-    let trait_item = tcx.hir_trait_item(id);
-    if matches!(trait_item.kind, Const(_, Some(_)) | Type(_, Some(_)) | Fn(..))
-        && let Some(comes_from_allow) =
-            has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id)
-    {
-        worklist.push((trait_item.owner_id.def_id, comes_from_allow));
-    }
-}
-
-fn check_foreign_item(
-    tcx: TyCtxt<'_>,
-    worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>,
-    id: hir::ForeignItemId,
-) {
-    if matches!(tcx.def_kind(id.owner_id), DefKind::Static { .. } | DefKind::Fn)
-        && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id)
-    {
-        worklist.push((id.owner_id.def_id, comes_from_allow));
-    }
-}
-
 fn create_and_seed_worklist(
     tcx: TyCtxt<'_>,
-) -> (
-    Vec<(LocalDefId, ComesFromAllowExpect)>,
-    LocalDefIdMap<LocalDefId>,
-    Vec<(hir::ItemId, LocalDefId)>,
-) {
+) -> (Vec<(LocalDefId, ComesFromAllowExpect)>, Vec<LocalDefId>) {
     let effective_visibilities = &tcx.effective_visibilities(());
-    // see `MarkSymbolVisitor::struct_constructors`
     let mut unsolved_impl_item = Vec::new();
-    let mut struct_constructors = Default::default();
     let mut worklist = effective_visibilities
         .iter()
         .filter_map(|(&id, effective_vis)| {
@@ -863,54 +812,49 @@ fn create_and_seed_worklist(
         .collect::<Vec<_>>();
 
     let crate_items = tcx.hir_crate_items(());
-    for id in crate_items.free_items() {
-        check_item(tcx, &mut worklist, &mut struct_constructors, &mut unsolved_impl_item, id);
-    }
-
-    for id in crate_items.trait_items() {
-        check_trait_item(tcx, &mut worklist, id);
-    }
-
-    for id in crate_items.foreign_items() {
-        check_foreign_item(tcx, &mut worklist, id);
+    for id in crate_items.owners() {
+        maybe_record_as_seed(tcx, id, &mut worklist, &mut unsolved_impl_item);
     }
 
-    (worklist, struct_constructors, unsolved_impl_item)
+    (worklist, unsolved_impl_item)
 }
 
 fn live_symbols_and_ignored_derived_traits(
     tcx: TyCtxt<'_>,
     (): (),
-) -> (LocalDefIdSet, LocalDefIdMap<FxIndexSet<(DefId, DefId)>>) {
-    let (worklist, struct_constructors, mut unsolved_items) = create_and_seed_worklist(tcx);
+) -> (LocalDefIdSet, LocalDefIdMap<FxIndexSet<DefId>>) {
+    let (worklist, mut unsolved_items) = create_and_seed_worklist(tcx);
     let mut symbol_visitor = MarkSymbolVisitor {
         worklist,
         tcx,
         maybe_typeck_results: None,
+        scanned: Default::default(),
         live_symbols: Default::default(),
         repr_unconditionally_treats_fields_as_live: false,
         repr_has_repr_simd: false,
         in_pat: false,
         ignore_variant_stack: vec![],
-        struct_constructors,
         ignored_derived_traits: Default::default(),
     };
     symbol_visitor.mark_live_symbols();
-    let mut items_to_check;
-    (items_to_check, unsolved_items) =
-        unsolved_items.into_iter().partition(|&(impl_id, local_def_id)| {
-            symbol_visitor.check_impl_or_impl_item_live(impl_id, local_def_id)
-        });
+
+    // We have marked the primary seeds as live. We now need to process unsolved items from traits
+    // and trait impls: add them to the work list if the trait or the implemented type is live.
+    let mut items_to_check: Vec<_> = unsolved_items
+        .extract_if(.., |&mut local_def_id| {
+            symbol_visitor.check_impl_or_impl_item_live(local_def_id)
+        })
+        .collect();
 
     while !items_to_check.is_empty() {
-        symbol_visitor.worklist =
-            items_to_check.into_iter().map(|(_, id)| (id, ComesFromAllowExpect::No)).collect();
+        symbol_visitor
+            .worklist
+            .extend(items_to_check.drain(..).map(|id| (id, ComesFromAllowExpect::No)));
         symbol_visitor.mark_live_symbols();
 
-        (items_to_check, unsolved_items) =
-            unsolved_items.into_iter().partition(|&(impl_id, local_def_id)| {
-                symbol_visitor.check_impl_or_impl_item_live(impl_id, local_def_id)
-            });
+        items_to_check.extend(unsolved_items.extract_if(.., |&mut local_def_id| {
+            symbol_visitor.check_impl_or_impl_item_live(local_def_id)
+        }));
     }
 
     (symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits)
@@ -925,7 +869,7 @@ struct DeadItem {
 struct DeadVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
     live_symbols: &'tcx LocalDefIdSet,
-    ignored_derived_traits: &'tcx LocalDefIdMap<FxIndexSet<(DefId, DefId)>>,
+    ignored_derived_traits: &'tcx LocalDefIdMap<FxIndexSet<DefId>>,
 }
 
 enum ShouldWarnAboutField {
@@ -984,25 +928,7 @@ impl<'tcx> DeadVisitor<'tcx> {
         parent_item: Option<LocalDefId>,
         report_on: ReportOn,
     ) {
-        fn get_parent_if_enum_variant<'tcx>(
-            tcx: TyCtxt<'tcx>,
-            may_variant: LocalDefId,
-        ) -> LocalDefId {
-            if let Node::Variant(_) = tcx.hir_node_by_def_id(may_variant)
-                && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id())
-                && let Some(enum_local_id) = enum_did.as_local()
-                && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id)
-                && let ItemKind::Enum(..) = item.kind
-            {
-                enum_local_id
-            } else {
-                may_variant
-            }
-        }
-
-        let Some(&first_item) = dead_codes.first() else {
-            return;
-        };
+        let Some(&first_item) = dead_codes.first() else { return };
         let tcx = self.tcx;
 
         let first_lint_level = first_item.level;
@@ -1011,81 +937,54 @@ impl<'tcx> DeadVisitor<'tcx> {
         let names: Vec<_> = dead_codes.iter().map(|item| item.name).collect();
         let spans: Vec<_> = dead_codes
             .iter()
-            .map(|item| match tcx.def_ident_span(item.def_id) {
-                Some(s) => s.with_ctxt(tcx.def_span(item.def_id).ctxt()),
-                None => tcx.def_span(item.def_id),
+            .map(|item| {
+                let span = tcx.def_span(item.def_id);
+                let ident_span = tcx.def_ident_span(item.def_id);
+                // FIXME(cjgillot) this SyntaxContext manipulation does not make any sense.
+                ident_span.map(|s| s.with_ctxt(span.ctxt())).unwrap_or(span)
             })
             .collect();
 
-        let descr = tcx.def_descr(first_item.def_id.to_def_id());
+        let mut descr = tcx.def_descr(first_item.def_id.to_def_id());
         // `impl` blocks are "batched" and (unlike other batching) might
         // contain different kinds of associated items.
-        let descr = if dead_codes.iter().any(|item| tcx.def_descr(item.def_id.to_def_id()) != descr)
-        {
-            "associated item"
-        } else {
-            descr
-        };
+        if dead_codes.iter().any(|item| tcx.def_descr(item.def_id.to_def_id()) != descr) {
+            descr = "associated item"
+        }
+
         let num = dead_codes.len();
         let multiple = num > 6;
         let name_list = names.into();
 
-        let parent_info = if let Some(parent_item) = parent_item {
+        let parent_info = parent_item.map(|parent_item| {
             let parent_descr = tcx.def_descr(parent_item.to_def_id());
             let span = if let DefKind::Impl { .. } = tcx.def_kind(parent_item) {
                 tcx.def_span(parent_item)
             } else {
                 tcx.def_ident_span(parent_item).unwrap()
             };
-            Some(ParentInfo { num, descr, parent_descr, span })
-        } else {
-            None
-        };
+            ParentInfo { num, descr, parent_descr, span }
+        });
 
-        let encl_def_id = parent_item.unwrap_or(first_item.def_id);
-        // If parent of encl_def_id is an enum, use the parent ID instead.
-        let encl_def_id = get_parent_if_enum_variant(tcx, encl_def_id);
+        let mut encl_def_id = parent_item.unwrap_or(first_item.def_id);
+        // `ignored_derived_traits` is computed for the enum, not for the variants.
+        if let DefKind::Variant = tcx.def_kind(encl_def_id) {
+            encl_def_id = tcx.local_parent(encl_def_id);
+        }
 
         let ignored_derived_impls =
-            if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) {
+            self.ignored_derived_traits.get(&encl_def_id).map(|ign_traits| {
                 let trait_list = ign_traits
                     .iter()
-                    .map(|(trait_id, _)| self.tcx.item_name(*trait_id))
+                    .map(|trait_id| self.tcx.item_name(*trait_id))
                     .collect::<Vec<_>>();
                 let trait_list_len = trait_list.len();
-                Some(IgnoredDerivedImpls {
+                IgnoredDerivedImpls {
                     name: self.tcx.item_name(encl_def_id.to_def_id()),
                     trait_list: trait_list.into(),
                     trait_list_len,
-                })
-            } else {
-                None
-            };
-
-        let enum_variants_with_same_name = dead_codes
-            .iter()
-            .filter_map(|dead_item| {
-                if let Node::ImplItem(ImplItem {
-                    kind: ImplItemKind::Fn(..) | ImplItemKind::Const(..),
-                    ..
-                }) = tcx.hir_node_by_def_id(dead_item.def_id)
-                    && let Some(impl_did) = tcx.opt_parent(dead_item.def_id.to_def_id())
-                    && let DefKind::Impl { of_trait: false } = tcx.def_kind(impl_did)
-                    && let ty::Adt(maybe_enum, _) = tcx.type_of(impl_did).skip_binder().kind()
-                    && maybe_enum.is_enum()
-                    && let Some(variant) =
-                        maybe_enum.variants().iter().find(|i| i.name == dead_item.name)
-                {
-                    Some(crate::errors::EnumVariantSameName {
-                        dead_descr: tcx.def_descr(dead_item.def_id.to_def_id()),
-                        dead_name: dead_item.name,
-                        variant_span: tcx.def_span(variant.def_id),
-                    })
-                } else {
-                    None
                 }
-            })
-            .collect();
+            });
 
         let diag = match report_on {
             ReportOn::TupleField => {
@@ -1132,16 +1031,42 @@ impl<'tcx> DeadVisitor<'tcx> {
                     ignored_derived_impls,
                 }
             }
-            ReportOn::NamedField => MultipleDeadCodes::DeadCodes {
-                multiple,
-                num,
-                descr,
-                participle,
-                name_list,
-                parent_info,
-                ignored_derived_impls,
-                enum_variants_with_same_name,
-            },
+            ReportOn::NamedField => {
+                let enum_variants_with_same_name = dead_codes
+                    .iter()
+                    .filter_map(|dead_item| {
+                        if let DefKind::AssocFn | DefKind::AssocConst =
+                            tcx.def_kind(dead_item.def_id)
+                            && let impl_did = tcx.local_parent(dead_item.def_id)
+                            && let DefKind::Impl { of_trait: false } = tcx.def_kind(impl_did)
+                            && let ty::Adt(maybe_enum, _) =
+                                tcx.type_of(impl_did).instantiate_identity().kind()
+                            && maybe_enum.is_enum()
+                            && let Some(variant) =
+                                maybe_enum.variants().iter().find(|i| i.name == dead_item.name)
+                        {
+                            Some(crate::errors::EnumVariantSameName {
+                                dead_descr: tcx.def_descr(dead_item.def_id.to_def_id()),
+                                dead_name: dead_item.name,
+                                variant_span: tcx.def_span(variant.def_id),
+                            })
+                        } else {
+                            None
+                        }
+                    })
+                    .collect();
+
+                MultipleDeadCodes::DeadCodes {
+                    multiple,
+                    num,
+                    descr,
+                    participle,
+                    name_list,
+                    parent_info,
+                    ignored_derived_impls,
+                    enum_variants_with_same_name,
+                }
+            }
         };
 
         let hir_id = tcx.local_def_id_to_hir_id(first_item.def_id);
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index af7ecf0830c..2ad0b5ff60e 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -8,6 +8,7 @@
 #![allow(internal_features)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
+#![feature(if_let_guard)]
 #![feature(map_try_insert)]
 #![feature(rustdoc_internals)]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index e12e74c0f1a..5d02c02b23c 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -26,9 +26,9 @@ use rustc_errors::{MultiSpan, listify};
 use rustc_hir as hir;
 use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, InferKind, Visitor};
-use rustc_hir::{AmbigArg, ForeignItemId, ItemId, PatKind, find_attr};
+use rustc_hir::{AmbigArg, ForeignItemId, ItemId, OwnerId, PatKind, find_attr};
 use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
@@ -599,7 +599,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
             DefKind::Struct | DefKind::Union => {
                 // While structs and unions have type privacy, their fields do not.
                 let struct_def = self.tcx.adt_def(def_id);
-                for field in struct_def.non_enum_variant().fields.iter() {
+                for field in &struct_def.non_enum_variant().fields {
                     let def_id = field.did.expect_local();
                     let field_vis = self.tcx.local_visibility(def_id);
                     if field_vis.is_accessible_from(module, self.tcx) {
@@ -637,45 +637,49 @@ impl<'tcx> EmbargoVisitor<'tcx> {
     }
 }
 
-impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
+impl<'tcx> EmbargoVisitor<'tcx> {
+    fn check_def_id(&mut self, owner_id: OwnerId) {
         // Update levels of nested things and mark all items
         // in interfaces of reachable items as reachable.
-        let item_ev = self.get(item.owner_id.def_id);
-        match item.kind {
+        let item_ev = self.get(owner_id.def_id);
+        match self.tcx.def_kind(owner_id) {
             // The interface is empty, and no nested items.
-            hir::ItemKind::Use(..)
-            | hir::ItemKind::ExternCrate(..)
-            | hir::ItemKind::GlobalAsm { .. } => {}
-            // The interface is empty, and all nested items are processed by `visit_item`.
-            hir::ItemKind::Mod(..) => {}
-            hir::ItemKind::Macro(_, macro_def, _) => {
+            DefKind::Use | DefKind::ExternCrate | DefKind::GlobalAsm => {}
+            // The interface is empty, and all nested items are processed by `check_def_id`.
+            DefKind::Mod => {}
+            DefKind::Macro { .. } => {
                 if let Some(item_ev) = item_ev {
-                    self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev);
+                    let (_, macro_def, _) =
+                        self.tcx.hir_expect_item(owner_id.def_id).expect_macro();
+                    self.update_reachability_from_macro(owner_id.def_id, macro_def, item_ev);
                 }
             }
-            hir::ItemKind::Const(..)
-            | hir::ItemKind::Static(..)
-            | hir::ItemKind::Fn { .. }
-            | hir::ItemKind::TyAlias(..) => {
+            DefKind::ForeignTy
+            | DefKind::Const
+            | DefKind::Static { .. }
+            | DefKind::Fn
+            | DefKind::TyAlias => {
                 if let Some(item_ev) = item_ev {
-                    self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty();
+                    self.reach(owner_id.def_id, item_ev).generics().predicates().ty();
                 }
             }
-            hir::ItemKind::Trait(.., trait_item_refs) => {
+            DefKind::Trait => {
                 if let Some(item_ev) = item_ev {
-                    self.reach(item.owner_id.def_id, item_ev).generics().predicates();
+                    self.reach(owner_id.def_id, item_ev).generics().predicates();
 
-                    for trait_item_ref in trait_item_refs {
-                        self.update(trait_item_ref.owner_id.def_id, item_ev, Level::Reachable);
+                    for assoc_item in self.tcx.associated_items(owner_id).in_definition_order() {
+                        if assoc_item.is_impl_trait_in_trait() {
+                            continue;
+                        }
+
+                        let def_id = assoc_item.def_id.expect_local();
+                        self.update(def_id, item_ev, Level::Reachable);
 
                         let tcx = self.tcx;
-                        let mut reach = self.reach(trait_item_ref.owner_id.def_id, item_ev);
+                        let mut reach = self.reach(def_id, item_ev);
                         reach.generics().predicates();
 
-                        if let DefKind::AssocTy = tcx.def_kind(trait_item_ref.owner_id)
-                            && !tcx.defaultness(trait_item_ref.owner_id).has_value()
-                        {
+                        if assoc_item.is_type() && !assoc_item.defaultness(tcx).has_value() {
                             // No type to visit.
                         } else {
                             reach.ty();
@@ -683,12 +687,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     }
                 }
             }
-            hir::ItemKind::TraitAlias(..) => {
+            DefKind::TraitAlias => {
                 if let Some(item_ev) = item_ev {
-                    self.reach(item.owner_id.def_id, item_ev).generics().predicates();
+                    self.reach(owner_id.def_id, item_ev).generics().predicates();
                 }
             }
-            hir::ItemKind::Impl(impl_) => {
+            DefKind::Impl { of_trait } => {
                 // Type inference is very smart sometimes. It can make an impl reachable even some
                 // components of its type or trait are unreachable. E.g. methods of
                 // `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
@@ -700,19 +704,23 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                 // without knowing both "shallow" version of its self type and "shallow" version of
                 // its trait if it exists (which require reaching the `DefId`s in them).
                 let item_ev = EffectiveVisibility::of_impl::<true>(
-                    item.owner_id.def_id,
+                    owner_id.def_id,
                     self.tcx,
                     &self.effective_visibilities,
                 );
 
-                self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct);
+                self.update_eff_vis(owner_id.def_id, item_ev, None, Level::Direct);
+
+                self.reach(owner_id.def_id, item_ev).generics().predicates().ty().trait_ref();
 
-                self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref();
+                for assoc_item in self.tcx.associated_items(owner_id).in_definition_order() {
+                    if assoc_item.is_impl_trait_in_trait() {
+                        continue;
+                    }
 
-                for impl_item_ref in impl_.items {
-                    let def_id = impl_item_ref.owner_id.def_id;
+                    let def_id = assoc_item.def_id.expect_local();
                     let max_vis =
-                        impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id));
+                        if of_trait { None } else { Some(self.tcx.local_visibility(def_id)) };
                     self.update_eff_vis(def_id, item_ev, max_vis, Level::Direct);
 
                     if let Some(impl_item_ev) = self.get(def_id) {
@@ -720,65 +728,76 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     }
                 }
             }
-            hir::ItemKind::Enum(_, _, ref def) => {
+            DefKind::Enum => {
                 if let Some(item_ev) = item_ev {
-                    self.reach(item.owner_id.def_id, item_ev).generics().predicates();
+                    self.reach(owner_id.def_id, item_ev).generics().predicates();
                 }
-                for variant in def.variants {
+                let def = self.tcx.adt_def(owner_id);
+                for variant in def.variants() {
                     if let Some(item_ev) = item_ev {
-                        self.update(variant.def_id, item_ev, Level::Reachable);
+                        self.update(variant.def_id.expect_local(), item_ev, Level::Reachable);
                     }
 
-                    if let Some(variant_ev) = self.get(variant.def_id) {
-                        if let Some(ctor_def_id) = variant.data.ctor_def_id() {
-                            self.update(ctor_def_id, variant_ev, Level::Reachable);
+                    if let Some(variant_ev) = self.get(variant.def_id.expect_local()) {
+                        if let Some(ctor_def_id) = variant.ctor_def_id() {
+                            self.update(ctor_def_id.expect_local(), variant_ev, Level::Reachable);
                         }
 
-                        for field in variant.data.fields() {
-                            self.update(field.def_id, variant_ev, Level::Reachable);
-                            self.reach(field.def_id, variant_ev).ty();
+                        for field in &variant.fields {
+                            let field = field.did.expect_local();
+                            self.update(field, variant_ev, Level::Reachable);
+                            self.reach(field, variant_ev).ty();
                         }
                         // Corner case: if the variant is reachable, but its
                         // enum is not, make the enum reachable as well.
-                        self.reach(item.owner_id.def_id, variant_ev).ty();
+                        self.reach(owner_id.def_id, variant_ev).ty();
                     }
-                    if let Some(ctor_def_id) = variant.data.ctor_def_id() {
-                        if let Some(ctor_ev) = self.get(ctor_def_id) {
-                            self.reach(item.owner_id.def_id, ctor_ev).ty();
+                    if let Some(ctor_def_id) = variant.ctor_def_id() {
+                        if let Some(ctor_ev) = self.get(ctor_def_id.expect_local()) {
+                            self.reach(owner_id.def_id, ctor_ev).ty();
                         }
                     }
                 }
             }
-            hir::ItemKind::ForeignMod { items, .. } => {
-                for foreign_item in items {
-                    if let Some(foreign_item_ev) = self.get(foreign_item.owner_id.def_id) {
-                        self.reach(foreign_item.owner_id.def_id, foreign_item_ev)
-                            .generics()
-                            .predicates()
-                            .ty();
-                    }
-                }
-            }
-            hir::ItemKind::Struct(_, _, ref struct_def)
-            | hir::ItemKind::Union(_, _, ref struct_def) => {
+            DefKind::Struct | DefKind::Union => {
+                let def = self.tcx.adt_def(owner_id).non_enum_variant();
                 if let Some(item_ev) = item_ev {
-                    self.reach(item.owner_id.def_id, item_ev).generics().predicates();
-                    for field in struct_def.fields() {
-                        self.update(field.def_id, item_ev, Level::Reachable);
-                        if let Some(field_ev) = self.get(field.def_id) {
-                            self.reach(field.def_id, field_ev).ty();
+                    self.reach(owner_id.def_id, item_ev).generics().predicates();
+                    for field in &def.fields {
+                        let field = field.did.expect_local();
+                        self.update(field, item_ev, Level::Reachable);
+                        if let Some(field_ev) = self.get(field) {
+                            self.reach(field, field_ev).ty();
                         }
                     }
                 }
-                if let Some(ctor_def_id) = struct_def.ctor_def_id() {
+                if let Some(ctor_def_id) = def.ctor_def_id() {
                     if let Some(item_ev) = item_ev {
-                        self.update(ctor_def_id, item_ev, Level::Reachable);
+                        self.update(ctor_def_id.expect_local(), item_ev, Level::Reachable);
                     }
-                    if let Some(ctor_ev) = self.get(ctor_def_id) {
-                        self.reach(item.owner_id.def_id, ctor_ev).ty();
+                    if let Some(ctor_ev) = self.get(ctor_def_id.expect_local()) {
+                        self.reach(owner_id.def_id, ctor_ev).ty();
                     }
                 }
             }
+            // Contents are checked directly.
+            DefKind::ForeignMod => {}
+            DefKind::Field
+            | DefKind::Variant
+            | DefKind::AssocFn
+            | DefKind::AssocTy
+            | DefKind::AssocConst
+            | DefKind::TyParam
+            | DefKind::AnonConst
+            | DefKind::InlineConst
+            | DefKind::OpaqueTy
+            | DefKind::Closure
+            | DefKind::SyntheticCoroutineBody
+            | DefKind::ConstParam
+            | DefKind::LifetimeParam
+            | DefKind::Ctor(..) => {
+                bug!("should be checked while checking parent")
+            }
         }
     }
 }
@@ -839,7 +858,7 @@ pub struct TestReachabilityVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> TestReachabilityVisitor<'a, 'tcx> {
-    fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) {
+    fn effective_visibility_diagnostic(&self, def_id: LocalDefId) {
         if self.tcx.has_attr(def_id, sym::rustc_effective_visibility) {
             let mut error_msg = String::new();
             let span = self.tcx.def_span(def_id.to_def_id());
@@ -859,43 +878,35 @@ impl<'a, 'tcx> TestReachabilityVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for TestReachabilityVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        self.effective_visibility_diagnostic(item.owner_id.def_id);
+impl<'a, 'tcx> TestReachabilityVisitor<'a, 'tcx> {
+    fn check_def_id(&self, owner_id: OwnerId) {
+        self.effective_visibility_diagnostic(owner_id.def_id);
 
-        match item.kind {
-            hir::ItemKind::Enum(_, _, ref def) => {
-                for variant in def.variants.iter() {
-                    self.effective_visibility_diagnostic(variant.def_id);
-                    if let Some(ctor_def_id) = variant.data.ctor_def_id() {
-                        self.effective_visibility_diagnostic(ctor_def_id);
+        match self.tcx.def_kind(owner_id) {
+            DefKind::Enum => {
+                let def = self.tcx.adt_def(owner_id.def_id);
+                for variant in def.variants() {
+                    self.effective_visibility_diagnostic(variant.def_id.expect_local());
+                    if let Some(ctor_def_id) = variant.ctor_def_id() {
+                        self.effective_visibility_diagnostic(ctor_def_id.expect_local());
                     }
-                    for field in variant.data.fields() {
-                        self.effective_visibility_diagnostic(field.def_id);
+                    for field in &variant.fields {
+                        self.effective_visibility_diagnostic(field.did.expect_local());
                     }
                 }
             }
-            hir::ItemKind::Struct(_, _, ref def) | hir::ItemKind::Union(_, _, ref def) => {
+            DefKind::Struct | DefKind::Union => {
+                let def = self.tcx.adt_def(owner_id.def_id).non_enum_variant();
                 if let Some(ctor_def_id) = def.ctor_def_id() {
-                    self.effective_visibility_diagnostic(ctor_def_id);
+                    self.effective_visibility_diagnostic(ctor_def_id.expect_local());
                 }
-                for field in def.fields() {
-                    self.effective_visibility_diagnostic(field.def_id);
+                for field in &def.fields {
+                    self.effective_visibility_diagnostic(field.did.expect_local());
                 }
             }
             _ => {}
         }
     }
-
-    fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'tcx>) {
-        self.effective_visibility_diagnostic(item.owner_id.def_id);
-    }
-    fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'tcx>) {
-        self.effective_visibility_diagnostic(item.owner_id.def_id);
-    }
-    fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
-        self.effective_visibility_diagnostic(item.owner_id.def_id);
-    }
 }
 
 //////////////////////////////////////////////////////////////////////////////////////
@@ -1423,8 +1434,6 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
         };
 
         let vis = self.tcx.local_visibility(local_def_id);
-        let span = self.tcx.def_span(self.item_def_id.to_def_id());
-        let vis_span = self.tcx.def_span(def_id);
         if self.in_assoc_ty && !vis.is_at_least(self.required_visibility, self.tcx) {
             let vis_descr = match vis {
                 ty::Visibility::Public => "public",
@@ -1441,6 +1450,8 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
                 }
             };
 
+            let span = self.tcx.def_span(self.item_def_id.to_def_id());
+            let vis_span = self.tcx.def_span(def_id);
             self.tcx.dcx().emit_err(InPublicInterface {
                 span,
                 vis_descr,
@@ -1463,6 +1474,8 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
             } else {
                 lint::builtin::PRIVATE_BOUNDS
             };
+            let span = self.tcx.def_span(self.item_def_id.to_def_id());
+            let vis_span = self.tcx.def_span(def_id);
             self.tcx.emit_node_span_lint(
                 lint,
                 self.tcx.local_def_id_to_hir_id(self.item_def_id),
@@ -1594,7 +1607,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
         self.effective_visibilities.effective_vis(def_id).copied()
     }
 
-    fn check_item(&mut self, id: ItemId) {
+    fn check_item(&self, id: ItemId) {
         let tcx = self.tcx;
         let def_id = id.owner_id.def_id;
         let item_visibility = tcx.local_visibility(def_id);
@@ -1722,7 +1735,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
         }
     }
 
-    fn check_foreign_item(&mut self, id: ForeignItemId) {
+    fn check_foreign_item(&self, id: ForeignItemId) {
         let tcx = self.tcx;
         let def_id = id.owner_id.def_id;
         let item_visibility = tcx.local_visibility(def_id);
@@ -1836,8 +1849,14 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
         visitor.changed = false;
     }
 
+    let crate_items = tcx.hir_crate_items(());
     loop {
-        tcx.hir_visit_all_item_likes_in_crate(&mut visitor);
+        for id in crate_items.free_items() {
+            visitor.check_def_id(id.owner_id);
+        }
+        for id in crate_items.foreign_items() {
+            visitor.check_def_id(id.owner_id);
+        }
         if visitor.changed {
             visitor.changed = false;
         } else {
@@ -1846,24 +1865,21 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
     }
     visitor.effective_visibilities.check_invariants(tcx);
 
-    let mut check_visitor =
+    let check_visitor =
         TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities };
-    check_visitor.effective_visibility_diagnostic(CRATE_DEF_ID);
-    tcx.hir_visit_all_item_likes_in_crate(&mut check_visitor);
+    for id in crate_items.owners() {
+        check_visitor.check_def_id(id);
+    }
 
     tcx.arena.alloc(visitor.effective_visibilities)
 }
 
-fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
+fn check_private_in_public(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     let effective_visibilities = tcx.effective_visibilities(());
     // Check for private types in public interfaces.
-    let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
+    let checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
 
-    let crate_items = tcx.hir_crate_items(());
-    for id in crate_items.free_items() {
-        checker.check_item(id);
-    }
-    for id in crate_items.foreign_items() {
-        checker.check_foreign_item(id);
-    }
+    let crate_items = tcx.hir_module_items(module_def_id);
+    let _ = crate_items.par_items(|id| Ok(checker.check_item(id)));
+    let _ = crate_items.par_foreign_items(|id| Ok(checker.check_foreign_item(id)));
 }
diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml
index 9ea9c58cfd1..eb98a6e85c0 100644
--- a/compiler/rustc_resolve/Cargo.toml
+++ b/compiler/rustc_resolve/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 bitflags = "2.4.1"
+indexmap = "2.4.0"
 itertools = "0.12"
 pulldown-cmark = { version = "0.11", features = ["html"], default-features = false }
 rustc_arena = { path = "../rustc_arena" }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 82eae088803..d9671c43b3d 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -968,7 +968,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         }
         self.r.potentially_unused_imports.push(import);
         let imported_binding = self.r.import(binding, import);
-        if parent == self.r.graph_root {
+        if ident.name != kw::Underscore && parent == self.r.graph_root {
             let ident = ident.normalize_to_macros_2_0();
             if let Some(entry) = self.r.extern_prelude.get(&ident)
                 && expansion != LocalExpnId::ROOT
@@ -984,23 +984,29 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                 // more details: https://github.com/rust-lang/rust/pull/111761
                 return;
             }
-            let entry = self.r.extern_prelude.entry(ident).or_insert(ExternPreludeEntry {
-                binding: Cell::new(None),
-                introduced_by_item: true,
-            });
-            if orig_name.is_some() {
-                entry.introduced_by_item = true;
-            }
-            // Binding from `extern crate` item in source code can replace
-            // a binding from `--extern` on command line here.
-            if !entry.is_import() {
-                entry.binding.set(Some(imported_binding));
-            } else if ident.name != kw::Underscore {
-                self.r.dcx().span_delayed_bug(
-                    item.span,
-                    format!("it had been define the external module '{ident}' multiple times"),
-                );
-            }
+
+            use indexmap::map::Entry;
+            match self.r.extern_prelude.entry(ident) {
+                Entry::Occupied(mut occupied) => {
+                    let entry = occupied.get_mut();
+                    if let Some(old_binding) = entry.binding.get()
+                        && old_binding.is_import()
+                    {
+                        let msg = format!("extern crate `{ident}` already in extern prelude");
+                        self.r.tcx.dcx().span_delayed_bug(item.span, msg);
+                    } else {
+                        // Binding from `extern crate` item in source code can replace
+                        // a binding from `--extern` on command line here.
+                        entry.binding.set(Some(imported_binding));
+                        entry.introduced_by_item = orig_name.is_some();
+                    }
+                    entry
+                }
+                Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry {
+                    binding: Cell::new(Some(imported_binding)),
+                    introduced_by_item: true,
+                }),
+            };
         }
         self.r.define_binding_local(parent, ident, TypeNS, imported_binding);
     }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index b14a6edb791..d18554bba1b 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -801,10 +801,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                     }
                     err.multipart_suggestion(msg, suggestions, applicability);
                 }
-                if let Some(ModuleOrUniformRoot::Module(module)) = module
-                    && let Some(module) = module.opt_def_id()
-                    && let Some(segment) = segment
-                {
+
+                if let Some(segment) = segment {
+                    let module = match module {
+                        Some(ModuleOrUniformRoot::Module(m)) if let Some(id) = m.opt_def_id() => id,
+                        _ => CRATE_DEF_ID.to_def_id(),
+                    };
                     self.find_cfg_stripped(&mut err, &segment, module);
                 }
 
@@ -1096,7 +1098,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                     }
                 }
                 Scope::ExternPrelude => {
-                    suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
+                    suggestions.extend(this.extern_prelude.keys().filter_map(|ident| {
                         let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
                         filter_fn(res).then_some(TypoSuggestion::typo_from_ident(*ident, res))
                     }));
@@ -1407,7 +1409,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         );
 
         if lookup_ident.span.at_least_rust_2018() {
-            for ident in self.extern_prelude.clone().into_keys() {
+            for &ident in self.extern_prelude.keys() {
                 if ident.span.from_expansion() {
                     // Idents are adjusted to the root context before being
                     // resolved in the extern prelude, so reporting this to the
@@ -2839,16 +2841,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 continue;
             }
 
-            let note = errors::FoundItemConfigureOut { span: ident.span };
-            err.subdiagnostic(note);
-
-            if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 {
-                let note = errors::ItemWasBehindFeature { feature, span: cfg.1 };
-                err.subdiagnostic(note);
+            let item_was = if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 {
+                errors::ItemWas::BehindFeature { feature, span: cfg.1 }
             } else {
-                let note = errors::ItemWasCfgOut { span: cfg.1 };
-                err.subdiagnostic(note);
-            }
+                errors::ItemWas::CfgOut { span: cfg.1 }
+            };
+            let note = errors::FoundItemConfigureOut { span: ident.span, item_was };
+            err.subdiagnostic(note);
         }
     }
 }
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index d6b1e4de6ea..2747ba135ed 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -1,10 +1,13 @@
 use rustc_errors::codes::*;
-use rustc_errors::{Applicability, ElidedLifetimeInPathSubdiag, MultiSpan};
+use rustc_errors::{
+    Applicability, Diag, ElidedLifetimeInPathSubdiag, EmissionGuarantee, IntoDiagArg, MultiSpan,
+    Subdiagnostic,
+};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{Ident, Span, Symbol};
 
-use crate::Res;
 use crate::late::PatternSource;
+use crate::{Res, fluent_generated as fluent};
 
 #[derive(Diagnostic)]
 #[diag(resolve_generic_params_from_outer_item, code = E0401)]
@@ -1201,26 +1204,35 @@ pub(crate) struct IdentInScopeButItIsDesc<'a> {
     pub(crate) imported_ident_desc: &'a str,
 }
 
-#[derive(Subdiagnostic)]
-#[note(resolve_found_an_item_configured_out)]
 pub(crate) struct FoundItemConfigureOut {
-    #[primary_span]
-    pub(crate) span: Span,
-}
-
-#[derive(Subdiagnostic)]
-#[note(resolve_item_was_behind_feature)]
-pub(crate) struct ItemWasBehindFeature {
-    pub(crate) feature: Symbol,
-    #[primary_span]
-    pub(crate) span: Span,
-}
-
-#[derive(Subdiagnostic)]
-#[note(resolve_item_was_cfg_out)]
-pub(crate) struct ItemWasCfgOut {
-    #[primary_span]
     pub(crate) span: Span,
+    pub(crate) item_was: ItemWas,
+}
+
+pub(crate) enum ItemWas {
+    BehindFeature { feature: Symbol, span: Span },
+    CfgOut { span: Span },
+}
+
+impl Subdiagnostic for FoundItemConfigureOut {
+    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
+        let mut multispan: MultiSpan = self.span.into();
+        match self.item_was {
+            ItemWas::BehindFeature { feature, span } => {
+                let key = "feature".into();
+                let value = feature.into_diag_arg(&mut None);
+                let msg = diag.dcx.eagerly_translate_to_string(
+                    fluent::resolve_item_was_behind_feature,
+                    [(&key, &value)].into_iter(),
+                );
+                multispan.push_span_label(span, msg);
+            }
+            ItemWas::CfgOut { span } => {
+                multispan.push_span_label(span, fluent::resolve_item_was_cfg_out);
+            }
+        }
+        diag.span_note(multispan, fluent::resolve_found_an_item_configured_out);
+    }
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 261d099abdc..163e4b5b7a9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -4231,13 +4231,21 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 //
                 // And that's what happens below - we're just mixing both messages
                 // into a single one.
+                let failed_to_resolve = match parent_err.node {
+                    ResolutionError::FailedToResolve { .. } => true,
+                    _ => false,
+                };
                 let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
 
                 // overwrite all properties with the parent's error message
                 err.messages = take(&mut parent_err.messages);
                 err.code = take(&mut parent_err.code);
                 swap(&mut err.span, &mut parent_err.span);
-                err.children = take(&mut parent_err.children);
+                if failed_to_resolve {
+                    err.children = take(&mut parent_err.children);
+                } else {
+                    err.children.append(&mut parent_err.children);
+                }
                 err.sort_span = parent_err.sort_span;
                 err.is_lint = parent_err.is_lint.clone();
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 98e48664e68..c8ca57a380f 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -525,9 +525,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         }
         self.err_code_special_cases(&mut err, source, path, span);
 
-        if let Some(module) = base_error.module {
-            self.r.find_cfg_stripped(&mut err, &path.last().unwrap().ident.name, module);
-        }
+        let module = base_error.module.unwrap_or_else(|| CRATE_DEF_ID.to_def_id());
+        self.r.find_cfg_stripped(&mut err, &path.last().unwrap().ident.name, module);
 
         (err, candidates)
     }
@@ -2477,19 +2476,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     } else {
                         // Items from the prelude
                         if !module.no_implicit_prelude {
-                            let extern_prelude = self.r.extern_prelude.clone();
-                            names.extend(extern_prelude.iter().flat_map(|(ident, _)| {
-                                self.r
-                                    .cstore_mut()
-                                    .maybe_process_path_extern(self.r.tcx, ident.name)
-                                    .and_then(|crate_id| {
-                                        let crate_mod =
-                                            Res::Def(DefKind::Mod, crate_id.as_def_id());
-
-                                        filter_fn(crate_mod).then(|| {
-                                            TypoSuggestion::typo_from_ident(*ident, crate_mod)
-                                        })
-                                    })
+                            names.extend(self.r.extern_prelude.keys().flat_map(|ident| {
+                                let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
+                                filter_fn(res)
+                                    .then_some(TypoSuggestion::typo_from_ident(*ident, res))
                             }));
 
                             if let Some(prelude) = self.r.prelude {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index dbde6f7cfd7..6b034c5129f 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1487,13 +1487,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         let mut invocation_parents = FxHashMap::default();
         invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT);
 
-        let mut extern_prelude: FxIndexMap<Ident, ExternPreludeEntry<'_>> = tcx
+        let mut extern_prelude: FxIndexMap<_, _> = tcx
             .sess
             .opts
             .externs
             .iter()
-            .filter(|(_, entry)| entry.add_prelude)
-            .map(|(name, _)| (Ident::from_str(name), Default::default()))
+            .filter_map(|(name, entry)| {
+                // Make sure `self`, `super`, `_` etc do not get into extern prelude.
+                // FIXME: reject `--extern self` and similar in option parsing instead.
+                if entry.add_prelude
+                    && let name = Symbol::intern(name)
+                    && name.can_be_raw()
+                {
+                    Some((Ident::with_dummy_span(name), Default::default()))
+                } else {
+                    None
+                }
+            })
             .collect();
 
         if !attr::contains_name(attrs, sym::no_core) {
@@ -2168,40 +2178,42 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     }
 
     fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBinding<'ra>> {
-        if ident.is_path_segment_keyword() {
-            // Make sure `self`, `super` etc produce an error when passed to here.
-            return None;
-        }
-
-        let norm_ident = ident.normalize_to_macros_2_0();
-        let binding = self.extern_prelude.get(&norm_ident).cloned().and_then(|entry| {
-            Some(if let Some(binding) = entry.binding.get() {
+        let mut record_use = None;
+        let entry = self.extern_prelude.get(&ident.normalize_to_macros_2_0());
+        let binding = entry.and_then(|entry| match entry.binding.get() {
+            Some(binding) if binding.is_import() => {
                 if finalize {
-                    if !entry.is_import() {
-                        self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
-                    } else if entry.introduced_by_item {
-                        self.record_use(ident, binding, Used::Other);
-                    }
+                    record_use = Some(binding);
                 }
-                binding
-            } else {
+                Some(binding)
+            }
+            Some(binding) => {
+                if finalize {
+                    self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
+                }
+                Some(binding)
+            }
+            None => {
                 let crate_id = if finalize {
-                    let Some(crate_id) =
-                        self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span)
-                    else {
-                        return Some(self.dummy_binding);
-                    };
-                    crate_id
+                    self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span)
                 } else {
-                    self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name)?
+                    self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name)
                 };
-                let res = Res::Def(DefKind::Mod, crate_id.as_def_id());
-                self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT)
-            })
+                match crate_id {
+                    Some(crate_id) => {
+                        let res = Res::Def(DefKind::Mod, crate_id.as_def_id());
+                        let binding =
+                            self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT);
+                        entry.binding.set(Some(binding));
+                        Some(binding)
+                    }
+                    None => finalize.then_some(self.dummy_binding),
+                }
+            }
         });
 
-        if let Some(entry) = self.extern_prelude.get(&norm_ident) {
-            entry.binding.set(binding);
+        if let Some(binding) = record_use {
+            self.record_use(ident, binding, Used::Scope);
         }
 
         binding
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 8f624e0fb2f..cfeadf3c759 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -182,14 +182,7 @@ pub enum InstrumentCoverage {
 pub struct CoverageOptions {
     pub level: CoverageLevel,
 
-    /// `-Zcoverage-options=no-mir-spans`: Don't extract block coverage spans
-    /// from MIR statements/terminators, making it easier to inspect/debug
-    /// branch and MC/DC coverage mappings.
-    ///
-    /// For internal debugging only. If other code changes would make it hard
-    /// to keep supporting this flag, remove it.
-    pub no_mir_spans: bool,
-
+    /// **(internal test-only flag)**
     /// `-Zcoverage-options=discard-all-spans-in-codegen`: During codegen,
     /// discard all coverage spans as though they were invalid. Needed by
     /// regression tests for #133606, because we don't have an easy way to
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 44b35e8921e..880b08d4444 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -755,8 +755,7 @@ mod desc {
     pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
     pub(crate) const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
     pub(crate) const parse_instrument_coverage: &str = parse_bool;
-    pub(crate) const parse_coverage_options: &str =
-        "`block` | `branch` | `condition` | `mcdc` | `no-mir-spans`";
+    pub(crate) const parse_coverage_options: &str = "`block` | `branch` | `condition` | `mcdc`";
     pub(crate) const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
     pub(crate) const parse_unpretty: &str = "`string` or `string=string`";
     pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
@@ -1460,7 +1459,6 @@ pub mod parse {
                 "branch" => slot.level = CoverageLevel::Branch,
                 "condition" => slot.level = CoverageLevel::Condition,
                 "mcdc" => slot.level = CoverageLevel::Mcdc,
-                "no-mir-spans" => slot.no_mir_spans = true,
                 "discard-all-spans-in-codegen" => slot.discard_all_spans_in_codegen = true,
                 _ => return false,
             }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index e7097ec8327..b94636fea94 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -39,8 +39,8 @@ use rustc_target::spec::{
 use crate::code_stats::CodeStats;
 pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
 use crate::config::{
-    self, CoverageLevel, CrateType, DebugInfo, ErrorOutputType, FunctionReturn, Input,
-    InstrumentCoverage, OptLevel, OutFileName, OutputType, RemapPathScopeComponents,
+    self, CoverageLevel, CoverageOptions, CrateType, DebugInfo, ErrorOutputType, FunctionReturn,
+    Input, InstrumentCoverage, OptLevel, OutFileName, OutputType, RemapPathScopeComponents,
     SwitchWithOptPath,
 };
 use crate::filesearch::FileSearch;
@@ -359,14 +359,11 @@ impl Session {
             && self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Mcdc
     }
 
-    /// True if `-Zcoverage-options=no-mir-spans` was passed.
-    pub fn coverage_no_mir_spans(&self) -> bool {
-        self.opts.unstable_opts.coverage_options.no_mir_spans
-    }
-
-    /// True if `-Zcoverage-options=discard-all-spans-in-codegen` was passed.
-    pub fn coverage_discard_all_spans_in_codegen(&self) -> bool {
-        self.opts.unstable_opts.coverage_options.discard_all_spans_in_codegen
+    /// Provides direct access to the `CoverageOptions` struct, so that
+    /// individual flags for debugging/testing coverage instrumetation don't
+    /// need separate accessors.
+    pub fn coverage_options(&self) -> &CoverageOptions {
+        &self.opts.unstable_opts.coverage_options
     }
 
     pub fn is_sanitizer_cfi_enabled(&self) -> bool {
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 97d1d9c2d2a..19494ffc37e 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -768,7 +768,9 @@ impl SyntaxContext {
     ///
     /// ```rust
     /// #![feature(decl_macro)]
-    /// mod foo { pub fn f() {} } // `f`'s `SyntaxContext` is empty.
+    /// mod foo {
+    ///     pub fn f() {} // `f`'s `SyntaxContext` is empty.
+    /// }
     /// m!(f);
     /// macro m($f:ident) {
     ///     mod bar {
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 12d1de46313..aa8292c0504 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -58,59 +58,57 @@ pub(super) fn mangle<'tcx>(
 
     let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate);
 
-    let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false };
-    printer
-        .print_def_path(
-            def_id,
-            if let ty::InstanceKind::DropGlue(_, _)
-            | ty::InstanceKind::AsyncDropGlueCtorShim(_, _)
-            | ty::InstanceKind::FutureDropPollShim(_, _, _) = instance.def
-            {
-                // Add the name of the dropped type to the symbol name
-                &*instance.args
-            } else if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def {
-                let ty::Coroutine(_, cor_args) = ty.kind() else {
-                    bug!();
-                };
-                let drop_ty = cor_args.first().unwrap().expect_ty();
-                tcx.mk_args(&[GenericArg::from(drop_ty)])
-            } else {
-                &[]
-            },
-        )
-        .unwrap();
+    let mut p = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false };
+    p.print_def_path(
+        def_id,
+        if let ty::InstanceKind::DropGlue(_, _)
+        | ty::InstanceKind::AsyncDropGlueCtorShim(_, _)
+        | ty::InstanceKind::FutureDropPollShim(_, _, _) = instance.def
+        {
+            // Add the name of the dropped type to the symbol name
+            &*instance.args
+        } else if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def {
+            let ty::Coroutine(_, cor_args) = ty.kind() else {
+                bug!();
+            };
+            let drop_ty = cor_args.first().unwrap().expect_ty();
+            tcx.mk_args(&[GenericArg::from(drop_ty)])
+        } else {
+            &[]
+        },
+    )
+    .unwrap();
 
     match instance.def {
         ty::InstanceKind::ThreadLocalShim(..) => {
-            printer.write_str("{{tls-shim}}").unwrap();
+            p.write_str("{{tls-shim}}").unwrap();
         }
         ty::InstanceKind::VTableShim(..) => {
-            printer.write_str("{{vtable-shim}}").unwrap();
+            p.write_str("{{vtable-shim}}").unwrap();
         }
         ty::InstanceKind::ReifyShim(_, reason) => {
-            printer.write_str("{{reify-shim").unwrap();
+            p.write_str("{{reify-shim").unwrap();
             match reason {
-                Some(ReifyReason::FnPtr) => printer.write_str("-fnptr").unwrap(),
-                Some(ReifyReason::Vtable) => printer.write_str("-vtable").unwrap(),
+                Some(ReifyReason::FnPtr) => p.write_str("-fnptr").unwrap(),
+                Some(ReifyReason::Vtable) => p.write_str("-vtable").unwrap(),
                 None => (),
             }
-            printer.write_str("}}").unwrap();
+            p.write_str("}}").unwrap();
         }
         // FIXME(async_closures): This shouldn't be needed when we fix
         // `Instance::ty`/`Instance::def_id`.
         ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } => {
-            printer
-                .write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" })
+            p.write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" })
                 .unwrap();
         }
         _ => {}
     }
 
     if let ty::InstanceKind::FutureDropPollShim(..) = instance.def {
-        let _ = printer.write_str("{{drop-shim}}");
+        let _ = p.write_str("{{drop-shim}}");
     }
 
-    printer.path.finish(hash)
+    p.path.finish(hash)
 }
 
 fn get_symbol_hash<'tcx>(
@@ -236,7 +234,7 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
     }
 
     fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
-        Ok(())
+        unreachable!(); // because `<Self As PrettyPrinter>::should_print_region` returns false
     }
 
     fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
@@ -334,7 +332,6 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
     fn path_append_impl(
         &mut self,
         print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
-        _disambiguated_data: &DisambiguatedDefPathData,
         self_ty: Ty<'tcx>,
         trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError> {
@@ -460,6 +457,8 @@ impl<'tcx> PrettyPrinter<'tcx> for SymbolPrinter<'tcx> {
     fn should_print_region(&self, _region: ty::Region<'_>) -> bool {
         false
     }
+
+    // Identical to `PrettyPrinter::comma_sep` except there is no space after each comma.
     fn comma_sep<T>(&mut self, mut elems: impl Iterator<Item = T>) -> Result<(), PrintError>
     where
         T: Print<'tcx, Self>,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index fe0f8e6113e..c2458ae814b 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -33,7 +33,7 @@ pub(super) fn mangle<'tcx>(
     let args = tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), instance.args);
 
     let prefix = "_R";
-    let mut cx: SymbolMangler<'_> = SymbolMangler {
+    let mut p: SymbolMangler<'_> = SymbolMangler {
         tcx,
         start_offset: prefix.len(),
         is_exportable,
@@ -69,16 +69,16 @@ pub(super) fn mangle<'tcx>(
             bug!();
         };
         let drop_ty = cor_args.first().unwrap().expect_ty();
-        cx.print_def_path(def_id, tcx.mk_args(&[GenericArg::from(drop_ty)])).unwrap()
+        p.print_def_path(def_id, tcx.mk_args(&[GenericArg::from(drop_ty)])).unwrap()
     } else if let Some(shim_kind) = shim_kind {
-        cx.path_append_ns(|cx| cx.print_def_path(def_id, args), 'S', 0, shim_kind).unwrap()
+        p.path_append_ns(|p| p.print_def_path(def_id, args), 'S', 0, shim_kind).unwrap()
     } else {
-        cx.print_def_path(def_id, args).unwrap()
+        p.print_def_path(def_id, args).unwrap()
     };
     if let Some(instantiating_crate) = instantiating_crate {
-        cx.print_def_path(instantiating_crate.as_def_id(), &[]).unwrap();
+        p.print_def_path(instantiating_crate.as_def_id(), &[]).unwrap();
     }
-    std::mem::take(&mut cx.out)
+    std::mem::take(&mut p.out)
 }
 
 pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> String {
@@ -88,7 +88,7 @@ pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> Strin
     }
 
     let prefix = "_R";
-    let mut cx: SymbolMangler<'_> = SymbolMangler {
+    let mut p: SymbolMangler<'_> = SymbolMangler {
         tcx,
         start_offset: prefix.len(),
         is_exportable: false,
@@ -99,10 +99,10 @@ pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> Strin
         out: String::from(prefix),
     };
 
-    cx.path_append_ns(
-        |cx| {
-            cx.push("C");
-            cx.push_disambiguator({
+    p.path_append_ns(
+        |p| {
+            p.push("C");
+            p.push_disambiguator({
                 let mut hasher = StableHasher::new();
                 // Incorporate the rustc version to ensure #[rustc_std_internal_symbol] functions
                 // get a different symbol name depending on the rustc version.
@@ -114,7 +114,7 @@ pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> Strin
                 let hash: Hash64 = hasher.finish();
                 hash.as_u64()
             });
-            cx.push_ident("__rustc");
+            p.push_ident("__rustc");
             Ok(())
         },
         'v',
@@ -123,7 +123,7 @@ pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> Strin
     )
     .unwrap();
 
-    std::mem::take(&mut cx.out)
+    std::mem::take(&mut p.out)
 }
 
 pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
@@ -131,7 +131,7 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
     trait_ref: ty::ExistentialTraitRef<'tcx>,
 ) -> String {
     // FIXME(flip1995): See comment in `mangle_typeid_for_fnabi`.
-    let mut cx = SymbolMangler {
+    let mut p = SymbolMangler {
         tcx,
         start_offset: 0,
         is_exportable: false,
@@ -141,8 +141,8 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
         binders: vec![],
         out: String::new(),
     };
-    cx.print_def_path(trait_ref.def_id, &[]).unwrap();
-    std::mem::take(&mut cx.out)
+    p.print_def_path(trait_ref.def_id, &[]).unwrap();
+    std::mem::take(&mut p.out)
 }
 
 struct BinderLevel {
@@ -368,7 +368,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             self.path_generic_args(
                 |this| {
                     this.path_append_ns(
-                        |cx| cx.print_def_path(parent_def_id, &[]),
+                        |p| p.print_def_path(parent_def_id, &[]),
                         'I',
                         key.disambiguated_data.disambiguator as u64,
                         "",
@@ -425,7 +425,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             ty::Bool => "b",
             ty::Char => "c",
             ty::Str => "e",
-            ty::Tuple(_) if ty.is_unit() => "u",
             ty::Int(IntTy::I8) => "a",
             ty::Int(IntTy::I16) => "s",
             ty::Int(IntTy::I32) => "l",
@@ -444,12 +443,12 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             ty::Float(FloatTy::F128) => "C4f128",
             ty::Never => "z",
 
+            ty::Tuple(_) if ty.is_unit() => "u",
+
             // Should only be encountered within the identity-substituted
             // impl header of an item nested within an impl item.
             ty::Param(_) => "p",
 
-            ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => bug!(),
-
             _ => "",
         };
         if !basic_type.is_empty() {
@@ -468,11 +467,9 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 unreachable!()
             }
             ty::Tuple(_) if ty.is_unit() => unreachable!(),
+            ty::Param(_) => unreachable!(),
 
-            // Placeholders, also handled as part of basic types.
-            ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => {
-                unreachable!()
-            }
+            ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => bug!(),
 
             ty::Ref(r, ty, mutbl) => {
                 self.push(match mutbl {
@@ -542,31 +539,31 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             ty::FnPtr(sig_tys, hdr) => {
                 let sig = sig_tys.with(hdr);
                 self.push("F");
-                self.wrap_binder(&sig, |cx, sig| {
+                self.wrap_binder(&sig, |p, sig| {
                     if sig.safety.is_unsafe() {
-                        cx.push("U");
+                        p.push("U");
                     }
                     match sig.abi {
                         ExternAbi::Rust => {}
-                        ExternAbi::C { unwind: false } => cx.push("KC"),
+                        ExternAbi::C { unwind: false } => p.push("KC"),
                         abi => {
-                            cx.push("K");
+                            p.push("K");
                             let name = abi.as_str();
                             if name.contains('-') {
-                                cx.push_ident(&name.replace('-', "_"));
+                                p.push_ident(&name.replace('-', "_"));
                             } else {
-                                cx.push_ident(name);
+                                p.push_ident(name);
                             }
                         }
                     }
                     for &ty in sig.inputs() {
-                        ty.print(cx)?;
+                        ty.print(p)?;
                     }
                     if sig.c_variadic {
-                        cx.push("v");
+                        p.push("v");
                     }
-                    cx.push("E");
-                    sig.output().print(cx)
+                    p.push("E");
+                    sig.output().print(p)
                 })?;
             }
 
@@ -623,7 +620,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
         // [<Trait> [{<Projection>}]] [{<Auto>}]
         // Since any predicates after the first one shouldn't change the binders,
         // just put them all in the binders of the first.
-        self.wrap_binder(&predicates[0], |cx, _| {
+        self.wrap_binder(&predicates[0], |p, _| {
             for predicate in predicates.iter() {
                 // It would be nice to be able to validate bound vars here, but
                 // projections can actually include bound vars from super traits
@@ -632,21 +629,21 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 match predicate.as_ref().skip_binder() {
                     ty::ExistentialPredicate::Trait(trait_ref) => {
                         // Use a type that can't appear in defaults of type parameters.
-                        let dummy_self = Ty::new_fresh(cx.tcx, 0);
-                        let trait_ref = trait_ref.with_self_ty(cx.tcx, dummy_self);
-                        cx.print_def_path(trait_ref.def_id, trait_ref.args)?;
+                        let dummy_self = Ty::new_fresh(p.tcx, 0);
+                        let trait_ref = trait_ref.with_self_ty(p.tcx, dummy_self);
+                        p.print_def_path(trait_ref.def_id, trait_ref.args)?;
                     }
                     ty::ExistentialPredicate::Projection(projection) => {
-                        let name = cx.tcx.associated_item(projection.def_id).name();
-                        cx.push("p");
-                        cx.push_ident(name.as_str());
+                        let name = p.tcx.associated_item(projection.def_id).name();
+                        p.push("p");
+                        p.push_ident(name.as_str());
                         match projection.term.kind() {
-                            ty::TermKind::Ty(ty) => ty.print(cx),
-                            ty::TermKind::Const(c) => c.print(cx),
+                            ty::TermKind::Ty(ty) => ty.print(p),
+                            ty::TermKind::Const(c) => c.print(p),
                         }?;
                     }
                     ty::ExistentialPredicate::AutoTrait(def_id) => {
-                        cx.print_def_path(*def_id, &[])?;
+                        p.print_def_path(*def_id, &[])?;
                     }
                 }
             }
@@ -849,7 +846,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
     fn path_append_impl(
         &mut self,
         _: impl FnOnce(&mut Self) -> Result<(), PrintError>,
-        _: &DisambiguatedDefPathData,
         _: Ty<'tcx>,
         _: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError> {
diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
index f7416a7e0fd..1abf0537cda 100644
--- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
@@ -7,7 +7,6 @@ pub(crate) fn target() -> Target {
     // FIXME: HVX length defaults are per-CPU
     base.features = "-small-data,+hvx-length128b".into();
 
-    base.crt_static_default = false;
     base.has_rpath = true;
     base.linker_flavor = LinkerFlavor::Unix(Cc::Yes);
 
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 f95ce756354..94ecd3590a9 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
@@ -23,8 +23,6 @@ pub(crate) fn target() -> Target {
             abi: "abi64".into(),
             endian: Endian::Big,
             mcount: "_mcount".into(),
-            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-            crt_static_default: true,
             llvm_abiname: "n64".into(),
             ..base
         },
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 4dc76f0936c..482b6790dad 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
@@ -10,8 +10,6 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
     base.max_atomic_width = Some(64);
     base.stack_probes = StackProbeType::Inline;
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
     base.abi = "elfv2".into();
     base.llvm_abiname = "elfv2".into();
 
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 316b62d941b..f39142d0101 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
@@ -9,8 +9,6 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
     base.max_atomic_width = Some(32);
     base.stack_probes = StackProbeType::Inline;
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
 
     Target {
         llvm_target: "powerpc-unknown-linux-musl".into(),
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 30d0d9cb60a..8ddb45483b3 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
@@ -9,8 +9,6 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe"]);
     base.max_atomic_width = Some(32);
     base.stack_probes = StackProbeType::Inline;
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
 
     Target {
         llvm_target: "powerpc-unknown-linux-muslspe".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
index 938b39b10c6..eb592cca1c8 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
@@ -23,8 +23,6 @@ pub(crate) fn target() -> Target {
             llvm_abiname: "ilp32d".into(),
             max_atomic_width: Some(32),
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
-            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
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 e9522ac760e..0cdbb626739 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
@@ -13,8 +13,6 @@ pub(crate) fn target() -> Target {
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
 
     Target {
         llvm_target: "s390x-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
index 81c502bfead..e026595439f 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
@@ -27,8 +27,6 @@ pub(crate) fn target() -> Target {
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".into(),
-            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_thread_pool/src/scope/mod.rs b/compiler/rustc_thread_pool/src/scope/mod.rs
index 38230383965..677009a9bc3 100644
--- a/compiler/rustc_thread_pool/src/scope/mod.rs
+++ b/compiler/rustc_thread_pool/src/scope/mod.rs
@@ -501,9 +501,9 @@ impl<'scope> Scope<'scope> {
     /// let mut value_c = None;
     /// rayon::scope(|s| {
     ///     s.spawn(|s1| {
-    ///           // ^ this is the same scope as `s`; this handle `s1`
-    ///           //   is intended for use by the spawned task,
-    ///           //   since scope handles cannot cross thread boundaries.
+    ///         //   ^ this is the same scope as `s`; this handle `s1`
+    ///         //     is intended for use by the spawned task,
+    ///         //     since scope handles cannot cross thread boundaries.
     ///
     ///         value_a = Some(22);
     ///
diff --git a/compiler/rustc_thread_pool/src/sleep/mod.rs b/compiler/rustc_thread_pool/src/sleep/mod.rs
index 31bf7184b42..aa666609214 100644
--- a/compiler/rustc_thread_pool/src/sleep/mod.rs
+++ b/compiler/rustc_thread_pool/src/sleep/mod.rs
@@ -44,7 +44,7 @@ impl SleepData {
 /// jobs are published, and it either blocks threads or wakes them in response to these
 /// events. See the [`README.md`] in this module for more details.
 ///
-/// [`README.md`] README.md
+/// [`README.md`]: README.md
 pub(super) struct Sleep {
     /// One "sleep state" per worker. Used to track if a worker is sleeping and to have
     /// them block.
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index b9acadc406e..ed8229154a9 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -235,28 +235,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
 
             fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
-                Err(fmt::Error)
+                unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
             }
 
             fn print_type(&mut self, _ty: Ty<'tcx>) -> Result<(), PrintError> {
-                Err(fmt::Error)
+                unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
             }
 
             fn print_dyn_existential(
                 &mut self,
                 _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
             ) -> Result<(), PrintError> {
-                Err(fmt::Error)
+                unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
             }
 
             fn print_const(&mut self, _ct: ty::Const<'tcx>) -> Result<(), PrintError> {
-                Err(fmt::Error)
+                unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
             }
 
             fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError> {
                 self.segments = vec![self.tcx.crate_name(cnum)];
                 Ok(())
             }
+
             fn path_qualified(
                 &mut self,
                 _self_ty: Ty<'tcx>,
@@ -268,12 +269,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             fn path_append_impl(
                 &mut self,
                 _print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
-                _disambiguated_data: &DisambiguatedDefPathData,
                 _self_ty: Ty<'tcx>,
                 _trait_ref: Option<ty::TraitRef<'tcx>>,
             ) -> Result<(), PrintError> {
                 Err(fmt::Error)
             }
+
             fn path_append(
                 &mut self,
                 print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
@@ -283,6 +284,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 self.segments.push(disambiguated_data.as_sym(true));
                 Ok(())
             }
+
             fn path_generic_args(
                 &mut self,
                 print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
@@ -298,8 +300,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             // let _ = [{struct Foo; Foo}, {struct Foo; Foo}];
             if did1.krate != did2.krate {
                 let abs_path = |def_id| {
-                    let mut printer = AbsolutePathPrinter { tcx: self.tcx, segments: vec![] };
-                    printer.print_def_path(def_id, &[]).map(|_| printer.segments)
+                    let mut p = AbsolutePathPrinter { tcx: self.tcx, segments: vec![] };
+                    p.print_def_path(def_id, &[]).map(|_| p.segments)
                 };
 
                 // We compare strings because DefPath can be different
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index 022d549a9df..966f117a1bf 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -244,7 +244,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'a, 'tcx> {
 }
 
 fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
-    let mut printer = FmtPrinter::new(infcx.tcx, ns);
+    let mut p = FmtPrinter::new(infcx.tcx, ns);
     let ty_getter = move |ty_vid| {
         if infcx.probe_ty_var(ty_vid).is_ok() {
             warn!("resolved ty var in error message");
@@ -270,11 +270,11 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
             None
         }
     };
-    printer.ty_infer_name_resolver = Some(Box::new(ty_getter));
+    p.ty_infer_name_resolver = Some(Box::new(ty_getter));
     let const_getter =
         move |ct_vid| Some(infcx.tcx.item_name(infcx.const_var_origin(ct_vid)?.param_def_id?));
-    printer.const_infer_name_resolver = Some(Box::new(const_getter));
-    printer
+    p.const_infer_name_resolver = Some(Box::new(const_getter));
+    p
 }
 
 fn ty_to_string<'tcx>(
@@ -282,7 +282,7 @@ fn ty_to_string<'tcx>(
     ty: Ty<'tcx>,
     called_method_def_id: Option<DefId>,
 ) -> String {
-    let mut printer = fmt_printer(infcx, Namespace::TypeNS);
+    let mut p = fmt_printer(infcx, Namespace::TypeNS);
     let ty = infcx.resolve_vars_if_possible(ty);
     // We use `fn` ptr syntax for closures, but this only works when the closure does not capture
     // anything. We also remove all type parameters that are fully known to the type system.
@@ -292,8 +292,8 @@ fn ty_to_string<'tcx>(
         // We don't want the regular output for `fn`s because it includes its path in
         // invalid pseudo-syntax, we want the `fn`-pointer output instead.
         (ty::FnDef(..), _) => {
-            ty.fn_sig(infcx.tcx).print(&mut printer).unwrap();
-            printer.into_buffer()
+            ty.fn_sig(infcx.tcx).print(&mut p).unwrap();
+            p.into_buffer()
         }
         (_, Some(def_id))
             if ty.is_ty_or_numeric_infer()
@@ -303,8 +303,8 @@ fn ty_to_string<'tcx>(
         }
         _ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(),
         _ => {
-            ty.print(&mut printer).unwrap();
-            printer.into_buffer()
+            ty.print(&mut p).unwrap();
+            p.into_buffer()
         }
     }
 }
@@ -561,21 +561,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 {
                     "Vec<_>".to_string()
                 } else {
-                    let mut printer = fmt_printer(self, Namespace::TypeNS);
-                    printer
-                        .comma_sep(generic_args.iter().copied().map(|arg| {
-                            if arg.is_suggestable(self.tcx, true) {
-                                return arg;
-                            }
+                    let mut p = fmt_printer(self, Namespace::TypeNS);
+                    p.comma_sep(generic_args.iter().copied().map(|arg| {
+                        if arg.is_suggestable(self.tcx, true) {
+                            return arg;
+                        }
 
-                            match arg.kind() {
-                                GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
-                                GenericArgKind::Type(_) => self.next_ty_var(DUMMY_SP).into(),
-                                GenericArgKind::Const(_) => self.next_const_var(DUMMY_SP).into(),
-                            }
-                        }))
-                        .unwrap();
-                    printer.into_buffer()
+                        match arg.kind() {
+                            GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
+                            GenericArgKind::Type(_) => self.next_ty_var(DUMMY_SP).into(),
+                            GenericArgKind::Const(_) => self.next_const_var(DUMMY_SP).into(),
+                        }
+                    }))
+                    .unwrap();
+                    p.into_buffer()
                 };
 
                 if !have_turbofish {
@@ -589,9 +588,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
                 let placeholder = Some(self.next_ty_var(DUMMY_SP));
                 if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) {
-                    let mut printer = fmt_printer(self, Namespace::ValueNS);
-                    printer.print_def_path(def_id, args).unwrap();
-                    let def_path = printer.into_buffer();
+                    let mut p = fmt_printer(self, Namespace::ValueNS);
+                    p.print_def_path(def_id, args).unwrap();
+                    let def_path = p.into_buffer();
 
                     // We only care about whether we have to add `&` or `&mut ` for now.
                     // This is the case if the last adjustment is a borrow and the
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs
index 64fc365c44a..373b756dcdb 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs
@@ -47,11 +47,11 @@ where
     T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let mut printer = ty::print::FmtPrinter::new(self.tcx, self.ns);
-        printer.region_highlight_mode = self.highlight;
+        let mut p = ty::print::FmtPrinter::new(self.tcx, self.ns);
+        p.region_highlight_mode = self.highlight;
 
-        self.value.print(&mut printer)?;
-        f.write_str(&printer.into_buffer())
+        self.value.print(&mut p)?;
+        f.write_str(&p.into_buffer())
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
index 8e0620f2048..129d0963a75 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -946,8 +946,8 @@ fn foo(&self) -> Self::T { String::new() }
     }
 
     pub fn format_generic_args(&self, args: &[ty::GenericArg<'tcx>]) -> String {
-        FmtPrinter::print_string(self.tcx, hir::def::Namespace::TypeNS, |cx| {
-            cx.path_generic_args(|_| Ok(()), args)
+        FmtPrinter::print_string(self.tcx, hir::def::Namespace::TypeNS, |p| {
+            p.path_generic_args(|_| Ok(()), args)
         })
         .expect("could not write to `String`.")
     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index f3441a8d72a..7369134420c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -581,7 +581,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         let trait_args = trait_ref
             .instantiate_identity()
             // Replace the explicit self type with `Self` for better suggestion rendering
-            .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
+            .with_replaced_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
             .args;
         let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
             .rebase_onto(self.tcx, impl_def_id, trait_args);
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 1ac309da101..a9e346a5cdb 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
@@ -512,7 +512,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             && self.fallback_has_occurred
                         {
                             let predicate = leaf_trait_predicate.map_bound(|trait_pred| {
-                                trait_pred.with_self_ty(self.tcx, tcx.types.unit)
+                                trait_pred.with_replaced_self_ty(self.tcx, tcx.types.unit)
                             });
                             let unit_obligation = obligation.with(tcx, predicate);
                             if self.predicate_may_hold(&unit_obligation) {
@@ -2364,8 +2364,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
     ) -> PredicateObligation<'tcx> {
-        let trait_pred =
-            trait_ref_and_ty.map_bound(|(tr, new_self_ty)| tr.with_self_ty(self.tcx, new_self_ty));
+        let trait_pred = trait_ref_and_ty
+            .map_bound(|(tr, new_self_ty)| tr.with_replaced_self_ty(self.tcx, new_self_ty));
 
         Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred)
     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
index d929ecf68bf..4f1f5c330e5 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
@@ -66,10 +66,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             if s.len() > 50 {
                 // We don't need to save the type to a file, we will be talking about this type already
                 // in a separate note when we explain the obligation, so it will be available that way.
-                let mut cx: FmtPrinter<'_, '_> =
+                let mut p: FmtPrinter<'_, '_> =
                     FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, rustc_session::Limit(6));
-                value.print(&mut cx).unwrap();
-                cx.into_buffer()
+                value.print(&mut p).unwrap();
+                p.into_buffer()
             } else {
                 s
             }
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 c182fd99b17..718cff6d135 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3942,7 +3942,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             if let hir::Expr { kind: hir::ExprKind::MethodCall(_, rcvr, _, _), .. } = expr
                 && let Some(ty) = typeck_results.node_type_opt(rcvr.hir_id)
                 && let Some(failed_pred) = failed_pred.as_trait_clause()
-                && let pred = failed_pred.map_bound(|pred| pred.with_self_ty(tcx, ty))
+                && let pred = failed_pred.map_bound(|pred| pred.with_replaced_self_ty(tcx, ty))
                 && self.predicate_must_hold_modulo_regions(&Obligation::misc(
                     tcx, expr.span, body_id, param_env, pred,
                 ))
@@ -4624,9 +4624,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         let Some(root_pred) = root_obligation.predicate.as_trait_clause() else { return };
 
         let trait_ref = root_pred.map_bound(|root_pred| {
-            root_pred
-                .trait_ref
-                .with_self_ty(self.tcx, Ty::new_tup(self.tcx, &[root_pred.trait_ref.self_ty()]))
+            root_pred.trait_ref.with_replaced_self_ty(
+                self.tcx,
+                Ty::new_tup(self.tcx, &[root_pred.trait_ref.self_ty()]),
+            )
         });
 
         let obligation =
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 01bdae7435d..3f628d80662 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -355,7 +355,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
             return ControlFlow::Continue(());
         }
 
-        if let ty::CoroutineWitness(def_id, _) = *ty.kind()
+        if let ty::Coroutine(def_id, _) = *ty.kind()
             && def_id.as_local().is_some_and(|def_id| self.stalled_coroutines.contains(&def_id))
         {
             ControlFlow::Break(())
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 517333d1561..39afd77a8b6 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -548,7 +548,10 @@ fn plug_infer_with_placeholders<'tcx>(
                         ct,
                         ty::Const::new_placeholder(
                             self.infcx.tcx,
-                            ty::Placeholder { universe: self.universe, bound: self.next_var() },
+                            ty::Placeholder {
+                                universe: self.universe,
+                                bound: ty::BoundConst { var: self.next_var() },
+                            },
                         ),
                     )
                 else {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 9b5e59ce0fd..08315dbd21f 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -706,7 +706,10 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
                 self.idx += 1;
                 ty::Const::new_placeholder(
                     self.tcx,
-                    ty::PlaceholderConst { universe: ty::UniverseIndex::ROOT, bound: idx },
+                    ty::PlaceholderConst {
+                        universe: ty::UniverseIndex::ROOT,
+                        bound: ty::BoundConst { var: idx },
+                    },
                 )
             } else {
                 c.super_fold_with(self)
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 38cfdcdc22d..b1b331d1b61 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -318,7 +318,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             })
         }
 
-        ty::Coroutine(_, args) => {
+        ty::Coroutine(def_id, args) => {
             // rust-lang/rust#49918: types can be constructed, stored
             // in the interior, and sit idle when coroutine yields
             // (and is subsequently dropped).
@@ -346,7 +346,10 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             // While we conservatively assume that all coroutines require drop
             // to avoid query cycles during MIR building, we can check the actual
             // witness during borrowck to avoid unnecessary liveness constraints.
-            if args.witness().needs_drop(tcx, tcx.erase_regions(typing_env)) {
+            let typing_env = tcx.erase_regions(typing_env);
+            if tcx.mir_coroutine_witnesses(def_id).is_some_and(|witness| {
+                witness.field_tys.iter().any(|field| field.ty.needs_drop(tcx, typing_env))
+            }) {
                 constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from));
                 constraints.outlives.push(args.resume_ty().into());
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 2c7089507a8..62795c8a3a6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -794,18 +794,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     // The auto impl might apply; we don't know.
                     candidates.ambiguous = true;
                 }
-                ty::Coroutine(coroutine_def_id, _)
-                    if self.tcx().is_lang_item(def_id, LangItem::Unpin) =>
-                {
-                    match self.tcx().coroutine_movability(coroutine_def_id) {
-                        hir::Movability::Static => {
-                            // Immovable coroutines are never `Unpin`, so
-                            // suppress the normal auto-impl candidate for it.
+                ty::Coroutine(coroutine_def_id, _) => {
+                    if self.tcx().is_lang_item(def_id, LangItem::Unpin) {
+                        match self.tcx().coroutine_movability(coroutine_def_id) {
+                            hir::Movability::Static => {
+                                // Immovable coroutines are never `Unpin`, so
+                                // suppress the normal auto-impl candidate for it.
+                            }
+                            hir::Movability::Movable => {
+                                // Movable coroutines are always `Unpin`, so add an
+                                // unconditional builtin candidate with no sub-obligations.
+                                candidates.vec.push(BuiltinCandidate);
+                            }
                         }
-                        hir::Movability::Movable => {
-                            // Movable coroutines are always `Unpin`, so add an
-                            // unconditional builtin candidate.
-                            candidates.vec.push(BuiltinCandidate);
+                    } else {
+                        if self.should_stall_coroutine(coroutine_def_id) {
+                            candidates.ambiguous = true;
+                        } else {
+                            // Coroutines implement all other auto traits normally.
+                            candidates.vec.push(AutoImplCandidate);
                         }
                     }
                 }
@@ -842,12 +849,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     }
                 }
 
-                ty::CoroutineWitness(def_id, _) => {
-                    if self.should_stall_coroutine_witness(def_id) {
-                        candidates.ambiguous = true;
-                    } else {
-                        candidates.vec.push(AutoImplCandidate);
-                    }
+                ty::CoroutineWitness(..) => {
+                    candidates.vec.push(AutoImplCandidate);
                 }
 
                 ty::Bool
@@ -866,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | ty::FnPtr(..)
                 | ty::Closure(..)
                 | ty::CoroutineClosure(..)
-                | ty::Coroutine(..)
                 | ty::Never
                 | ty::Tuple(_)
                 | ty::UnsafeBinder(_) => {
@@ -1153,15 +1155,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::Ref(_, _, hir::Mutability::Mut) => {}
 
             ty::Coroutine(coroutine_def_id, args) => {
+                if self.should_stall_coroutine(coroutine_def_id) {
+                    candidates.ambiguous = true;
+                    return;
+                }
+
                 match self.tcx().coroutine_movability(coroutine_def_id) {
                     hir::Movability::Static => {}
                     hir::Movability::Movable => {
                         if self.tcx().features().coroutine_clone() {
                             let resolved_upvars =
                                 self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
-                            let resolved_witness =
-                                self.infcx.shallow_resolve(args.as_coroutine().witness());
-                            if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
+                            if resolved_upvars.is_ty_var() {
                                 // Not yet resolved.
                                 candidates.ambiguous = true;
                             } else {
@@ -1194,12 +1199,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
             }
 
-            ty::CoroutineWitness(coroutine_def_id, _) => {
-                if self.should_stall_coroutine_witness(coroutine_def_id) {
-                    candidates.ambiguous = true;
-                } else {
-                    candidates.vec.push(SizedCandidate);
-                }
+            ty::CoroutineWitness(..) => {
+                candidates.vec.push(SizedCandidate);
             }
 
             // Fallback to whatever user-defined impls or param-env clauses exist in this case.
@@ -1238,7 +1239,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::RawPtr(..)
             | ty::Char
             | ty::Ref(..)
-            | ty::Coroutine(..)
             | ty::Array(..)
             | ty::Closure(..)
             | ty::CoroutineClosure(..)
@@ -1247,14 +1247,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 candidates.vec.push(SizedCandidate);
             }
 
-            ty::CoroutineWitness(coroutine_def_id, _) => {
-                if self.should_stall_coroutine_witness(coroutine_def_id) {
+            ty::Coroutine(coroutine_def_id, _) => {
+                if self.should_stall_coroutine(coroutine_def_id) {
                     candidates.ambiguous = true;
                 } else {
                     candidates.vec.push(SizedCandidate);
                 }
             }
 
+            ty::CoroutineWitness(..) => {
+                candidates.vec.push(SizedCandidate);
+            }
+
             // Conditionally `Sized`.
             ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
                 candidates.vec.push(SizedCandidate);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index d7c3543cb3f..7ea1548f8f2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2196,7 +2196,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                                 args.as_coroutine()
                                     .upvar_tys()
                                     .iter()
-                                    .chain([args.as_coroutine().witness()])
+                                    .chain([Ty::new_coroutine_witness(
+                                        self.tcx(),
+                                        coroutine_def_id,
+                                        self.tcx().mk_args(args.as_coroutine().parent_args()),
+                                    )])
                                     .collect::<Vec<_>>(),
                             )
                         } else {
@@ -2327,9 +2331,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 ty::Binder::dummy(AutoImplConstituents { types: vec![ty], assumptions: vec![] })
             }
 
-            ty::Coroutine(_, args) => {
+            ty::Coroutine(def_id, args) => {
                 let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
-                let witness = args.as_coroutine().witness();
+                let witness = Ty::new_coroutine_witness(
+                    self.tcx(),
+                    def_id,
+                    self.tcx().mk_args(args.as_coroutine().parent_args()),
+                );
                 ty::Binder::dummy(AutoImplConstituents {
                     types: [ty].into_iter().chain(iter::once(witness)).collect(),
                     assumptions: vec![],
@@ -2841,7 +2849,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         obligations
     }
 
-    fn should_stall_coroutine_witness(&self, def_id: DefId) -> bool {
+    fn should_stall_coroutine(&self, def_id: DefId) -> bool {
         match self.infcx.typing_mode() {
             TypingMode::Analysis { defining_opaque_types_and_generators: stalled_generators } => {
                 def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index c3d60ec45c4..83c0969762f 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -222,7 +222,7 @@ pub struct PlaceholderReplacer<'a, 'tcx> {
     infcx: &'a InferCtxt<'tcx>,
     mapped_regions: FxIndexMap<ty::PlaceholderRegion, ty::BoundRegion>,
     mapped_types: FxIndexMap<ty::PlaceholderType, ty::BoundTy>,
-    mapped_consts: FxIndexMap<ty::PlaceholderConst, ty::BoundVar>,
+    mapped_consts: FxIndexMap<ty::PlaceholderConst, ty::BoundConst>,
     universe_indices: &'a [Option<ty::UniverseIndex>],
     current_index: ty::DebruijnIndex,
 }
@@ -232,7 +232,7 @@ impl<'a, 'tcx> PlaceholderReplacer<'a, 'tcx> {
         infcx: &'a InferCtxt<'tcx>,
         mapped_regions: FxIndexMap<ty::PlaceholderRegion, ty::BoundRegion>,
         mapped_types: FxIndexMap<ty::PlaceholderType, ty::BoundTy>,
-        mapped_consts: FxIndexMap<ty::PlaceholderConst, ty::BoundVar>,
+        mapped_consts: FxIndexMap<ty::PlaceholderConst, ty::BoundConst>,
         universe_indices: &'a [Option<ty::UniverseIndex>],
         value: T,
     ) -> T {
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index c3b04c20f4b..13d56889bd1 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -101,9 +101,6 @@ fn has_significant_drop_raw<'tcx>(
 struct NeedsDropTypes<'tcx, F> {
     tcx: TyCtxt<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
-    /// Whether to reveal coroutine witnesses, this is set
-    /// to `false` unless we compute `needs_drop` for a coroutine witness.
-    reveal_coroutine_witnesses: bool,
     query_ty: Ty<'tcx>,
     seen_tys: FxHashSet<Ty<'tcx>>,
     /// A stack of types left to process, and the recursion depth when we
@@ -115,6 +112,15 @@ struct NeedsDropTypes<'tcx, F> {
     adt_components: F,
     /// Set this to true if an exhaustive list of types involved in
     /// drop obligation is requested.
+    // FIXME: Calling this bool `exhaustive` is confusing and possibly a footgun,
+    // since it does two things: It makes the iterator yield *all* of the types
+    // that need drop, and it also affects the computation of the drop components
+    // on `Coroutine`s. The latter is somewhat confusing, and probably should be
+    // a function of `typing_env`. See the HACK comment below for why this is
+    // necessary. If this isn't possible, then we probably should turn this into
+    // a `NeedsDropMode` so that we can have a variant like `CollectAllSignificantDrops`,
+    // which will more accurately indicate that we want *all* of the *significant*
+    // drops, which are the two important behavioral changes toggled by this bool.
     exhaustive: bool,
 }
 
@@ -131,7 +137,6 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
         Self {
             tcx,
             typing_env,
-            reveal_coroutine_witnesses: exhaustive,
             seen_tys,
             query_ty: ty,
             unchecked_tys: vec![(ty, 0)],
@@ -195,23 +200,27 @@ where
                     // for the coroutine witness and check whether any of the contained types
                     // need to be dropped, and only require the captured types to be live
                     // if they do.
-                    ty::Coroutine(_, args) => {
-                        if self.reveal_coroutine_witnesses {
-                            queue_type(self, args.as_coroutine().witness());
+                    ty::Coroutine(def_id, args) => {
+                        // FIXME: See FIXME on `exhaustive` field above.
+                        if self.exhaustive {
+                            for upvar in args.as_coroutine().upvar_tys() {
+                                queue_type(self, upvar);
+                            }
+                            queue_type(self, args.as_coroutine().resume_ty());
+                            if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
+                                for field_ty in &witness.field_tys {
+                                    queue_type(
+                                        self,
+                                        EarlyBinder::bind(field_ty.ty).instantiate(tcx, args),
+                                    );
+                                }
+                            }
                         } else {
                             return Some(self.always_drop_component(ty));
                         }
                     }
-                    ty::CoroutineWitness(def_id, args) => {
-                        if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
-                            self.reveal_coroutine_witnesses = true;
-                            for field_ty in &witness.field_tys {
-                                queue_type(
-                                    self,
-                                    EarlyBinder::bind(field_ty.ty).instantiate(tcx, args),
-                                );
-                            }
-                        }
+                    ty::CoroutineWitness(..) => {
+                        unreachable!("witness should be handled in parent");
                     }
 
                     ty::UnsafeBinder(bound_ty) => {
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
index a7b915c4845..189afa32852 100644
--- a/compiler/rustc_type_ir/src/binder.rs
+++ b/compiler/rustc_type_ir/src/binder.rs
@@ -274,8 +274,9 @@ impl<I: Interner, T: IntoIterator> Binder<I, T> {
 pub struct ValidateBoundVars<I: Interner> {
     bound_vars: I::BoundVarKinds,
     binder_index: ty::DebruijnIndex,
-    // We may encounter the same variable at different levels of binding, so
-    // this can't just be `Ty`
+    // We only cache types because any complex const will have to step through
+    // a type at some point anyways. We may encounter the same variable at
+    // different levels of binding, so this can't just be `Ty`.
     visited: SsoHashSet<(ty::DebruijnIndex, I::Ty)>,
 }
 
@@ -319,6 +320,24 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
         t.super_visit_with(self)
     }
 
+    fn visit_const(&mut self, c: I::Const) -> Self::Result {
+        if c.outer_exclusive_binder() < self.binder_index {
+            return ControlFlow::Break(());
+        }
+        match c.kind() {
+            ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.binder_index => {
+                let idx = bound_const.var().as_usize();
+                if self.bound_vars.len() <= idx {
+                    panic!("Not enough bound vars: {:?} not found in {:?}", c, self.bound_vars);
+                }
+                bound_const.assert_eq(self.bound_vars.get(idx).unwrap());
+            }
+            _ => {}
+        };
+
+        c.super_visit_with(self)
+    }
+
     fn visit_region(&mut self, r: I::Region) -> Self::Result {
         match r.kind() {
             ty::ReBound(index, br) if index == self.binder_index => {
@@ -357,7 +376,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
 pub struct EarlyBinder<I: Interner, T> {
     value: T,
     #[derive_where(skip(Debug))]
-    _tcx: PhantomData<I>,
+    _tcx: PhantomData<fn() -> I>,
 }
 
 /// For early binders, you should first call `instantiate` before using any visitors.
diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs
index d7b9e0ca340..23b7f55fbbe 100644
--- a/compiler/rustc_type_ir/src/flags.rs
+++ b/compiler/rustc_type_ir/src/flags.rs
@@ -131,10 +131,7 @@ bitflags::bitflags! {
         /// Does this have any binders with bound vars (e.g. that need to be anonymized)?
         const HAS_BINDER_VARS             = 1 << 23;
 
-        /// Does this type have any coroutine witnesses in it?
-        // FIXME: This should probably be changed to track whether the type has any
-        // *coroutines* in it, though this will happen if we remove coroutine witnesses
-        // altogether.
+        /// Does this type have any coroutines in it?
         const HAS_TY_CORO                 = 1 << 24;
     }
 }
@@ -246,11 +243,13 @@ impl<I: Interner> FlagComputation<I> {
                 self.add_flags(TypeFlags::HAS_TY_PARAM);
             }
 
-            ty::Closure(_, args) | ty::Coroutine(_, args) | ty::CoroutineClosure(_, args) => {
+            ty::Closure(_, args)
+            | ty::CoroutineClosure(_, args)
+            | ty::CoroutineWitness(_, args) => {
                 self.add_args(args.as_slice());
             }
 
-            ty::CoroutineWitness(_, args) => {
+            ty::Coroutine(_, args) => {
                 self.add_flags(TypeFlags::HAS_TY_CORO);
                 self.add_args(args.as_slice());
             }
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 0e307e15d5b..1a6c99ce7de 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -251,7 +251,7 @@ pub trait Const<I: Interner<Const = Self>>:
 
     fn new_var(interner: I, var: ty::ConstVid) -> Self;
 
-    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundConst) -> Self;
+    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, bound_const: I::BoundConst) -> Self;
 
     fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
 
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index ad1a7a633e4..50b588029ae 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -387,16 +387,6 @@ rustc_index::newtype_index! {
     pub struct BoundVar {}
 }
 
-impl<I: Interner> inherent::BoundVarLike<I> for BoundVar {
-    fn var(self) -> BoundVar {
-        self
-    }
-
-    fn assert_eq(self, _var: I::BoundVarKind) {
-        unreachable!("FIXME: We really should have a separate `BoundConst` for consts")
-    }
-}
-
 /// Represents the various closure traits in the language. This
 /// will determine the type of the environment (`self`, in the
 /// desugaring) argument that the closure expects.
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index 4643cd0ab85..c9489c98cce 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -97,7 +97,7 @@ impl<I: Interner> TraitRef<I> {
         )
     }
 
-    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
+    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
         TraitRef::new(
             interner,
             self.def_id,
@@ -146,8 +146,11 @@ pub struct TraitPredicate<I: Interner> {
 }
 
 impl<I: Interner> TraitPredicate<I> {
-    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
-        Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity }
+    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
+        Self {
+            trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty),
+            polarity: self.polarity,
+        }
     }
 
     pub fn def_id(self) -> I::DefId {
@@ -645,7 +648,7 @@ impl<I: Interner> AliasTerm<I> {
         self.args.type_at(0)
     }
 
-    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
+    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
         AliasTerm::new(
             interner,
             self.def_id,
@@ -756,8 +759,11 @@ impl<I: Interner> ProjectionPredicate<I> {
         self.projection_term.self_ty()
     }
 
-    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
-        Self { projection_term: self.projection_term.with_self_ty(interner, self_ty), ..self }
+    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
+        Self {
+            projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty),
+            ..self
+        }
     }
 
     pub fn trait_def_id(self, interner: I) -> I::DefId {
@@ -814,8 +820,8 @@ impl<I: Interner> NormalizesTo<I> {
         self.alias.self_ty()
     }
 
-    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
-        Self { alias: self.alias.with_self_ty(interner, self_ty), ..self }
+    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
+        Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self }
     }
 
     pub fn trait_def_id(self, interner: I) -> I::DefId {
@@ -849,8 +855,8 @@ impl<I: Interner> HostEffectPredicate<I> {
         self.trait_ref.self_ty()
     }
 
-    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
-        Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self }
+    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
+        Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self }
     }
 
     pub fn def_id(self) -> I::DefId {
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index d11f1735219..73aeab5092d 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -475,7 +475,7 @@ impl<I: Interner> AliasTy<I> {
         self.args.type_at(0)
     }
 
-    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
+    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
         AliasTy::new(
             interner,
             self.def_id,
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs
index d1ca9bdb7fb..c32f8339d0b 100644
--- a/compiler/rustc_type_ir/src/ty_kind/closure.rs
+++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -101,7 +101,6 @@ use crate::{self as ty, Interner};
 ///   `yield` inside the coroutine.
 /// * `GR`: The "return type", which is the type of value returned upon
 ///   completion of the coroutine.
-/// * `GW`: The "coroutine witness".
 #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
 pub struct ClosureArgs<I: Interner> {
@@ -239,8 +238,6 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
     /// while the `tupled_upvars_ty`, representing the by-move version of the same
     /// captures, will be `(String,)`.
     pub coroutine_captures_by_ref_ty: I::Ty,
-    /// Witness type returned by the generator produced by this coroutine-closure.
-    pub coroutine_witness_ty: I::Ty,
 }
 
 impl<I: Interner> CoroutineClosureArgs<I> {
@@ -251,7 +248,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
                 parts.signature_parts_ty.into(),
                 parts.tupled_upvars_ty.into(),
                 parts.coroutine_captures_by_ref_ty.into(),
-                parts.coroutine_witness_ty.into(),
             ])),
         }
     }
@@ -292,7 +288,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
     }
 
     pub fn coroutine_closure_sig(self) -> ty::Binder<I, CoroutineClosureSignature<I>> {
-        let interior = self.coroutine_witness_ty();
         let ty::FnPtr(sig_tys, hdr) = self.signature_parts_ty().kind() else { panic!() };
         sig_tys.map_bound(|sig_tys| {
             let [resume_ty, tupled_inputs_ty] = *sig_tys.inputs().as_slice() else {
@@ -302,7 +297,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
                 panic!()
             };
             CoroutineClosureSignature {
-                interior,
                 tupled_inputs_ty,
                 resume_ty,
                 yield_ty,
@@ -318,10 +312,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
         self.split().coroutine_captures_by_ref_ty
     }
 
-    pub fn coroutine_witness_ty(self) -> I::Ty {
-        self.split().coroutine_witness_ty
-    }
-
     pub fn has_self_borrows(&self) -> bool {
         match self.coroutine_captures_by_ref_ty().kind() {
             ty::FnPtr(sig_tys, _) => sig_tys
@@ -361,7 +351,6 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
 #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
 pub struct CoroutineClosureSignature<I: Interner> {
-    pub interior: I::Ty,
     pub tupled_inputs_ty: I::Ty,
     pub resume_ty: I::Ty,
     pub yield_ty: I::Ty,
@@ -407,7 +396,6 @@ impl<I: Interner> CoroutineClosureSignature<I> {
                 resume_ty: self.resume_ty,
                 yield_ty: self.yield_ty,
                 return_ty: self.return_ty,
-                witness: self.interior,
                 tupled_upvars_ty,
             },
         );
@@ -587,11 +575,6 @@ pub struct CoroutineArgsParts<I: Interner> {
     pub yield_ty: I::Ty,
     pub return_ty: I::Ty,
 
-    /// The interior type of the coroutine.
-    /// Represents all types that are stored in locals
-    /// in the coroutine's body.
-    pub witness: I::Ty,
-
     /// The upvars captured by the closure. Remains an inference variable
     /// until the upvar analysis, which happens late in HIR typeck.
     pub tupled_upvars_ty: I::Ty,
@@ -607,7 +590,6 @@ impl<I: Interner> CoroutineArgs<I> {
                 parts.resume_ty.into(),
                 parts.yield_ty.into(),
                 parts.return_ty.into(),
-                parts.witness.into(),
                 parts.tupled_upvars_ty.into(),
             ])),
         }
@@ -629,15 +611,6 @@ impl<I: Interner> CoroutineArgs<I> {
         self.split().kind_ty
     }
 
-    /// This describes the types that can be contained in a coroutine.
-    /// It will be a type variable initially and unified in the last stages of typeck of a body.
-    /// It contains a tuple of all the types that could end up on a coroutine frame.
-    /// The state transformation MIR pass may only produce layouts which mention types
-    /// in this tuple. Upvars are not counted here.
-    pub fn witness(self) -> I::Ty {
-        self.split().witness
-    }
-
     /// Returns an iterator over the list of types of captured paths by the coroutine.
     /// In case there was a type error in figuring out the types of the captured path, an
     /// empty iterator is returned.
diff --git a/library/Cargo.lock b/library/Cargo.lock
index a9a611fe1ed..09228825086 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -169,9 +169,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.37.1"
+version = "0.37.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a"
+checksum = "b3e3d0a7419f081f4a808147e845310313a39f322d7ae1f996b7f001d6cbed04"
 dependencies = [
  "memchr",
  "rustc-std-workspace-alloc",
@@ -183,9 +183,8 @@ name = "panic_abort"
 version = "0.0.0"
 dependencies = [
  "alloc",
- "compiler_builtins",
- "core",
  "libc",
+ "rustc-std-workspace-core",
 ]
 
 [[package]]
@@ -194,9 +193,8 @@ version = "0.0.0"
 dependencies = [
  "alloc",
  "cfg-if",
- "compiler_builtins",
- "core",
  "libc",
+ "rustc-std-workspace-core",
  "unwind",
 ]
 
@@ -261,9 +259,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.25"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
+checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -313,7 +311,6 @@ dependencies = [
  "addr2line",
  "alloc",
  "cfg-if",
- "compiler_builtins",
  "core",
  "dlmalloc",
  "fortanix-sgx-abi",
@@ -380,19 +377,17 @@ name = "unwind"
 version = "0.0.0"
 dependencies = [
  "cfg-if",
- "compiler_builtins",
- "core",
  "libc",
+ "rustc-std-workspace-core",
  "unwinding",
 ]
 
 [[package]]
 name = "unwinding"
-version = "0.2.7"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d80f6c2bfede213d9a90b4a14f3eb99b84e33c52df6c1a15de0a100f5a88751"
+checksum = "60612c845ef41699f39dc8c5391f252942c0a88b7d15da672eff0d14101bbd6d"
 dependencies = [
- "compiler_builtins",
  "gimli",
  "rustc-std-workspace-core",
 ]
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index d58240f3051..9eacbf00e42 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -265,12 +265,12 @@ use crate::vec::{self, Vec};
 /// You can look at these with the [`as_ptr`], [`len`], and [`capacity`]
 /// methods:
 ///
+// FIXME Update this when vec_into_raw_parts is stabilized
 /// ```
 /// use std::mem;
 ///
 /// let story = String::from("Once upon a time...");
 ///
-// FIXME Update this when vec_into_raw_parts is stabilized
 /// // Prevent automatically dropping the String's data
 /// let mut story = mem::ManuallyDrop::new(story);
 ///
@@ -970,13 +970,13 @@ impl String {
     ///
     /// # Examples
     ///
+    // FIXME Update this when vec_into_raw_parts is stabilized
     /// ```
     /// use std::mem;
     ///
     /// unsafe {
     ///     let s = String::from("hello");
     ///
-    // FIXME Update this when vec_into_raw_parts is stabilized
     ///     // Prevent automatically dropping the String's data
     ///     let mut s = mem::ManuallyDrop::new(s);
     ///
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index ce74615dbcc..2321aab2c51 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -566,13 +566,13 @@ impl<T> Vec<T> {
     ///
     /// # Examples
     ///
+    // FIXME Update this when vec_into_raw_parts is stabilized
     /// ```
     /// use std::ptr;
     /// use std::mem;
     ///
     /// let v = vec![1, 2, 3];
     ///
-    // FIXME Update this when vec_into_raw_parts is stabilized
     /// // Prevent running `v`'s destructor so we are in complete control
     /// // of the allocation.
     /// let mut v = mem::ManuallyDrop::new(v);
@@ -674,6 +674,7 @@ impl<T> Vec<T> {
     ///
     /// # Examples
     ///
+    // FIXME Update this when vec_into_raw_parts is stabilized
     /// ```
     /// #![feature(box_vec_non_null)]
     ///
@@ -682,7 +683,6 @@ impl<T> Vec<T> {
     ///
     /// let v = vec![1, 2, 3];
     ///
-    // FIXME Update this when vec_into_raw_parts is stabilized
     /// // Prevent running `v`'s destructor so we are in complete control
     /// // of the allocation.
     /// let mut v = mem::ManuallyDrop::new(v);
@@ -994,6 +994,7 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// # Examples
     ///
+    // FIXME Update this when vec_into_raw_parts is stabilized
     /// ```
     /// #![feature(allocator_api)]
     ///
@@ -1007,7 +1008,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// v.push(2);
     /// v.push(3);
     ///
-    // FIXME Update this when vec_into_raw_parts is stabilized
     /// // Prevent running `v`'s destructor so we are in complete control
     /// // of the allocation.
     /// let mut v = mem::ManuallyDrop::new(v);
@@ -1114,6 +1114,7 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// # Examples
     ///
+    // FIXME Update this when vec_into_raw_parts is stabilized
     /// ```
     /// #![feature(allocator_api, box_vec_non_null)]
     ///
@@ -1127,7 +1128,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// v.push(2);
     /// v.push(3);
     ///
-    // FIXME Update this when vec_into_raw_parts is stabilized
     /// // Prevent running `v`'s destructor so we are in complete control
     /// // of the allocation.
     /// let mut v = mem::ManuallyDrop::new(v);
@@ -3872,8 +3872,8 @@ impl<T, A: Allocator> Vec<T, A> {
     /// while i < vec.len() - end_items {
     ///     if some_predicate(&mut vec[i]) {
     ///         let val = vec.remove(i);
-    /// #         extracted.push(val);
     ///         // your code here
+    /// #         extracted.push(val);
     ///     } else {
     ///         i += 1;
     ///     }
diff --git a/library/core/src/array/equality.rs b/library/core/src/array/equality.rs
index bb668d2a673..1ad2cca64a3 100644
--- a/library/core/src/array/equality.rs
+++ b/library/core/src/array/equality.rs
@@ -22,18 +22,16 @@ where
 {
     #[inline]
     fn eq(&self, other: &[U]) -> bool {
-        let b: Result<&[U; N], _> = other.try_into();
-        match b {
-            Ok(b) => *self == *b,
-            Err(_) => false,
+        match other.as_array::<N>() {
+            Some(b) => *self == *b,
+            None => false,
         }
     }
     #[inline]
     fn ne(&self, other: &[U]) -> bool {
-        let b: Result<&[U; N], _> = other.try_into();
-        match b {
-            Ok(b) => *self != *b,
-            Err(_) => true,
+        match other.as_array::<N>() {
+            Some(b) => *self != *b,
+            None => true,
         }
     }
 }
@@ -45,18 +43,16 @@ where
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
-        let b: Result<&[T; N], _> = self.try_into();
-        match b {
-            Ok(b) => *b == *other,
-            Err(_) => false,
+        match self.as_array::<N>() {
+            Some(b) => *b == *other,
+            None => false,
         }
     }
     #[inline]
     fn ne(&self, other: &[U; N]) -> bool {
-        let b: Result<&[T; N], _> = self.try_into();
-        match b {
-            Ok(b) => *b != *other,
-            Err(_) => true,
+        match self.as_array::<N>() {
+            Some(b) => *b != *other,
+            None => true,
         }
     }
 }
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index d6d1bf2effa..d67408cae1b 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -2068,9 +2068,9 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// implies exclusive access to its `T`:
 ///
 /// ```rust
-/// #![forbid(unsafe_code)] // with exclusive accesses,
-///                         // `UnsafeCell` is a transparent no-op wrapper,
-///                         // so no need for `unsafe` here.
+/// #![forbid(unsafe_code)]
+/// // with exclusive accesses, `UnsafeCell` is a transparent no-op wrapper, so no need for
+/// // `unsafe` here.
 /// use std::cell::UnsafeCell;
 ///
 /// let mut x: UnsafeCell<i32> = 42.into();
diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs
index 1758e84ad7c..a1bd4c85717 100644
--- a/library/core/src/cell/lazy.rs
+++ b/library/core/src/cell/lazy.rs
@@ -15,6 +15,22 @@ enum State<T, F> {
 ///
 /// [`std::sync::LazyLock`]: ../../std/sync/struct.LazyLock.html
 ///
+/// # Poisoning
+///
+/// If the initialization closure passed to [`LazyCell::new`] panics, the cell will be poisoned.
+/// Once the cell is poisoned, any threads that attempt to access this cell (via a dereference
+/// or via an explicit call to [`force()`]) will panic.
+///
+/// This concept is similar to that of poisoning in the [`std::sync::poison`] module. A key
+/// difference, however, is that poisoning in `LazyCell` is _unrecoverable_. All future accesses of
+/// the cell from other threads will panic, whereas a type in [`std::sync::poison`] like
+/// [`std::sync::poison::Mutex`] allows recovery via [`PoisonError::into_inner()`].
+///
+/// [`force()`]: LazyCell::force
+/// [`std::sync::poison`]: ../../std/sync/poison/index.html
+/// [`std::sync::poison::Mutex`]: ../../std/sync/poison/struct.Mutex.html
+/// [`PoisonError::into_inner()`]: ../../std/sync/poison/struct.PoisonError.html#method.into_inner
+///
 /// # Examples
 ///
 /// ```
@@ -64,6 +80,10 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
     ///
     /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
     ///
+    /// # Panics
+    ///
+    /// Panics if the cell is poisoned.
+    ///
     /// # Examples
     ///
     /// ```
@@ -93,6 +113,15 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
     ///
     /// This is equivalent to the `Deref` impl, but is explicit.
     ///
+    /// # Panics
+    ///
+    /// If the initialization closure panics (the one that is passed to the [`new()`] method), the
+    /// panic is propagated to the caller, and the cell becomes poisoned. This will cause all future
+    /// accesses of the cell (via [`force()`] or a dereference) to panic.
+    ///
+    /// [`new()`]: LazyCell::new
+    /// [`force()`]: LazyCell::force
+    ///
     /// # Examples
     ///
     /// ```
@@ -123,6 +152,15 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
     /// Forces the evaluation of this lazy value and returns a mutable reference to
     /// the result.
     ///
+    /// # Panics
+    ///
+    /// If the initialization closure panics (the one that is passed to the [`new()`] method), the
+    /// panic is propagated to the caller, and the cell becomes poisoned. This will cause all future
+    /// accesses of the cell (via [`force()`] or a dereference) to panic.
+    ///
+    /// [`new()`]: LazyCell::new
+    /// [`force()`]: LazyCell::force
+    ///
     /// # Examples
     ///
     /// ```
@@ -219,7 +257,8 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
 }
 
 impl<T, F> LazyCell<T, F> {
-    /// Returns a mutable reference to the value if initialized, or `None` if not.
+    /// Returns a mutable reference to the value if initialized. Otherwise (if uninitialized or
+    /// poisoned), returns `None`.
     ///
     /// # Examples
     ///
@@ -245,7 +284,8 @@ impl<T, F> LazyCell<T, F> {
         }
     }
 
-    /// Returns a reference to the value if initialized, or `None` if not.
+    /// Returns a reference to the value if initialized. Otherwise (if uninitialized or poisoned),
+    /// returns `None`.
     ///
     /// # Examples
     ///
@@ -278,6 +318,15 @@ impl<T, F> LazyCell<T, F> {
 #[stable(feature = "lazy_cell", since = "1.80.0")]
 impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
     type Target = T;
+
+    /// # Panics
+    ///
+    /// If the initialization closure panics (the one that is passed to the [`new()`] method), the
+    /// panic is propagated to the caller, and the cell becomes poisoned. This will cause all future
+    /// accesses of the cell (via [`force()`] or a dereference) to panic.
+    ///
+    /// [`new()`]: LazyCell::new
+    /// [`force()`]: LazyCell::force
     #[inline]
     fn deref(&self) -> &T {
         LazyCell::force(self)
@@ -286,6 +335,14 @@ impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
 
 #[stable(feature = "lazy_deref_mut", since = "1.89.0")]
 impl<T, F: FnOnce() -> T> DerefMut for LazyCell<T, F> {
+    /// # Panics
+    ///
+    /// If the initialization closure panics (the one that is passed to the [`new()`] method), the
+    /// panic is propagated to the caller, and the cell becomes poisoned. This will cause all future
+    /// accesses of the cell (via [`force()`] or a dereference) to panic.
+    ///
+    /// [`new()`]: LazyCell::new
+    /// [`force()`]: LazyCell::force
     #[inline]
     fn deref_mut(&mut self) -> &mut T {
         LazyCell::force_mut(self)
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 696d323c66d..c72eeb9a9c9 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -649,8 +649,6 @@ pub const fn must_use<T>(value: T) -> T {
 ///     }
 /// }
 /// ```
-///
-///
 #[unstable(feature = "likely_unlikely", issue = "136873")]
 #[inline(always)]
 pub const fn likely(b: bool) -> bool {
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 7ca41d224a0..56ca1305b60 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -233,10 +233,12 @@
 //!
 //! ```
 //! let mut values = vec![41];
-//! for x in &mut values { // same as `values.iter_mut()`
+//! for x in &mut values {
+//!     //   ^ same as `values.iter_mut()`
 //!     *x += 1;
 //! }
-//! for x in &values { // same as `values.iter()`
+//! for x in &values {
+//!     //   ^ same as `values.iter()`
 //!     assert_eq!(*x, 42);
 //! }
 //! assert_eq!(values.len(), 1);
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 10f9d464f7d..29313867ff2 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -807,7 +807,7 @@ pub trait Iterator {
     /// might be preferable to keep a functional style with longer iterators:
     ///
     /// ```
-    /// (0..5).flat_map(|x| x * 100 .. x * 110)
+    /// (0..5).flat_map(|x| (x * 100)..(x * 110))
     ///       .enumerate()
     ///       .filter(|&(i, x)| (i + x) % 3 == 0)
     ///       .for_each(|(i, x)| println!("{i}:{x}"));
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 3d57da63683..c59290a757b 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -271,7 +271,10 @@ pub macro cfg_select($($tt:tt)*) {
 /// // expression given.
 /// debug_assert!(true);
 ///
-/// fn some_expensive_computation() -> bool { true } // a very simple function
+/// fn some_expensive_computation() -> bool {
+///     // Some expensive computation here
+///     true
+/// }
 /// debug_assert!(some_expensive_computation());
 ///
 /// // assert with a custom message
@@ -1547,7 +1550,10 @@ pub(crate) mod builtin {
     /// // expression given.
     /// assert!(true);
     ///
-    /// fn some_computation() -> bool { true } // a very simple function
+    /// fn some_computation() -> bool {
+    ///     // Some expensive computation here
+    ///     true
+    /// }
     ///
     /// assert!(some_computation());
     ///
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 45277a1c82d..ba00ee17b65 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -138,8 +138,7 @@ unsafe impl<T: Sync + PointeeSized> Send for &T {}
 /// impl Bar for Impl { }
 ///
 /// let x: &dyn Foo = &Impl;    // OK
-/// // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot
-///                             // be made into an object
+/// // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot be made into an object
 /// ```
 ///
 /// [trait object]: ../../book/ch17-02-trait-objects.html
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 34d8370da7e..c160360cfac 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -773,8 +773,7 @@ impl<T> MaybeUninit<T> {
     /// // Initialize the `MaybeUninit` using `Cell::set`:
     /// unsafe {
     ///     b.assume_init_ref().set(true);
-    ///    // ^^^^^^^^^^^^^^^
-    ///    // Reference to an uninitialized `Cell<bool>`: UB!
+    ///     //^^^^^^^^^^^^^^^ Reference to an uninitialized `Cell<bool>`: UB!
     /// }
     /// ```
     #[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
@@ -864,9 +863,9 @@ impl<T> MaybeUninit<T> {
     /// {
     ///     let mut buffer = MaybeUninit::<[u8; 64]>::uninit();
     ///     reader.read_exact(unsafe { buffer.assume_init_mut() })?;
-    ///                             // ^^^^^^^^^^^^^^^^^^^^^^^^
-    ///                             // (mutable) reference to uninitialized memory!
-    ///                             // This is undefined behavior.
+    ///     //                         ^^^^^^^^^^^^^^^^^^^^^^^^
+    ///     // (mutable) reference to uninitialized memory!
+    ///     // This is undefined behavior.
     ///     Ok(unsafe { buffer.assume_init() })
     /// }
     /// ```
@@ -884,13 +883,13 @@ impl<T> MaybeUninit<T> {
     /// let foo: Foo = unsafe {
     ///     let mut foo = MaybeUninit::<Foo>::uninit();
     ///     ptr::write(&mut foo.assume_init_mut().a as *mut u32, 1337);
-    ///                  // ^^^^^^^^^^^^^^^^^^^^^
-    ///                  // (mutable) reference to uninitialized memory!
-    ///                  // This is undefined behavior.
+    ///     //              ^^^^^^^^^^^^^^^^^^^^^
+    ///     // (mutable) reference to uninitialized memory!
+    ///     // This is undefined behavior.
     ///     ptr::write(&mut foo.assume_init_mut().b as *mut u8, 42);
-    ///                  // ^^^^^^^^^^^^^^^^^^^^^
-    ///                  // (mutable) reference to uninitialized memory!
-    ///                  // This is undefined behavior.
+    ///     //              ^^^^^^^^^^^^^^^^^^^^^
+    ///     // (mutable) reference to uninitialized memory!
+    ///     // This is undefined behavior.
     ///     foo.assume_init()
     /// };
     /// ```
diff --git a/library/core/src/num/niche_types.rs b/library/core/src/num/niche_types.rs
index b92561c9e35..d57b1d433e5 100644
--- a/library/core/src/num/niche_types.rs
+++ b/library/core/src/num/niche_types.rs
@@ -46,11 +46,11 @@ macro_rules! define_valid_range_type {
             /// primitive without checking whether its zero.
             ///
             /// # Safety
-            /// Immediate language UB if `val == 0`, as it violates the validity
-            /// invariant of this type.
+            /// Immediate language UB if `val` is not within the valid range for this
+            /// type, as it violates the validity invariant.
             #[inline]
             pub const unsafe fn new_unchecked(val: $int) -> Self {
-                // SAFETY: Caller promised that `val` is non-zero.
+                // SAFETY: Caller promised that `val` is within the valid range.
                 unsafe { $name(val) }
             }
 
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 9a1ba7d1728..1c824e336be 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -271,6 +271,7 @@ mod prim_bool {}
 /// When the compiler sees a value of type `!` in a [coercion site], it implicitly inserts a
 /// coercion to allow the type checker to infer any type:
 ///
+// FIXME: use `core::convert::absurd` here instead, once it's merged
 /// ```rust,ignore (illustrative-and-has-placeholders)
 /// // this
 /// let x: u8 = panic!();
@@ -281,7 +282,6 @@ mod prim_bool {}
 /// // where absurd is a function with the following signature
 /// // (it's sound, because `!` always marks unreachable code):
 /// fn absurd<T>(_: !) -> T { ... }
-// FIXME: use `core::convert::absurd` here instead, once it's merged
 /// ```
 ///
 /// This can lead to compilation errors if the type cannot be inferred:
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index bd5b4e21baa..402634e49b3 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::enum_clike_unportable_variant)]
+
 use crate::num::NonZero;
 use crate::ub_checks::assert_unsafe_precondition;
 use crate::{cmp, fmt, hash, mem, num};
@@ -241,7 +243,7 @@ impl const Default for Alignment {
 
 #[cfg(target_pointer_width = "16")]
 #[derive(Copy, Clone, PartialEq, Eq)]
-#[repr(u16)]
+#[repr(usize)]
 enum AlignmentEnum {
     _Align1Shl0 = 1 << 0,
     _Align1Shl1 = 1 << 1,
@@ -263,7 +265,7 @@ enum AlignmentEnum {
 
 #[cfg(target_pointer_width = "32")]
 #[derive(Copy, Clone, PartialEq, Eq)]
-#[repr(u32)]
+#[repr(usize)]
 enum AlignmentEnum {
     _Align1Shl0 = 1 << 0,
     _Align1Shl1 = 1 << 1,
@@ -301,7 +303,7 @@ enum AlignmentEnum {
 
 #[cfg(target_pointer_width = "64")]
 #[derive(Copy, Clone, PartialEq, Eq)]
-#[repr(u64)]
+#[repr(usize)]
 enum AlignmentEnum {
     _Align1Shl0 = 1 << 0,
     _Align1Shl1 = 1 << 1,
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index f65257ff59b..474f86395ae 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -534,6 +534,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::iter::{self, FusedIterator, TrustedLen};
+use crate::marker::Destruct;
 use crate::ops::{self, ControlFlow, Deref, DerefMut};
 use crate::{convert, fmt, hint};
 
@@ -606,7 +607,13 @@ impl<T, E> Result<T, E> {
     #[must_use]
     #[inline]
     #[stable(feature = "is_some_and", since = "1.70.0")]
-    pub fn is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn is_ok_and<F>(self, f: F) -> bool
+    where
+        F: ~const FnOnce(T) -> bool + ~const Destruct,
+        T: ~const Destruct,
+        E: ~const Destruct,
+    {
         match self {
             Err(_) => false,
             Ok(x) => f(x),
@@ -655,7 +662,13 @@ impl<T, E> Result<T, E> {
     #[must_use]
     #[inline]
     #[stable(feature = "is_some_and", since = "1.70.0")]
-    pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn is_err_and<F>(self, f: F) -> bool
+    where
+        F: ~const FnOnce(E) -> bool + ~const Destruct,
+        E: ~const Destruct,
+        T: ~const Destruct,
+    {
         match self {
             Ok(_) => false,
             Err(e) => f(e),
@@ -682,8 +695,13 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
     #[rustc_diagnostic_item = "result_ok_method"]
-    pub fn ok(self) -> Option<T> {
+    pub const fn ok(self) -> Option<T>
+    where
+        T: ~const Destruct,
+        E: ~const Destruct,
+    {
         match self {
             Ok(x) => Some(x),
             Err(_) => None,
@@ -706,7 +724,12 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn err(self) -> Option<E> {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn err(self) -> Option<E>
+    where
+        T: ~const Destruct,
+        E: ~const Destruct,
+    {
         match self {
             Ok(_) => None,
             Err(x) => Some(x),
@@ -796,7 +819,11 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U, E> {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn map<U, F>(self, op: F) -> Result<U, E>
+    where
+        F: ~const FnOnce(T) -> U + ~const Destruct,
+    {
         match self {
             Ok(t) => Ok(op(t)),
             Err(e) => Err(e),
@@ -823,8 +850,15 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "result_map_or", since = "1.41.0")]
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
     #[must_use = "if you don't need the returned value, use `if let` instead"]
-    pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
+    pub const fn map_or<U, F>(self, default: U, f: F) -> U
+    where
+        F: ~const FnOnce(T) -> U + ~const Destruct,
+        T: ~const Destruct,
+        E: ~const Destruct,
+        U: ~const Destruct,
+    {
         match self {
             Ok(t) => f(t),
             Err(_) => default,
@@ -851,7 +885,12 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "result_map_or_else", since = "1.41.0")]
-    pub fn map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U
+    where
+        D: ~const FnOnce(E) -> U + ~const Destruct,
+        F: ~const FnOnce(T) -> U + ~const Destruct,
+    {
         match self {
             Ok(t) => f(t),
             Err(e) => default(e),
@@ -877,10 +916,13 @@ impl<T, E> Result<T, E> {
     /// [default value]: Default::default
     #[inline]
     #[unstable(feature = "result_option_map_or_default", issue = "138099")]
-    pub fn map_or_default<U, F>(self, f: F) -> U
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn map_or_default<U, F>(self, f: F) -> U
     where
-        U: Default,
-        F: FnOnce(T) -> U,
+        F: ~const FnOnce(T) -> U + ~const Destruct,
+        U: ~const Default,
+        T: ~const Destruct,
+        E: ~const Destruct,
     {
         match self {
             Ok(t) => f(t),
@@ -908,7 +950,11 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, F> {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn map_err<F, O>(self, op: O) -> Result<T, F>
+    where
+        O: ~const FnOnce(E) -> F + ~const Destruct,
+    {
         match self {
             Ok(t) => Ok(t),
             Err(e) => Err(op(e)),
@@ -930,7 +976,11 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "result_option_inspect", since = "1.76.0")]
-    pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn inspect<F>(self, f: F) -> Self
+    where
+        F: ~const FnOnce(&T) + ~const Destruct,
+    {
         if let Ok(ref t) = self {
             f(t);
         }
@@ -954,7 +1004,11 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "result_option_inspect", since = "1.76.0")]
-    pub fn inspect_err<F: FnOnce(&E)>(self, f: F) -> Self {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn inspect_err<F>(self, f: F) -> Self
+    where
+        F: ~const FnOnce(&E) + ~const Destruct,
+    {
         if let Err(ref e) = self {
             f(e);
         }
@@ -1033,7 +1087,8 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter(&self) -> Iter<'_, T> {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn iter(&self) -> Iter<'_, T> {
         Iter { inner: self.as_ref().ok() }
     }
 
@@ -1056,7 +1111,8 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn iter_mut(&mut self) -> IterMut<'_, T> {
         IterMut { inner: self.as_mut().ok() }
     }
 
@@ -1195,9 +1251,11 @@ impl<T, E> Result<T, E> {
     /// [`FromStr`]: crate::str::FromStr
     #[inline]
     #[stable(feature = "result_unwrap_or_default", since = "1.16.0")]
-    pub fn unwrap_or_default(self) -> T
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn unwrap_or_default(self) -> T
     where
-        T: Default,
+        T: ~const Default + ~const Destruct,
+        E: ~const Destruct,
     {
         match self {
             Ok(x) => x,
@@ -1370,7 +1428,13 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn and<U>(self, res: Result<U, E>) -> Result<U, E>
+    where
+        T: ~const Destruct,
+        E: ~const Destruct,
+        U: ~const Destruct,
+    {
         match self {
             Ok(_) => res,
             Err(e) => Err(e),
@@ -1409,8 +1473,12 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
     #[rustc_confusables("flat_map", "flatmap")]
-    pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> {
+    pub const fn and_then<U, F>(self, op: F) -> Result<U, E>
+    where
+        F: ~const FnOnce(T) -> Result<U, E> + ~const Destruct,
+    {
         match self {
             Ok(t) => op(t),
             Err(e) => Err(e),
@@ -1446,7 +1514,13 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn or<F>(self, res: Result<T, F>) -> Result<T, F> {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn or<F>(self, res: Result<T, F>) -> Result<T, F>
+    where
+        T: ~const Destruct,
+        E: ~const Destruct,
+        F: ~const Destruct,
+    {
         match self {
             Ok(v) => Ok(v),
             Err(_) => res,
@@ -1471,7 +1545,11 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn or_else<F, O>(self, op: O) -> Result<T, F>
+    where
+        O: ~const FnOnce(E) -> Result<T, F> + ~const Destruct,
+    {
         match self {
             Ok(t) => Ok(t),
             Err(e) => op(e),
@@ -1498,7 +1576,12 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unwrap_or(self, default: T) -> T {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn unwrap_or(self, default: T) -> T
+    where
+        T: ~const Destruct,
+        E: ~const Destruct,
+    {
         match self {
             Ok(t) => t,
             Err(_) => default,
@@ -1519,7 +1602,11 @@ impl<T, E> Result<T, E> {
     #[inline]
     #[track_caller]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
+    #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
+    pub const fn unwrap_or_else<F>(self, op: F) -> T
+    where
+        F: ~const FnOnce(E) -> T + ~const Destruct,
+    {
         match self {
             Ok(t) => t,
             Err(e) => op(e),
@@ -1544,7 +1631,7 @@ impl<T, E> Result<T, E> {
     ///
     /// ```no_run
     /// let x: Result<u32, &str> = Err("emergency failure");
-    /// unsafe { x.unwrap_unchecked(); } // Undefined behavior!
+    /// unsafe { x.unwrap_unchecked() }; // Undefined behavior!
     /// ```
     #[inline]
     #[track_caller]
@@ -1762,7 +1849,7 @@ impl<T, E> Result<Result<T, E>, E> {
 #[cold]
 #[track_caller]
 fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! {
-    panic!("{msg}: {error:?}")
+    panic!("{msg}: {error:?}");
 }
 
 // This is a separate function to avoid constructing a `dyn Debug`
@@ -1773,7 +1860,7 @@ fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! {
 #[inline]
 #[cold]
 #[track_caller]
-fn unwrap_failed<T>(_msg: &str, _error: &T) -> ! {
+const fn unwrap_failed<T>(_msg: &str, _error: &T) -> ! {
     panic!()
 }
 
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 14042997bc2..1dddc48e68e 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -3974,8 +3974,9 @@ impl<T> [T] {
     ///
     /// [`split_at_mut`]: slice::split_at_mut
     #[stable(feature = "swap_with_slice", since = "1.27.0")]
+    #[rustc_const_unstable(feature = "const_swap_with_slice", issue = "142204")]
     #[track_caller]
-    pub fn swap_with_slice(&mut self, other: &mut [T]) {
+    pub const fn swap_with_slice(&mut self, other: &mut [T]) {
         assert!(self.len() == other.len(), "destination and source slices have different lengths");
         // SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
         // checked to have the same length. The slices cannot overlap because
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 029a7b00ad3..0a9c0c61c95 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -20,6 +20,7 @@
 #![feature(const_eval_select)]
 #![feature(const_ops)]
 #![feature(const_ref_cell)]
+#![feature(const_result_trait_fn)]
 #![feature(const_trait_impl)]
 #![feature(core_float_math)]
 #![feature(core_intrinsics)]
@@ -82,6 +83,7 @@
 #![feature(pointer_is_aligned_to)]
 #![feature(portable_simd)]
 #![feature(ptr_metadata)]
+#![feature(result_option_map_or_default)]
 #![feature(slice_from_ptr_range)]
 #![feature(slice_internals)]
 #![feature(slice_partition_dedup)]
diff --git a/library/coretests/tests/result.rs b/library/coretests/tests/result.rs
index 90ec844bc57..39898d5dbb7 100644
--- a/library/coretests/tests/result.rs
+++ b/library/coretests/tests/result.rs
@@ -421,3 +421,86 @@ fn result_try_trait_v2_branch() {
     assert_eq!(Ok::<NonZero<u32>, ()>(one).branch(), Continue(one));
     assert_eq!(Err::<NonZero<u32>, ()>(()).branch(), Break(Err(())));
 }
+
+// helper functions for const contexts
+const fn eq10(x: u8) -> bool {
+    x == 10
+}
+const fn eq20(e: u8) -> bool {
+    e == 20
+}
+const fn double_u16(x: u8) -> u16 {
+    x as u16 * 2
+}
+const fn to_u16(x: u8) -> u16 {
+    x as u16
+}
+const fn err_to_u16_plus1(e: u8) -> u16 {
+    e as u16 + 1
+}
+const fn inc_u8(x: u8) -> u8 {
+    x + 1
+}
+const fn noop_u8_ref(_x: &u8) {}
+const fn add1_result(x: u8) -> Result<u8, u8> {
+    Ok(x + 1)
+}
+const fn add5_result(e: u8) -> Result<u8, u8> {
+    Ok(e + 5)
+}
+const fn plus7_u8(e: u8) -> u8 {
+    e + 7
+}
+
+#[test]
+fn test_const_result() {
+    const {
+        let r_ok: Result<u8, u8> = Ok(10);
+        let r_err: Result<u8, u8> = Err(20);
+        assert!(r_ok.is_ok());
+        assert!(r_err.is_err());
+
+        let ok_and = r_ok.is_ok_and(eq10);
+        let err_and = r_err.is_err_and(eq20);
+        assert!(ok_and);
+        assert!(err_and);
+
+        let opt_ok: Option<u8> = r_ok.ok();
+        let opt_err: Option<u8> = r_err.err();
+        assert!(opt_ok.unwrap() == 10);
+        assert!(opt_err.unwrap() == 20);
+
+        let mapped: Result<u16, u8> = r_ok.map(double_u16);
+        let map_or: u16 = r_ok.map_or(0, to_u16);
+        let map_or_else: u16 = r_err.map_or_else(err_to_u16_plus1, to_u16);
+        let map_or_default: u8 = r_err.map_or_default(inc_u8);
+        assert!(mapped.unwrap_or_default() == 20);
+        assert!(map_or == 10);
+        assert!(map_or_else == 21);
+        assert!(map_or_default == 0);
+
+        let _map_err: Result<u8, u16> = r_err.map_err(to_u16);
+        //FIXME: currently can't unwrap const error
+        // assert!(map_err.unwrap_err() == 20);
+
+        let inspected_ok: Result<u8, u8> = r_ok.inspect(noop_u8_ref);
+        let inspected_err: Result<u8, u8> = r_err.inspect_err(noop_u8_ref);
+        assert!(inspected_ok.is_ok());
+        assert!(inspected_err.is_err());
+
+        let unwrapped_default: u8 = r_err.unwrap_or_default();
+        assert!(unwrapped_default == 0);
+
+        let and_then: Result<u8, u8> = r_ok.and_then(add1_result);
+        let or: Result<u8, u8> = r_err.or(Ok(5));
+        let or_else: Result<u8, u8> = r_err.or_else(add5_result);
+        assert!(and_then.unwrap_or_default() == 11);
+        assert!(or.unwrap_or_default() == 5);
+        assert!(or_else.unwrap_or_default() == 25);
+
+        let u_or: u8 = r_err.unwrap_or(7);
+        let u_or_else: u8 = r_err.unwrap_or_else(plus7_u8);
+        assert!(u_or == 7);
+        assert!(u_or_else == 27);
+    };
+}
diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml
index e8c66f1a4dd..ecf043ac707 100644
--- a/library/panic_abort/Cargo.toml
+++ b/library/panic_abort/Cargo.toml
@@ -12,8 +12,7 @@ bench = false
 doc = false
 
 [dependencies]
-core = { path = "../core" }
-compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
+core = { path = "../rustc-std-workspace-core", package = "rustc-std-workspace-core" }
 
 [target.'cfg(target_os = "android")'.dependencies]
 libc = { version = "0.2", default-features = false }
diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml
index 47914b9cd3c..13d1a7160da 100644
--- a/library/panic_unwind/Cargo.toml
+++ b/library/panic_unwind/Cargo.toml
@@ -13,10 +13,9 @@ doc = false
 
 [dependencies]
 alloc = { path = "../alloc" }
-core = { path = "../core" }
-unwind = { path = "../unwind" }
-compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
 cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
+core = { path = "../rustc-std-workspace-core", package = "rustc-std-workspace-core" }
+unwind = { path = "../unwind" }
 
 [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
 libc = { version = "0.2", default-features = false }
diff --git a/library/rustc-std-workspace-core/README.md b/library/rustc-std-workspace-core/README.md
index 55a36e74106..15bc93f7948 100644
--- a/library/rustc-std-workspace-core/README.md
+++ b/library/rustc-std-workspace-core/README.md
@@ -11,6 +11,12 @@ on crates.io will draw a dependency edge to `libcore`, the version defined in
 this repository. That should draw all the dependency edges to ensure Cargo
 builds crates successfully!
 
+`rustc-std-workspace-core` also ensures `compiler-builtins` is in the crate
+graph. This crate is used by other crates in `library/`, other than `std` and
+`alloc`, so the `compiler-builtins` setup only needs to be configured in a
+single place. (Otherwise these crates would just need to depend on `core` and
+`compiler-builtins` separately.)
+
 Note that crates on crates.io need to depend on this crate with the name `core`
 for everything to work correctly. To do that they can use:
 
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 29ab9be0e69..7bc52976500 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,6 @@ 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 = { path = "../compiler-builtins/compiler-builtins" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 77301d7228e..fd06a3b540c 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -294,6 +294,8 @@
 #![feature(f128)]
 #![feature(ffi_const)]
 #![feature(formatting_options)]
+#![feature(hash_map_internals)]
+#![feature(hash_map_macro)]
 #![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
 #![feature(iter_advance_by)]
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs
index 25e2b7ea137..254570ae9c8 100644
--- a/library/std/src/macros.rs
+++ b/library/std/src/macros.rs
@@ -379,3 +379,77 @@ macro_rules! dbg {
         ($($crate::dbg!($val)),+,)
     };
 }
+
+#[doc(hidden)]
+#[macro_export]
+#[allow_internal_unstable(hash_map_internals)]
+#[unstable(feature = "hash_map_internals", issue = "none")]
+macro_rules! repetition_utils {
+    (@count $($tokens:tt),*) => {{
+        [$($crate::repetition_utils!(@replace $tokens => ())),*].len()
+    }};
+
+    (@replace $x:tt => $y:tt) => { $y }
+}
+
+/// Creates a [`HashMap`] containing the arguments.
+///
+/// `hash_map!` allows specifying the entries that make
+/// up the [`HashMap`] where the key and value are separated by a `=>`.
+///
+/// The entries are separated by commas with a trailing comma being allowed.
+///
+/// It is semantically equivalent to using repeated [`HashMap::insert`]
+/// on a newly created hashmap.
+///
+/// `hash_map!` will attempt to avoid repeated reallocations by
+/// using [`HashMap::with_capacity`].
+///
+/// # Examples
+///
+/// ```rust
+/// #![feature(hash_map_macro)]
+///
+/// let map = hash_map! {
+///     "key" => "value",
+///     "key1" => "value1"
+/// };
+///
+/// assert_eq!(map.get("key"), Some(&"value"));
+/// assert_eq!(map.get("key1"), Some(&"value1"));
+/// assert!(map.get("brrrrrrooooommm").is_none());
+/// ```
+///
+/// And with a trailing comma
+///
+///```rust
+/// #![feature(hash_map_macro)]
+///
+/// let map = hash_map! {
+///     "key" => "value", // notice the ,
+/// };
+///
+/// assert_eq!(map.get("key"), Some(&"value"));
+/// ```
+///
+/// The key and value are moved into the HashMap.
+///
+/// [`HashMap`]: crate::collections::HashMap
+/// [`HashMap::insert`]: crate::collections::HashMap::insert
+/// [`HashMap::with_capacity`]: crate::collections::HashMap::with_capacity
+#[macro_export]
+#[allow_internal_unstable(hash_map_internals)]
+#[unstable(feature = "hash_map_macro", issue = "144032")]
+macro_rules! hash_map {
+    () => {{
+        $crate::collections::HashMap::new()
+    }};
+
+    ( $( $key:expr => $value:expr ),* $(,)? ) => {{
+        let mut map = $crate::collections::HashMap::with_capacity(
+            const { $crate::repetition_utils!(@count $($key),*) }
+        );
+        $( map.insert($key, $value); )*
+        map
+    }}
+}
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 234fb284a59..913ef72f674 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -388,7 +388,7 @@ pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
 /// ```
 #[stable(feature = "resume_unwind", since = "1.9.0")]
 pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
-    panicking::rust_panic_without_hook(payload)
+    panicking::resume_unwind(payload)
 }
 
 /// Makes all future panics abort directly without running the panic hook or unwinding.
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 7873049d20b..224cd39855a 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -696,14 +696,14 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
     let msg = info.message();
     crate::sys::backtrace::__rust_end_short_backtrace(move || {
         if let Some(s) = msg.as_str() {
-            rust_panic_with_hook(
+            panic_with_hook(
                 &mut StaticStrPayload(s),
                 loc,
                 info.can_unwind(),
                 info.force_no_backtrace(),
             );
         } else {
-            rust_panic_with_hook(
+            panic_with_hook(
                 &mut FormatStringPayload { inner: &msg, string: None },
                 loc,
                 info.can_unwind(),
@@ -767,7 +767,7 @@ pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
 
     let loc = Location::caller();
     crate::sys::backtrace::__rust_end_short_backtrace(move || {
-        rust_panic_with_hook(
+        panic_with_hook(
             &mut Payload { inner: Some(msg) },
             loc,
             /* can_unwind */ true,
@@ -792,7 +792,7 @@ fn payload_as_str(payload: &dyn Any) -> &str {
 /// panics, panic hooks, and finally dispatching to the panic runtime to either
 /// abort or unwind.
 #[optimize(size)]
-fn rust_panic_with_hook(
+fn panic_with_hook(
     payload: &mut dyn PanicPayload,
     location: &Location<'_>,
     can_unwind: bool,
@@ -861,7 +861,7 @@ fn rust_panic_with_hook(
 /// This is the entry point for `resume_unwind`.
 /// It just forwards the payload to the panic runtime.
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
-pub fn rust_panic_without_hook(payload: Box<dyn Any + Send>) -> ! {
+pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
     panic_count::increase(false);
 
     struct RewrapBox(Box<dyn Any + Send>);
@@ -885,8 +885,8 @@ pub fn rust_panic_without_hook(payload: Box<dyn Any + Send>) -> ! {
     rust_panic(&mut RewrapBox(payload))
 }
 
-/// An unmangled function (through `rustc_std_internal_symbol`) on which to slap
-/// yer breakpoints.
+/// A function with a fixed suffix (through `rustc_std_internal_symbol`)
+/// on which to slap yer breakpoints.
 #[inline(never)]
 #[cfg_attr(not(test), rustc_std_internal_symbol)]
 #[cfg(not(feature = "panic_immediate_abort"))]
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index d9c34d4fa04..055e7f81480 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -3259,8 +3259,8 @@ impl Path {
     ///
     /// # Examples
     ///
-    #[cfg_attr(unix, doc = "```no_run")]
-    #[cfg_attr(not(unix), doc = "```ignore")]
+    /// ```rust,no_run
+    /// # #[cfg(unix)] {
     /// use std::path::Path;
     /// use std::os::unix::fs::symlink;
     ///
@@ -3268,6 +3268,7 @@ impl Path {
     /// symlink("/origin_does_not_exist/", link_path).unwrap();
     /// assert_eq!(link_path.is_symlink(), true);
     /// assert_eq!(link_path.exists(), false);
+    /// # }
     /// ```
     ///
     /// # See Also
diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs
index eba849d16da..a40e29a772a 100644
--- a/library/std/src/sync/lazy_lock.rs
+++ b/library/std/src/sync/lazy_lock.rs
@@ -25,6 +25,22 @@ union Data<T, F> {
 ///
 /// [`LazyCell`]: crate::cell::LazyCell
 ///
+/// # Poisoning
+///
+/// If the initialization closure passed to [`LazyLock::new`] panics, the lock will be poisoned.
+/// Once the lock is poisoned, any threads that attempt to access this lock (via a dereference
+/// or via an explicit call to [`force()`]) will panic.
+///
+/// This concept is similar to that of poisoning in the [`std::sync::poison`] module. A key
+/// difference, however, is that poisoning in `LazyLock` is _unrecoverable_. All future accesses of
+/// the lock from other threads will panic, whereas a type in [`std::sync::poison`] like
+/// [`std::sync::poison::Mutex`] allows recovery via [`PoisonError::into_inner()`].
+///
+/// [`force()`]: LazyLock::force
+/// [`std::sync::poison`]: crate::sync::poison
+/// [`std::sync::poison::Mutex`]: crate::sync::poison::Mutex
+/// [`PoisonError::into_inner()`]: crate::sync::poison::PoisonError::into_inner
+///
 /// # Examples
 ///
 /// Initialize static variables with `LazyLock`.
@@ -102,6 +118,10 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
     ///
     /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
     ///
+    /// # Panics
+    ///
+    /// Panics if the lock is poisoned.
+    ///
     /// # Examples
     ///
     /// ```
@@ -136,6 +156,15 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
     /// Forces the evaluation of this lazy value and returns a mutable reference to
     /// the result.
     ///
+    /// # Panics
+    ///
+    /// If the initialization closure panics (the one that is passed to the [`new()`] method), the
+    /// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future
+    /// accesses of the lock (via [`force()`] or a dereference) to panic.
+    ///
+    /// [`new()`]: LazyLock::new
+    /// [`force()`]: LazyLock::force
+    ///
     /// # Examples
     ///
     /// ```
@@ -193,6 +222,15 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
     /// This method will block the calling thread if another initialization
     /// routine is currently running.
     ///
+    /// # Panics
+    ///
+    /// If the initialization closure panics (the one that is passed to the [`new()`] method), the
+    /// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future
+    /// accesses of the lock (via [`force()`] or a dereference) to panic.
+    ///
+    /// [`new()`]: LazyLock::new
+    /// [`force()`]: LazyLock::force
+    ///
     /// # Examples
     ///
     /// ```
@@ -227,7 +265,8 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
 }
 
 impl<T, F> LazyLock<T, F> {
-    /// Returns a mutable reference to the value if initialized, or `None` if not.
+    /// Returns a mutable reference to the value if initialized. Otherwise (if uninitialized or
+    /// poisoned), returns `None`.
     ///
     /// # Examples
     ///
@@ -256,7 +295,8 @@ impl<T, F> LazyLock<T, F> {
         }
     }
 
-    /// Returns a reference to the value if initialized, or `None` if not.
+    /// Returns a reference to the value if initialized. Otherwise (if uninitialized or poisoned),
+    /// returns `None`.
     ///
     /// # Examples
     ///
@@ -307,6 +347,14 @@ impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
     /// This method will block the calling thread if another initialization
     /// routine is currently running.
     ///
+    /// # Panics
+    ///
+    /// If the initialization closure panics (the one that is passed to the [`new()`] method), the
+    /// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future
+    /// accesses of the lock (via [`force()`] or a dereference) to panic.
+    ///
+    /// [`new()`]: LazyLock::new
+    /// [`force()`]: LazyLock::force
     #[inline]
     fn deref(&self) -> &T {
         LazyLock::force(self)
@@ -315,6 +363,14 @@ impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
 
 #[stable(feature = "lazy_deref_mut", since = "1.89.0")]
 impl<T, F: FnOnce() -> T> DerefMut for LazyLock<T, F> {
+    /// # Panics
+    ///
+    /// If the initialization closure panics (the one that is passed to the [`new()`] method), the
+    /// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future
+    /// accesses of the lock (via [`force()`] or a dereference) to panic.
+    ///
+    /// [`new()`]: LazyLock::new
+    /// [`force()`]: LazyLock::force
     #[inline]
     fn deref_mut(&mut self) -> &mut T {
         LazyLock::force_mut(self)
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index a5c3a6c46a4..b224044cbe0 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -16,6 +16,8 @@ use crate::sync::Once;
 /// A `OnceLock` can be thought of as a safe abstraction over uninitialized data that becomes
 /// initialized once written.
 ///
+/// Unlike [`Mutex`](crate::sync::Mutex), `OnceLock` is never poisoned on panic.
+///
 /// [`OnceCell`]: crate::cell::OnceCell
 /// [`LazyLock<T, F>`]: crate::sync::LazyLock
 /// [`LazyLock::new(|| ...)`]: crate::sync::LazyLock::new
diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs
index b901a5701a4..31889dcc10f 100644
--- a/library/std/src/sync/poison.rs
+++ b/library/std/src/sync/poison.rs
@@ -2,15 +2,16 @@
 //!
 //! # Poisoning
 //!
-//! All synchronization objects in this module implement a strategy called "poisoning"
-//! where if a thread panics while holding the exclusive access granted by the primitive,
-//! the state of the primitive is set to "poisoned".
-//! This information is then propagated to all other threads
+//! All synchronization objects in this module implement a strategy called
+//! "poisoning" where a primitive becomes poisoned if it recognizes that some
+//! thread has panicked while holding the exclusive access granted by the
+//! primitive. This information is then propagated to all other threads
 //! to signify that the data protected by this primitive is likely tainted
 //! (some invariant is not being upheld).
 //!
-//! The specifics of how this "poisoned" state affects other threads
-//! depend on the primitive. See [#Overview] below.
+//! The specifics of how this "poisoned" state affects other threads and whether
+//! the panics are recognized reliably or on a best-effort basis depend on the
+//! primitive. See [Overview](#overview) below.
 //!
 //! For the alternative implementations that do not employ poisoning,
 //! see [`std::sync::nonpoison`].
@@ -36,14 +37,15 @@
 //! - [`Mutex`]: Mutual Exclusion mechanism, which ensures that at
 //!   most one thread at a time is able to access some data.
 //!
-//!   [`Mutex::lock()`] returns a [`LockResult`],
-//!   providing a way to deal with the poisoned state.
-//!   See [`Mutex`'s documentation](Mutex#poisoning) for more.
+//!   Panicking while holding the lock typically poisons the mutex, but it is
+//!   not guaranteed to detect this condition in all circumstances.
+//!   [`Mutex::lock()`] returns a [`LockResult`], providing a way to deal with
+//!   the poisoned state. See [`Mutex`'s documentation](Mutex#poisoning) for more.
 //!
 //! - [`Once`]: A thread-safe way to run a piece of code only once.
 //!   Mostly useful for implementing one-time global initialization.
 //!
-//!   [`Once`] is poisoned if the piece of code passed to
+//!   [`Once`] is reliably poisoned if the piece of code passed to
 //!   [`Once::call_once()`] or [`Once::call_once_force()`] panics.
 //!   When in poisoned state, subsequent calls to [`Once::call_once()`] will panic too.
 //!   [`Once::call_once_force()`] can be used to clear the poisoned state.
@@ -53,7 +55,7 @@
 //!   writer at a time. In some cases, this can be more efficient than
 //!   a mutex.
 //!
-//!   This implementation, like [`Mutex`], will become poisoned on a panic.
+//!   This implementation, like [`Mutex`], usually becomes poisoned on a panic.
 //!   Note, however, that an `RwLock` may only be poisoned if a panic occurs
 //!   while it is locked exclusively (write mode). If a panic occurs in any reader,
 //!   then the lock will not be poisoned.
diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs
index 64744f18c74..6205c4fa4ca 100644
--- a/library/std/src/sync/poison/mutex.rs
+++ b/library/std/src/sync/poison/mutex.rs
@@ -18,20 +18,69 @@ use crate::sys::sync as sys;
 /// # Poisoning
 ///
 /// The mutexes in this module implement a strategy called "poisoning" where a
-/// mutex is considered poisoned whenever a thread panics while holding the
-/// mutex. Once a mutex is poisoned, all other threads are unable to access the
-/// data by default as it is likely tainted (some invariant is not being
-/// upheld).
+/// mutex becomes poisoned if it recognizes that the thread holding it has
+/// panicked.
 ///
-/// For a mutex, this means that the [`lock`] and [`try_lock`] methods return a
+/// Once a mutex is poisoned, all other threads are unable to access the data by
+/// default as it is likely tainted (some invariant is not being upheld). For a
+/// mutex, this means that the [`lock`] and [`try_lock`] methods return a
 /// [`Result`] which indicates whether a mutex has been poisoned or not. Most
 /// usage of a mutex will simply [`unwrap()`] these results, propagating panics
 /// among threads to ensure that a possibly invalid invariant is not witnessed.
 ///
-/// A poisoned mutex, however, does not prevent all access to the underlying
-/// data. The [`PoisonError`] type has an [`into_inner`] method which will return
-/// the guard that would have otherwise been returned on a successful lock. This
-/// allows access to the data, despite the lock being poisoned.
+/// Poisoning is only advisory: the [`PoisonError`] type has an [`into_inner`]
+/// method which will return the guard that would have otherwise been returned
+/// on a successful lock. This allows access to the data, despite the lock being
+/// poisoned.
+///
+/// In addition, the panic detection is not ideal, so even unpoisoned mutexes
+/// need to be handled with care, since certain panics may have been skipped.
+/// Here is a non-exhaustive list of situations where this might occur:
+///
+/// - If a mutex is locked while a panic is underway, e.g. within a [`Drop`]
+///   implementation or a [panic hook], panicking for the second time while the
+///   lock is held will leave the mutex unpoisoned. Note that while double panic
+///   usually aborts the program, [`catch_unwind`] can prevent this.
+///
+/// - Locking and unlocking the mutex across different panic contexts, e.g. by
+///   storing the guard to a [`Cell`] within [`Drop::drop`] and accessing it
+///   outside, or vice versa, can affect poisoning status in an unexpected way.
+///
+/// - Foreign exceptions do not currently trigger poisoning even in absence of
+///   other panics.
+///
+/// While this rarely happens in realistic code, `unsafe` code cannot rely on
+/// poisoning for soundness, since the behavior of poisoning can depend on
+/// outside context. Here's an example of **incorrect** use of poisoning:
+///
+/// ```rust
+/// use std::sync::Mutex;
+///
+/// struct MutexBox<T> {
+///     data: Mutex<*mut T>,
+/// }
+///
+/// impl<T> MutexBox<T> {
+///     pub fn new(value: T) -> Self {
+///         Self {
+///             data: Mutex::new(Box::into_raw(Box::new(value))),
+///         }
+///     }
+///
+///     pub fn replace_with(&self, f: impl FnOnce(T) -> T) {
+///         let ptr = self.data.lock().expect("poisoned");
+///         // While `f` is running, the data is moved out of `*ptr`. If `f`
+///         // panics, `*ptr` keeps pointing at a dropped value. The intention
+///         // is that this will poison the mutex, so the following calls to
+///         // `replace_with` will panic without reading `*ptr`. But since
+///         // poisoning is not guaranteed to occur if this is run from a panic
+///         // hook, this can lead to use-after-free.
+///         unsafe {
+///             (*ptr).write(f((*ptr).read()));
+///         }
+///     }
+/// }
+/// ```
 ///
 /// [`new`]: Self::new
 /// [`lock`]: Self::lock
@@ -39,6 +88,9 @@ use crate::sys::sync as sys;
 /// [`unwrap()`]: Result::unwrap
 /// [`PoisonError`]: super::PoisonError
 /// [`into_inner`]: super::PoisonError::into_inner
+/// [panic hook]: crate::panic::set_hook
+/// [`catch_unwind`]: crate::panic::catch_unwind
+/// [`Cell`]: crate::cell::Cell
 ///
 /// # Examples
 ///
diff --git a/library/std/src/sync/poison/once.rs b/library/std/src/sync/poison/once.rs
index 103e5195407..faf2913c547 100644
--- a/library/std/src/sync/poison/once.rs
+++ b/library/std/src/sync/poison/once.rs
@@ -136,7 +136,8 @@ impl Once {
     /// it will *poison* this [`Once`] instance, causing all future invocations of
     /// `call_once` to also panic.
     ///
-    /// This is similar to [poisoning with mutexes][poison].
+    /// This is similar to [poisoning with mutexes][poison], but this mechanism
+    /// is guaranteed to never skip panics within `f`.
     ///
     /// [poison]: struct.Mutex.html#poisoning
     #[inline]
@@ -293,6 +294,9 @@ impl Once {
 
     /// Blocks the current thread until initialization has completed, ignoring
     /// poisoning.
+    ///
+    /// If this [`Once`] has been poisoned, this function blocks until it
+    /// becomes completed, unlike [`Once::wait()`], which panics in this case.
     #[stable(feature = "once_wait", since = "1.86.0")]
     pub fn wait_force(&self) {
         if !self.inner.is_completed() {
diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs
index 934a173425a..2c92602bc87 100644
--- a/library/std/src/sync/poison/rwlock.rs
+++ b/library/std/src/sync/poison/rwlock.rs
@@ -46,10 +46,12 @@ use crate::sys::sync as sys;
 ///
 /// # Poisoning
 ///
-/// An `RwLock`, like [`Mutex`], will become poisoned on a panic. Note, however,
-/// that an `RwLock` may only be poisoned if a panic occurs while it is locked
-/// exclusively (write mode). If a panic occurs in any reader, then the lock
-/// will not be poisoned.
+/// An `RwLock`, like [`Mutex`], will [usually] become poisoned on a panic. Note,
+/// however, that an `RwLock` may only be poisoned if a panic occurs while it is
+/// locked exclusively (write mode). If a panic occurs in any reader, then the
+/// lock will not be poisoned.
+///
+/// [usually]: super::Mutex#poisoning
 ///
 /// # Examples
 ///
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index 271dc4d11de..b50574de937 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -444,17 +444,17 @@ impl<'a> DevicePathNode<'a> {
 
 impl<'a> PartialEq for DevicePathNode<'a> {
     fn eq(&self, other: &Self) -> bool {
-        let self_len = self.length();
-        let other_len = other.length();
-
-        self_len == other_len
-            && unsafe {
-                compiler_builtins::mem::memcmp(
-                    self.protocol.as_ptr().cast(),
-                    other.protocol.as_ptr().cast(),
-                    usize::from(self_len),
-                ) == 0
-            }
+        // Compare as a single buffer rather than by field since it optimizes better.
+        //
+        // SAFETY: `Protocol` is followed by a buffer of `length - sizeof::<Protocol>()`. `Protocol`
+        // has no padding so it is sound to interpret as a slice.
+        unsafe {
+            let s1 =
+                slice::from_raw_parts(self.protocol.as_ptr().cast::<u8>(), self.length().into());
+            let s2 =
+                slice::from_raw_parts(other.protocol.as_ptr().cast::<u8>(), other.length().into());
+            s1 == s2
+        }
     }
 }
 
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index dff981c900c..8d3ab82ace1 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -2018,6 +2018,9 @@ fn _assert_sync_and_send() {
 ///   which may take time on systems with large numbers of mountpoints.
 ///   (This does not apply to cgroup v2, or to processes not in a
 ///   cgroup.)
+/// - It does not attempt to take `ulimit` into account. If there is a limit set on the number of
+///   threads, `available_parallelism` cannot know how much of that limit a Rust program should
+///   take, or know in a reliable and race-free way how much of that limit is already taken.
 ///
 /// On all targets:
 /// - It may overcount the amount of parallelism available when running in a VM
diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml
index f8da09f7193..b9ce676eb3f 100644
--- a/library/unwind/Cargo.toml
+++ b/library/unwind/Cargo.toml
@@ -14,9 +14,8 @@ bench = false
 doc = false
 
 [dependencies]
-core = { path = "../core" }
-compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
 cfg-if = "1.0"
+core = { path = "../rustc-std-workspace-core", package = "rustc-std-workspace-core" }
 
 [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
 libc = { version = "0.2.140", features = ['rustc-dep-of-std'], default-features = false }
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index 181d71f63c2..cf24fedaebb 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -159,6 +159,9 @@ fn main() {
     if is_bootstrap_profiling_enabled() {
         build.report_summary(start_time);
     }
+
+    #[cfg(feature = "tracing")]
+    build.report_step_graph();
 }
 
 fn check_version(config: &Config) -> Option<String> {
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index b4232409ba8..f6653ed899b 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -13,7 +13,7 @@ use crate::core::builder::{
 };
 use crate::core::config::TargetSelection;
 use crate::utils::build_stamp::{self, BuildStamp};
-use crate::{Compiler, Mode, Subcommand};
+use crate::{CodegenBackendKind, Compiler, Mode, Subcommand};
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Std {
@@ -312,7 +312,7 @@ fn prepare_compiler_for_check(
 pub struct CodegenBackend {
     pub build_compiler: Compiler,
     pub target: TargetSelection,
-    pub backend: &'static str,
+    pub backend: CodegenBackendKind,
 }
 
 impl Step for CodegenBackend {
@@ -327,14 +327,14 @@ impl Step for CodegenBackend {
     fn make_run(run: RunConfig<'_>) {
         // FIXME: only check the backend(s) that were actually selected in run.paths
         let build_compiler = prepare_compiler_for_check(run.builder, run.target, Mode::Codegen);
-        for &backend in &["cranelift", "gcc"] {
+        for backend in [CodegenBackendKind::Cranelift, CodegenBackendKind::Gcc] {
             run.builder.ensure(CodegenBackend { build_compiler, target: run.target, backend });
         }
     }
 
     fn run(self, builder: &Builder<'_>) {
         // FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved
-        if builder.build.config.vendor && self.backend == "gcc" {
+        if builder.build.config.vendor && self.backend.is_gcc() {
             println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
             return;
         }
@@ -354,19 +354,22 @@ impl Step for CodegenBackend {
 
         cargo
             .arg("--manifest-path")
-            .arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
+            .arg(builder.src.join(format!("compiler/{}/Cargo.toml", backend.crate_name())));
         rustc_cargo_env(builder, &mut cargo, target);
 
-        let _guard = builder.msg_check(format!("rustc_codegen_{backend}"), target, None);
+        let _guard = builder.msg_check(backend.crate_name(), target, None);
 
-        let stamp = build_stamp::codegen_backend_stamp(builder, build_compiler, target, backend)
+        let stamp = build_stamp::codegen_backend_stamp(builder, build_compiler, target, &backend)
             .with_prefix("check");
 
         run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
     }
 
     fn metadata(&self) -> Option<StepMetadata> {
-        Some(StepMetadata::check(self.backend, self.target).built_by(self.build_compiler))
+        Some(
+            StepMetadata::check(&self.backend.crate_name(), self.target)
+                .built_by(self.build_compiler),
+        )
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 4abfe1843eb..95707e37018 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -19,7 +19,7 @@ use serde_derive::Deserialize;
 use tracing::{instrument, span};
 
 use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags};
-use crate::core::build_steps::tool::{SourceType, copy_lld_artifacts};
+use crate::core::build_steps::tool::{RustcPrivateCompilers, SourceType, copy_lld_artifacts};
 use crate::core::build_steps::{dist, llvm};
 use crate::core::builder;
 use crate::core::builder::{
@@ -33,7 +33,10 @@ use crate::utils::exec::command;
 use crate::utils::helpers::{
     exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date,
 };
-use crate::{CLang, Compiler, DependencyType, FileType, GitRepo, LLVM_TOOLS, Mode, debug, trace};
+use crate::{
+    CLang, CodegenBackendKind, Compiler, DependencyType, FileType, GitRepo, LLVM_TOOLS, Mode,
+    debug, trace,
+};
 
 /// Build a standard library for the given `target` using the given `compiler`.
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -1128,7 +1131,7 @@ impl Step for Rustc {
             cargo.env("RUSTC_BOLT_LINK_FLAGS", "1");
         }
 
-        let _guard = builder.msg_sysroot_tool(
+        let _guard = builder.msg_rustc_tool(
             Kind::Build,
             build_compiler.stage,
             format_args!("compiler artifacts{}", crate_description(&self.crates)),
@@ -1330,7 +1333,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
     }
 
     if let Some(backend) = builder.config.default_codegen_backend(target) {
-        cargo.env("CFG_DEFAULT_CODEGEN_BACKEND", backend);
+        cargo.env("CFG_DEFAULT_CODEGEN_BACKEND", backend.name());
     }
 
     let libdir_relative = builder.config.libdir_relative().unwrap_or_else(|| Path::new("lib"));
@@ -1541,9 +1544,8 @@ impl Step for RustcLink {
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct CodegenBackend {
-    pub target: TargetSelection,
-    pub compiler: Compiler,
-    pub backend: String,
+    compilers: RustcPrivateCompilers,
+    backend: CodegenBackendKind,
 }
 
 fn needs_codegen_config(run: &RunConfig<'_>) -> bool {
@@ -1568,7 +1570,7 @@ fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool {
     if path.contains(CODEGEN_BACKEND_PREFIX) {
         let mut needs_codegen_backend_config = true;
         for backend in run.builder.config.codegen_backends(run.target) {
-            if path.ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + backend)) {
+            if path.ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + backend.name())) {
                 needs_codegen_backend_config = false;
             }
         }
@@ -1602,13 +1604,16 @@ impl Step for CodegenBackend {
         }
 
         for backend in run.builder.config.codegen_backends(run.target) {
-            if backend == "llvm" {
+            if backend.is_llvm() {
                 continue; // Already built as part of rustc
             }
 
             run.builder.ensure(CodegenBackend {
-                target: run.target,
-                compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
+                compilers: RustcPrivateCompilers::new(
+                    run.builder,
+                    run.builder.top_stage,
+                    run.target,
+                ),
                 backend: backend.clone(),
             });
         }
@@ -1621,20 +1626,17 @@ impl Step for CodegenBackend {
             name = "CodegenBackend::run",
             skip_all,
             fields(
-                compiler = ?self.compiler,
-                target = ?self.target,
-                backend = ?self.target,
+                compilers = ?self.compilers,
+                backend = ?self.backend,
             ),
         ),
     )]
     fn run(self, builder: &Builder<'_>) {
-        let compiler = self.compiler;
-        let target = self.target;
         let backend = self.backend;
+        let target = self.compilers.target();
+        let build_compiler = self.compilers.build_compiler();
 
-        builder.ensure(Rustc::new(compiler, target));
-
-        if builder.config.keep_stage.contains(&compiler.stage) {
+        if builder.config.keep_stage.contains(&build_compiler.stage) {
             trace!("`keep-stage` requested");
             builder.info(
                 "WARNING: Using a potentially old codegen backend. \
@@ -1645,17 +1647,11 @@ impl Step for CodegenBackend {
             return;
         }
 
-        let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
-        if compiler_to_use != compiler {
-            builder.ensure(CodegenBackend { compiler: compiler_to_use, target, backend });
-            return;
-        }
-
-        let out_dir = builder.cargo_out(compiler, Mode::Codegen, target);
+        let out_dir = builder.cargo_out(build_compiler, Mode::Codegen, target);
 
         let mut cargo = builder::Cargo::new(
             builder,
-            compiler,
+            build_compiler,
             Mode::Codegen,
             SourceType::InTree,
             target,
@@ -1663,20 +1659,26 @@ impl Step for CodegenBackend {
         );
         cargo
             .arg("--manifest-path")
-            .arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
+            .arg(builder.src.join(format!("compiler/{}/Cargo.toml", backend.crate_name())));
         rustc_cargo_env(builder, &mut cargo, target);
 
         // Ideally, we'd have a separate step for the individual codegen backends,
         // like we have in tests (test::CodegenGCC) but that would require a lot of restructuring.
         // If the logic gets more complicated, it should probably be done.
-        if backend == "gcc" {
+        if backend.is_gcc() {
             let gcc = builder.ensure(Gcc { target });
             add_cg_gcc_cargo_flags(&mut cargo, &gcc);
         }
 
         let tmp_stamp = BuildStamp::new(&out_dir).with_prefix("tmp");
 
-        let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target);
+        let _guard = builder.msg_rustc_tool(
+            Kind::Build,
+            build_compiler.stage,
+            format_args!("codegen backend {}", backend.name()),
+            build_compiler.host,
+            target,
+        );
         let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false);
         if builder.config.dry_run() {
             return;
@@ -1696,10 +1698,17 @@ impl Step for CodegenBackend {
                 f.display()
             );
         }
-        let stamp = build_stamp::codegen_backend_stamp(builder, compiler, target, &backend);
+        let stamp = build_stamp::codegen_backend_stamp(builder, build_compiler, target, &backend);
         let codegen_backend = codegen_backend.to_str().unwrap();
         t!(stamp.add_stamp(codegen_backend).write());
     }
+
+    fn metadata(&self) -> Option<StepMetadata> {
+        Some(
+            StepMetadata::build(&self.backend.crate_name(), self.compilers.target())
+                .built_by(self.compilers.build_compiler()),
+        )
+    }
 }
 
 /// Creates the `codegen-backends` folder for a compiler that's about to be
@@ -1731,7 +1740,7 @@ fn copy_codegen_backends_to_sysroot(
     }
 
     for backend in builder.config.codegen_backends(target) {
-        if backend == "llvm" {
+        if backend.is_llvm() {
             continue; // Already built as part of rustc
         }
 
@@ -2161,7 +2170,7 @@ impl Step for Assemble {
         let _codegen_backend_span =
             span!(tracing::Level::DEBUG, "building requested codegen backends").entered();
         for backend in builder.config.codegen_backends(target_compiler.host) {
-            if backend == "llvm" {
+            if backend.is_llvm() {
                 debug!("llvm codegen backend is already built as part of rustc");
                 continue; // Already built as part of rustc
             }
@@ -2186,8 +2195,10 @@ impl Step for Assemble {
                 continue;
             }
             builder.ensure(CodegenBackend {
-                compiler: build_compiler,
-                target: target_compiler.host,
+                compilers: RustcPrivateCompilers::from_build_and_target_compiler(
+                    build_compiler,
+                    target_compiler,
+                ),
                 backend: backend.clone(),
             });
         }
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index c8a54ad250c..0465a071159 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -20,7 +20,7 @@ use object::read::archive::ArchiveFile;
 use tracing::instrument;
 
 use crate::core::build_steps::doc::DocumentationFormat;
-use crate::core::build_steps::tool::{self, Tool};
+use crate::core::build_steps::tool::{self, RustcPrivateCompilers, Tool};
 use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor};
 use crate::core::build_steps::{compile, llvm};
 use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata};
@@ -32,7 +32,7 @@ use crate::utils::helpers::{
     exe, is_dylib, move_file, t, target_supports_cranelift_backend, timeit,
 };
 use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball};
-use crate::{Compiler, DependencyType, FileType, LLVM_TOOLS, Mode, trace};
+use crate::{CodegenBackendKind, Compiler, DependencyType, FileType, LLVM_TOOLS, Mode, trace};
 
 pub fn pkgname(builder: &Builder<'_>, component: &str) -> String {
     format!("{}-{}", component, builder.rust_package_vers())
@@ -425,19 +425,20 @@ impl Step for Rustc {
                 .as_ref()
                 .is_none_or(|tools| tools.iter().any(|tool| tool == "rustdoc"))
             {
-                let rustdoc = builder.rustdoc(compiler);
+                let rustdoc = builder.rustdoc_for_compiler(compiler);
                 builder.install(&rustdoc, &image.join("bin"), FileType::Executable);
             }
 
             let ra_proc_macro_srv_compiler =
                 builder.compiler_for(compiler.stage, builder.config.host_target, compiler.host);
-            builder.ensure(compile::Rustc::new(ra_proc_macro_srv_compiler, compiler.host));
+            let compilers = RustcPrivateCompilers::from_build_compiler(
+                builder,
+                ra_proc_macro_srv_compiler,
+                compiler.host,
+            );
 
             if let Some(ra_proc_macro_srv) = builder.ensure_if_default(
-                tool::RustAnalyzerProcMacroSrv {
-                    compiler: ra_proc_macro_srv_compiler,
-                    target: compiler.host,
-                },
+                tool::RustAnalyzerProcMacroSrv::from_compilers(compilers),
                 builder.kind,
             ) {
                 let dst = image.join("libexec");
@@ -1172,7 +1173,7 @@ impl Step for PlainSourceTarball {
 
 #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
 pub struct Cargo {
-    pub compiler: Compiler,
+    pub build_compiler: Compiler,
     pub target: TargetSelection,
 }
 
@@ -1188,7 +1189,7 @@ impl Step for Cargo {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Cargo {
-            compiler: run.builder.compiler_for(
+            build_compiler: run.builder.compiler_for(
                 run.builder.top_stage,
                 run.builder.config.host_target,
                 run.target,
@@ -1198,12 +1199,10 @@ impl Step for Cargo {
     }
 
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
-        let compiler = self.compiler;
+        let build_compiler = self.build_compiler;
         let target = self.target;
 
-        builder.ensure(compile::Rustc::new(compiler, target));
-
-        let cargo = builder.ensure(tool::Cargo { compiler, target });
+        let cargo = builder.ensure(tool::Cargo::from_build_compiler(build_compiler, target));
         let src = builder.src.join("src/tools/cargo");
         let etc = src.join("src/etc");
 
@@ -1228,7 +1227,7 @@ impl Step for Cargo {
 
 #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
 pub struct RustAnalyzer {
-    pub compiler: Compiler,
+    pub build_compiler: Compiler,
     pub target: TargetSelection,
 }
 
@@ -1244,7 +1243,7 @@ impl Step for RustAnalyzer {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(RustAnalyzer {
-            compiler: run.builder.compiler_for(
+            build_compiler: run.builder.compiler_for(
                 run.builder.top_stage,
                 run.builder.config.host_target,
                 run.target,
@@ -1254,12 +1253,11 @@ impl Step for RustAnalyzer {
     }
 
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
-        let compiler = self.compiler;
         let target = self.target;
+        let compilers =
+            RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target);
 
-        builder.ensure(compile::Rustc::new(compiler, target));
-
-        let rust_analyzer = builder.ensure(tool::RustAnalyzer { compiler, target });
+        let rust_analyzer = builder.ensure(tool::RustAnalyzer::from_compilers(compilers));
 
         let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple);
         tarball.set_overlay(OverlayKind::RustAnalyzer);
@@ -1270,9 +1268,9 @@ impl Step for RustAnalyzer {
     }
 }
 
-#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct Clippy {
-    pub compiler: Compiler,
+    pub build_compiler: Compiler,
     pub target: TargetSelection,
 }
 
@@ -1288,7 +1286,7 @@ impl Step for Clippy {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Clippy {
-            compiler: run.builder.compiler_for(
+            build_compiler: run.builder.compiler_for(
                 run.builder.top_stage,
                 run.builder.config.host_target,
                 run.target,
@@ -1298,16 +1296,15 @@ impl Step for Clippy {
     }
 
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
-        let compiler = self.compiler;
         let target = self.target;
-
-        builder.ensure(compile::Rustc::new(compiler, target));
+        let compilers =
+            RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, target);
 
         // Prepare the image directory
         // We expect clippy to build, because we've exited this step above if tool
         // state for clippy isn't testing.
-        let clippy = builder.ensure(tool::Clippy { compiler, target });
-        let cargoclippy = builder.ensure(tool::CargoClippy { compiler, target });
+        let clippy = builder.ensure(tool::Clippy::from_compilers(compilers));
+        let cargoclippy = builder.ensure(tool::CargoClippy::from_compilers(compilers));
 
         let mut tarball = Tarball::new(builder, "clippy", &target.triple);
         tarball.set_overlay(OverlayKind::Clippy);
@@ -1319,9 +1316,9 @@ impl Step for Clippy {
     }
 }
 
-#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct Miri {
-    pub compiler: Compiler,
+    pub build_compiler: Compiler,
     pub target: TargetSelection,
 }
 
@@ -1337,7 +1334,7 @@ impl Step for Miri {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Miri {
-            compiler: run.builder.compiler_for(
+            build_compiler: run.builder.compiler_for(
                 run.builder.top_stage,
                 run.builder.config.host_target,
                 run.target,
@@ -1354,15 +1351,12 @@ impl Step for Miri {
             return None;
         }
 
-        let compiler = self.compiler;
-        let target = self.target;
+        let compilers =
+            RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target);
+        let miri = builder.ensure(tool::Miri::from_compilers(compilers));
+        let cargomiri = builder.ensure(tool::CargoMiri::from_compilers(compilers));
 
-        builder.ensure(compile::Rustc::new(compiler, target));
-
-        let miri = builder.ensure(tool::Miri { compiler, target });
-        let cargomiri = builder.ensure(tool::CargoMiri { compiler, target });
-
-        let mut tarball = Tarball::new(builder, "miri", &target.triple);
+        let mut tarball = Tarball::new(builder, "miri", &self.target.triple);
         tarball.set_overlay(OverlayKind::Miri);
         tarball.is_preview(true);
         tarball.add_file(&miri.tool_path, "bin", FileType::Executable);
@@ -1372,10 +1366,10 @@ impl Step for Miri {
     }
 }
 
-#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct CodegenBackend {
     pub compiler: Compiler,
-    pub backend: String,
+    pub backend: CodegenBackendKind,
 }
 
 impl Step for CodegenBackend {
@@ -1389,7 +1383,7 @@ impl Step for CodegenBackend {
 
     fn make_run(run: RunConfig<'_>) {
         for backend in run.builder.config.codegen_backends(run.target) {
-            if backend == "llvm" {
+            if backend.is_llvm() {
                 continue; // Already built as part of rustc
             }
 
@@ -1412,12 +1406,11 @@ impl Step for CodegenBackend {
             return None;
         }
 
-        if !builder.config.codegen_backends(self.compiler.host).contains(&self.backend.to_string())
-        {
+        if !builder.config.codegen_backends(self.compiler.host).contains(&self.backend) {
             return None;
         }
 
-        if self.backend == "cranelift" && !target_supports_cranelift_backend(self.compiler.host) {
+        if self.backend.is_cranelift() && !target_supports_cranelift_backend(self.compiler.host) {
             builder.info("target not supported by rustc_codegen_cranelift. skipping");
             return None;
         }
@@ -1425,15 +1418,18 @@ impl Step for CodegenBackend {
         let compiler = self.compiler;
         let backend = self.backend;
 
-        let mut tarball =
-            Tarball::new(builder, &format!("rustc-codegen-{backend}"), &compiler.host.triple);
-        if backend == "cranelift" {
+        let mut tarball = Tarball::new(
+            builder,
+            &format!("rustc-codegen-{}", backend.name()),
+            &compiler.host.triple,
+        );
+        if backend.is_cranelift() {
             tarball.set_overlay(OverlayKind::RustcCodegenCranelift);
         } else {
-            panic!("Unknown backend rustc_codegen_{backend}");
+            panic!("Unknown codegen backend {}", backend.name());
         }
         tarball.is_preview(true);
-        tarball.add_legal_and_readme_to(format!("share/doc/rustc_codegen_{backend}"));
+        tarball.add_legal_and_readme_to(format!("share/doc/{}", backend.crate_name()));
 
         let src = builder.sysroot(compiler);
         let backends_src = builder.sysroot_codegen_backends(compiler);
@@ -1445,7 +1441,7 @@ impl Step for CodegenBackend {
         // Don't use custom libdir here because ^lib/ will be resolved again with installer
         let backends_dst = PathBuf::from("lib").join(backends_rel);
 
-        let backend_name = format!("rustc_codegen_{backend}");
+        let backend_name = backend.crate_name();
         let mut found_backend = false;
         for backend in fs::read_dir(&backends_src).unwrap() {
             let file_name = backend.unwrap().file_name();
@@ -1464,9 +1460,9 @@ impl Step for CodegenBackend {
     }
 }
 
-#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct Rustfmt {
-    pub compiler: Compiler,
+    pub build_compiler: Compiler,
     pub target: TargetSelection,
 }
 
@@ -1482,7 +1478,7 @@ impl Step for Rustfmt {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Rustfmt {
-            compiler: run.builder.compiler_for(
+            build_compiler: run.builder.compiler_for(
                 run.builder.top_stage,
                 run.builder.config.host_target,
                 run.target,
@@ -1492,14 +1488,13 @@ impl Step for Rustfmt {
     }
 
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
-        let compiler = self.compiler;
-        let target = self.target;
+        let compilers =
+            RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target);
 
-        builder.ensure(compile::Rustc::new(compiler, target));
+        let rustfmt = builder.ensure(tool::Rustfmt::from_compilers(compilers));
+        let cargofmt = builder.ensure(tool::Cargofmt::from_compilers(compilers));
 
-        let rustfmt = builder.ensure(tool::Rustfmt { compiler, target });
-        let cargofmt = builder.ensure(tool::Cargofmt { compiler, target });
-        let mut tarball = Tarball::new(builder, "rustfmt", &target.triple);
+        let mut tarball = Tarball::new(builder, "rustfmt", &self.target.triple);
         tarball.set_overlay(OverlayKind::Rustfmt);
         tarball.is_preview(true);
         tarball.add_file(&rustfmt.tool_path, "bin", FileType::Executable);
@@ -1546,7 +1541,7 @@ impl Step for Extended {
         let mut built_tools = HashSet::new();
         macro_rules! add_component {
             ($name:expr => $step:expr) => {
-                if let Some(tarball) = builder.ensure_if_default($step, Kind::Dist) {
+                if let Some(Some(tarball)) = builder.ensure_if_default($step, Kind::Dist) {
                     tarballs.push(tarball);
                     built_tools.insert($name);
                 }
@@ -1566,16 +1561,16 @@ impl Step for Extended {
 
         add_component!("rust-docs" => Docs { host: target });
         add_component!("rust-json-docs" => JsonDocs { host: target });
-        add_component!("cargo" => Cargo { compiler, target });
-        add_component!("rustfmt" => Rustfmt { compiler, target });
-        add_component!("rust-analyzer" => RustAnalyzer { compiler, target });
+        add_component!("cargo" => Cargo { build_compiler: compiler, target });
+        add_component!("rustfmt" => Rustfmt { build_compiler: compiler, target });
+        add_component!("rust-analyzer" => RustAnalyzer { build_compiler: compiler, target });
         add_component!("llvm-components" => LlvmTools { target });
-        add_component!("clippy" => Clippy { compiler, target });
-        add_component!("miri" => Miri { compiler, target });
+        add_component!("clippy" => Clippy { build_compiler: compiler, target });
+        add_component!("miri" => Miri { build_compiler: compiler, target });
         add_component!("analysis" => Analysis { compiler, target });
         add_component!("rustc-codegen-cranelift" => CodegenBackend {
             compiler: builder.compiler(stage, target),
-            backend: "cranelift".to_string(),
+            backend: CodegenBackendKind::Cranelift,
         });
         add_component!("llvm-bitcode-linker" => LlvmBitcodeLinker {
             build_compiler: compiler,
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 37418f640ac..d4539a0eb34 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -149,7 +149,7 @@ impl<P: Step> Step for RustbookSrc<P> {
             let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
 
             if let Some(compiler) = self.rustdoc_compiler {
-                let mut rustdoc = builder.rustdoc(compiler);
+                let mut rustdoc = builder.rustdoc_for_compiler(compiler);
                 rustdoc.pop();
                 let old_path = env::var_os("PATH").unwrap_or_default();
                 let new_path =
@@ -365,7 +365,7 @@ impl Step for Standalone {
             }
 
             let html = out.join(filename).with_extension("html");
-            let rustdoc = builder.rustdoc(compiler);
+            let rustdoc = builder.rustdoc_for_compiler(compiler);
             if up_to_date(&path, &html)
                 && up_to_date(&footer, &html)
                 && up_to_date(&favicon, &html)
@@ -463,7 +463,7 @@ impl Step for Releases {
         let html = out.join("releases.html");
         let tmppath = out.join("releases.md");
         let inpath = builder.src.join("RELEASES.md");
-        let rustdoc = builder.rustdoc(compiler);
+        let rustdoc = builder.rustdoc_for_compiler(compiler);
         if !up_to_date(&inpath, &html)
             || !up_to_date(&footer, &html)
             || !up_to_date(&favicon, &html)
@@ -811,7 +811,7 @@ impl Step for Rustc {
         let compiler = builder.compiler(stage, builder.config.host_target);
         builder.std(compiler, builder.config.host_target);
 
-        let _guard = builder.msg_sysroot_tool(
+        let _guard = builder.msg_rustc_tool(
             Kind::Doc,
             stage,
             format!("compiler{}", crate_description(&self.crates)),
@@ -901,6 +901,10 @@ impl Step for Rustc {
             builder.open_in_browser(index);
         }
     }
+
+    fn metadata(&self) -> Option<StepMetadata> {
+        Some(StepMetadata::doc("rustc", self.target).stage(self.stage))
+    }
 }
 
 macro_rules! tool_doc {
@@ -1018,6 +1022,10 @@ macro_rules! tool_doc {
                     })?
                 }
             }
+
+            fn metadata(&self) -> Option<StepMetadata> {
+                Some(StepMetadata::doc(stringify!($tool), self.target))
+            }
         }
     }
 }
diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs
index 4156b49a8b3..f628330e9ed 100644
--- a/src/bootstrap/src/core/build_steps/install.rs
+++ b/src/bootstrap/src/core/build_steps/install.rs
@@ -12,7 +12,7 @@ use crate::core::config::{Config, TargetSelection};
 use crate::utils::exec::command;
 use crate::utils::helpers::t;
 use crate::utils::tarball::GeneratedTarball;
-use crate::{Compiler, Kind};
+use crate::{CodegenBackendKind, Compiler, Kind};
 
 #[cfg(target_os = "illumos")]
 const SHELL: &str = "bash";
@@ -215,13 +215,13 @@ install!((self, builder, _config),
     };
     Cargo, alias = "cargo", Self::should_build(_config), only_hosts: true, {
         let tarball = builder
-            .ensure(dist::Cargo { compiler: self.compiler, target: self.target })
+            .ensure(dist::Cargo { build_compiler: self.compiler, target: self.target })
             .expect("missing cargo");
         install_sh(builder, "cargo", self.compiler.stage, Some(self.target), &tarball);
     };
     RustAnalyzer, alias = "rust-analyzer", Self::should_build(_config), only_hosts: true, {
         if let Some(tarball) =
-            builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
+            builder.ensure(dist::RustAnalyzer { build_compiler: self.compiler, target: self.target })
         {
             install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball);
         } else {
@@ -232,12 +232,12 @@ install!((self, builder, _config),
     };
     Clippy, alias = "clippy", Self::should_build(_config), only_hosts: true, {
         let tarball = builder
-            .ensure(dist::Clippy { compiler: self.compiler, target: self.target })
+            .ensure(dist::Clippy { build_compiler: self.compiler, target: self.target })
             .expect("missing clippy");
         install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball);
     };
     Miri, alias = "miri", Self::should_build(_config), only_hosts: true, {
-        if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) {
+        if let Some(tarball) = builder.ensure(dist::Miri { build_compiler: self.compiler, target: self.target }) {
             install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
         } else {
             // Miri is only available on nightly
@@ -257,7 +257,7 @@ install!((self, builder, _config),
     };
     Rustfmt, alias = "rustfmt", Self::should_build(_config), only_hosts: true, {
         if let Some(tarball) = builder.ensure(dist::Rustfmt {
-            compiler: self.compiler,
+            build_compiler: self.compiler,
             target: self.target
         }) {
             install_sh(builder, "rustfmt", self.compiler.stage, Some(self.target), &tarball);
@@ -276,7 +276,7 @@ install!((self, builder, _config),
     RustcCodegenCranelift, alias = "rustc-codegen-cranelift", Self::should_build(_config), only_hosts: true, {
         if let Some(tarball) = builder.ensure(dist::CodegenBackend {
             compiler: self.compiler,
-            backend: "cranelift".to_string(),
+            backend: CodegenBackendKind::Cranelift,
         }) {
             install_sh(builder, "rustc-codegen-cranelift", self.compiler.stage, Some(self.target), &tarball);
         } else {
diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs
index 4d61b38c876..108b7f90c14 100644
--- a/src/bootstrap/src/core/build_steps/perf.rs
+++ b/src/bootstrap/src/core/build_steps/perf.rs
@@ -157,7 +157,7 @@ Consider setting `rust.debuginfo-level = 1` in `bootstrap.toml`."#);
     if let Some(opts) = args.cmd.shared_opts()
         && opts.profiles.contains(&Profile::Doc)
     {
-        builder.ensure(Rustdoc { compiler });
+        builder.ensure(Rustdoc { target_compiler: compiler });
     }
 
     let sysroot = builder.ensure(Sysroot::new(compiler));
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index b2293fdd9b5..962dd372849 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -9,7 +9,7 @@ use clap_complete::{Generator, shells};
 
 use crate::core::build_steps::dist::distdir;
 use crate::core::build_steps::test;
-use crate::core::build_steps::tool::{self, SourceType, Tool};
+use crate::core::build_steps::tool::{self, RustcPrivateCompilers, SourceType, Tool};
 use crate::core::build_steps::vendor::{Vendor, default_paths_to_vendor};
 use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
 use crate::core::config::TargetSelection;
@@ -135,13 +135,13 @@ impl Step for Miri {
         }
 
         // This compiler runs on the host, we'll just use it for the target.
-        let target_compiler = builder.compiler(stage, target);
-        let miri_build = builder.ensure(tool::Miri { compiler: target_compiler, target });
-        // Rustc tools are off by one stage, so use the build compiler to run miri.
+        let compilers = RustcPrivateCompilers::new(builder, stage, target);
+        let miri_build = builder.ensure(tool::Miri::from_compilers(compilers));
         let host_compiler = miri_build.build_compiler;
 
         // Get a target sysroot for Miri.
-        let miri_sysroot = test::Miri::build_miri_sysroot(builder, target_compiler, target);
+        let miri_sysroot =
+            test::Miri::build_miri_sysroot(builder, compilers.target_compiler(), target);
 
         // # Run miri.
         // Running it via `cargo run` as that figures out the right dylib path.
@@ -465,8 +465,8 @@ impl Step for Rustfmt {
             std::process::exit(1);
         }
 
-        let compiler = builder.compiler(stage, host);
-        let rustfmt_build = builder.ensure(tool::Rustfmt { compiler, target: host });
+        let compilers = RustcPrivateCompilers::new(builder, stage, host);
+        let rustfmt_build = builder.ensure(tool::Rustfmt::from_compilers(compilers));
 
         let mut rustfmt = tool::prepare_tool_cargo(
             builder,
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 951ca73fcc4..09d2657b666 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -4,10 +4,12 @@
 //! However, this contains ~all test parts we expect people to be able to build and run locally.
 
 use std::collections::HashSet;
+use std::env::split_paths;
 use std::ffi::{OsStr, OsString};
 use std::path::{Path, PathBuf};
 use std::{env, fs, iter};
 
+use build_helper::exit;
 #[cfg(feature = "tracing")]
 use tracing::instrument;
 
@@ -17,7 +19,10 @@ use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags};
 use crate::core::build_steps::llvm::get_llvm_version;
 use crate::core::build_steps::run::get_completion_paths;
 use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;
-use crate::core::build_steps::tool::{self, COMPILETEST_ALLOW_FEATURES, SourceType, Tool};
+use crate::core::build_steps::tool::{
+    self, COMPILETEST_ALLOW_FEATURES, RustcPrivateCompilers, SourceType, Tool, ToolTargetBuildMode,
+    get_tool_target_compiler,
+};
 use crate::core::build_steps::toolstate::ToolState;
 use crate::core::build_steps::{compile, dist, llvm};
 use crate::core::builder::{
@@ -29,11 +34,11 @@ use crate::core::config::flags::{Subcommand, get_completion};
 use crate::utils::build_stamp::{self, BuildStamp};
 use crate::utils::exec::{BootstrapCommand, command};
 use crate::utils::helpers::{
-    self, LldThreads, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var, linker_args,
-    linker_flags, t, target_supports_cranelift_backend, up_to_date,
+    self, LldThreads, add_dylib_path, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var,
+    linker_args, linker_flags, t, target_supports_cranelift_backend, up_to_date,
 };
 use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};
-use crate::{CLang, DocTests, GitRepo, Mode, PathSet, debug, envify};
+use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, debug, envify};
 
 const ADB_TEST_DIR: &str = "/data/local/tmp/work";
 
@@ -226,7 +231,7 @@ impl Step for HtmlCheck {
 /// order to test cargo.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Cargotest {
-    stage: u32,
+    build_compiler: Compiler,
     host: TargetSelection,
 }
 
@@ -239,7 +244,19 @@ impl Step for Cargotest {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Cargotest { stage: run.builder.top_stage, host: run.target });
+        if run.builder.top_stage == 0 {
+            eprintln!(
+                "ERROR: running cargotest with stage 0 is currently unsupported. Use at least stage 1."
+            );
+            exit!(1);
+        }
+        // We want to build cargo stage N (where N == top_stage), and rustc stage N,
+        // and test both of these together.
+        // So we need to get a build compiler stage N-1 to build the stage N components.
+        run.builder.ensure(Cargotest {
+            build_compiler: run.builder.compiler(run.builder.top_stage - 1, run.target),
+            host: run.target,
+        });
     }
 
     /// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler.
@@ -247,9 +264,19 @@ impl Step for Cargotest {
     /// This tool in `src/tools` will check out a few Rust projects and run `cargo
     /// test` to ensure that we don't regress the test suites there.
     fn run(self, builder: &Builder<'_>) {
-        let compiler = builder.compiler(self.stage, self.host);
-        builder.ensure(compile::Rustc::new(compiler, compiler.host));
-        let cargo = builder.ensure(tool::Cargo { compiler, target: compiler.host });
+        // cargotest's staging has several pieces:
+        // consider ./x test cargotest --stage=2.
+        //
+        // The test goal is to exercise a (stage 2 cargo, stage 2 rustc) pair through a stage 2
+        // cargotest tool.
+        // To produce the stage 2 cargo and cargotest, we need to do so with the stage 1 rustc and std.
+        // Importantly, the stage 2 rustc being tested (`tested_compiler`) via stage 2 cargotest is
+        // the rustc built by an earlier stage 1 rustc (the build_compiler). These are two different
+        // compilers!
+        let cargo =
+            builder.ensure(tool::Cargo::from_build_compiler(self.build_compiler, self.host));
+        let tested_compiler = builder.compiler(self.build_compiler.stage + 1, self.host);
+        builder.std(tested_compiler, self.host);
 
         // Note that this is a short, cryptic, and not scoped directory name. This
         // is currently to minimize the length of path on Windows where we otherwise
@@ -262,23 +289,28 @@ impl Step for Cargotest {
         cmd.arg(&cargo.tool_path)
             .arg(&out_dir)
             .args(builder.config.test_args())
-            .env("RUSTC", builder.rustc(compiler))
-            .env("RUSTDOC", builder.rustdoc(compiler));
+            .env("RUSTC", builder.rustc(tested_compiler))
+            .env("RUSTDOC", builder.rustdoc_for_compiler(tested_compiler));
         add_rustdoc_cargo_linker_args(
             &mut cmd,
             builder,
-            compiler.host,
+            tested_compiler.host,
             LldThreads::No,
-            compiler.stage,
+            tested_compiler.stage,
         );
         cmd.delay_failure().run(builder);
     }
+
+    fn metadata(&self) -> Option<StepMetadata> {
+        Some(StepMetadata::test("cargotest", self.host).stage(self.build_compiler.stage + 1))
+    }
 }
 
 /// Runs `cargo test` for cargo itself.
+/// We label these tests as "cargo self-tests".
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Cargo {
-    stage: u32,
+    build_compiler: Compiler,
     host: TargetSelection,
 }
 
@@ -295,35 +327,33 @@ impl Step for Cargo {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        // If stage is explicitly set or not lower than 2, keep it. Otherwise, make sure it's at least 2
-        // as tests for this step don't work with a lower stage.
-        let stage = if run.builder.config.is_explicit_stage() || run.builder.top_stage >= 2 {
-            run.builder.top_stage
-        } else {
-            2
-        };
-
-        run.builder.ensure(Cargo { stage, host: run.target });
+        run.builder.ensure(Cargo {
+            build_compiler: get_tool_target_compiler(
+                run.builder,
+                ToolTargetBuildMode::Build(run.target),
+            ),
+            host: run.target,
+        });
     }
 
     /// Runs `cargo test` for `cargo` packaged with Rust.
     fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
-
-        if stage < 2 {
-            eprintln!("WARNING: cargo tests on stage {stage} may not behave well.");
-            eprintln!("HELP: consider using stage 2");
-        }
-
-        let compiler = builder.compiler(stage, self.host);
-
-        let cargo = builder.ensure(tool::Cargo { compiler, target: self.host });
-        let compiler = cargo.build_compiler;
+        // When we do a "stage 1 cargo self-test", it means that we test the stage 1 rustc
+        // using stage 1 cargo. So we actually build cargo using the stage 0 compiler, and then
+        // run its tests against the stage 1 compiler (called `tested_compiler` below).
+        builder.ensure(tool::Cargo::from_build_compiler(self.build_compiler, self.host));
+
+        let tested_compiler = builder.compiler(self.build_compiler.stage + 1, self.host);
+        builder.std(tested_compiler, self.host);
+        // We also need to build rustdoc for cargo tests
+        // It will be located in the bindir of `tested_compiler`, so we don't need to explicitly
+        // pass its path to Cargo.
+        builder.rustdoc_for_compiler(tested_compiler);
 
         let cargo = tool::prepare_tool_cargo(
             builder,
-            compiler,
-            Mode::ToolRustc,
+            self.build_compiler,
+            Mode::ToolTarget,
             self.host,
             Kind::Test,
             Self::CRATE_PATH,
@@ -340,7 +370,25 @@ impl Step for Cargo {
         // Forcibly disable tests using nightly features since any changes to
         // those features won't be able to land.
         cargo.env("CARGO_TEST_DISABLE_NIGHTLY", "1");
-        cargo.env("PATH", path_for_cargo(builder, compiler));
+
+        // Configure PATH to find the right rustc. NB. we have to use PATH
+        // and not RUSTC because the Cargo test suite has tests that will
+        // fail if rustc is not spelled `rustc`.
+        cargo.env("PATH", bin_path_for_cargo(builder, tested_compiler));
+
+        // The `cargo` command configured above has dylib dir path set to the `build_compiler`'s
+        // libdir. That causes issues in cargo test, because the programs that cargo compiles are
+        // incorrectly picking that libdir, even though they should be picking the
+        // `tested_compiler`'s libdir. We thus have to override the precedence here.
+        let mut existing_dylib_paths = cargo
+            .get_envs()
+            .find(|(k, _)| *k == OsStr::new(dylib_path_var()))
+            .and_then(|(_, v)| v)
+            .map(|value| split_paths(value).collect::<Vec<PathBuf>>())
+            .unwrap_or_default();
+        existing_dylib_paths.insert(0, builder.rustc_libdir(tested_compiler));
+        add_dylib_path(existing_dylib_paths, &mut cargo);
+
         // Cargo's test suite uses `CARGO_RUSTC_CURRENT_DIR` to determine the path that `file!` is
         // relative to. Cargo no longer sets this env var, so we have to do that. This has to be the
         // same value as `-Zroot-dir`.
@@ -352,7 +400,7 @@ impl Step for Cargo {
                 crates: vec!["cargo".into()],
                 target: self.host.triple.to_string(),
                 host: self.host.triple.to_string(),
-                stage,
+                stage: self.build_compiler.stage + 1,
             },
             builder,
         );
@@ -364,8 +412,7 @@ impl Step for Cargo {
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RustAnalyzer {
-    stage: u32,
-    host: TargetSelection,
+    compilers: RustcPrivateCompilers,
 }
 
 impl Step for RustAnalyzer {
@@ -378,19 +425,18 @@ impl Step for RustAnalyzer {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Self { stage: run.builder.top_stage, host: run.target });
+        run.builder.ensure(Self {
+            compilers: RustcPrivateCompilers::new(
+                run.builder,
+                run.builder.top_stage,
+                run.builder.host_target,
+            ),
+        });
     }
 
     /// Runs `cargo test` for rust-analyzer
     fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
-        let host = self.host;
-        let compiler = builder.compiler(stage, host);
-        let compiler = tool::get_tool_rustc_compiler(builder, compiler);
-
-        // We don't need to build the whole Rust Analyzer for the proc-macro-srv test suite,
-        // but we do need the standard library to be present.
-        builder.ensure(compile::Rustc::new(compiler, host));
+        let host = self.compilers.target();
 
         let workspace_path = "src/tools/rust-analyzer";
         // until the whole RA test suite runs on `i686`, we only run
@@ -398,7 +444,7 @@ impl Step for RustAnalyzer {
         let crate_path = "src/tools/rust-analyzer/crates/proc-macro-srv";
         let mut cargo = tool::prepare_tool_cargo(
             builder,
-            compiler,
+            self.compilers.build_compiler(),
             Mode::ToolRustc,
             host,
             Kind::Test,
@@ -425,8 +471,7 @@ impl Step for RustAnalyzer {
 /// Runs `cargo test` for rustfmt.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Rustfmt {
-    stage: u32,
-    host: TargetSelection,
+    compilers: RustcPrivateCompilers,
 }
 
 impl Step for Rustfmt {
@@ -438,36 +483,39 @@ impl Step for Rustfmt {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Rustfmt { stage: run.builder.top_stage, host: run.target });
+        run.builder.ensure(Rustfmt {
+            compilers: RustcPrivateCompilers::new(
+                run.builder,
+                run.builder.top_stage,
+                run.builder.host_target,
+            ),
+        });
     }
 
     /// Runs `cargo test` for rustfmt.
     fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
-        let host = self.host;
-        let compiler = builder.compiler(stage, host);
-
-        let tool_result = builder.ensure(tool::Rustfmt { compiler, target: self.host });
-        let compiler = tool_result.build_compiler;
+        let tool_result = builder.ensure(tool::Rustfmt::from_compilers(self.compilers));
+        let build_compiler = tool_result.build_compiler;
+        let target = self.compilers.target();
 
         let mut cargo = tool::prepare_tool_cargo(
             builder,
-            compiler,
+            build_compiler,
             Mode::ToolRustc,
-            host,
+            target,
             Kind::Test,
             "src/tools/rustfmt",
             SourceType::InTree,
             &[],
         );
 
-        let dir = testdir(builder, compiler.host);
+        let dir = testdir(builder, target);
         t!(fs::create_dir_all(&dir));
         cargo.env("RUSTFMT_TEST_DIR", dir);
 
         cargo.add_rustc_lib_path(builder);
 
-        run_cargo_test(cargo, &[], &[], "rustfmt", host, builder);
+        run_cargo_test(cargo, &[], &[], "rustfmt", target, builder);
     }
 }
 
@@ -542,12 +590,14 @@ impl Step for Miri {
         }
 
         // This compiler runs on the host, we'll just use it for the target.
-        let target_compiler = builder.compiler(stage, host);
+        let compilers = RustcPrivateCompilers::new(builder, stage, host);
 
         // Build our tools.
-        let miri = builder.ensure(tool::Miri { compiler: target_compiler, target: host });
+        let miri = builder.ensure(tool::Miri::from_compilers(compilers));
         // the ui tests also assume cargo-miri has been built
-        builder.ensure(tool::CargoMiri { compiler: target_compiler, target: host });
+        builder.ensure(tool::CargoMiri::from_compilers(compilers));
+
+        let target_compiler = compilers.target_compiler();
 
         // We also need sysroots, for Miri and for the host (the latter for build scripts).
         // This is for the tests so everything is done with the target compiler.
@@ -599,7 +649,7 @@ impl Step for Miri {
         cargo.env("MIRI_TEST_TARGET", target.rustc_target_arg());
 
         {
-            let _guard = builder.msg_sysroot_tool(Kind::Test, stage, "miri", host, target);
+            let _guard = builder.msg_rustc_tool(Kind::Test, stage, "miri", host, target);
             let _time = helpers::timeit(builder);
             cargo.run(builder);
         }
@@ -615,7 +665,7 @@ impl Step for Miri {
             cargo.args(["tests/pass", "tests/panic"]);
 
             {
-                let _guard = builder.msg_sysroot_tool(
+                let _guard = builder.msg_rustc_tool(
                     Kind::Test,
                     stage,
                     "miri (mir-opt-level 4)",
@@ -692,7 +742,7 @@ impl Step for CargoMiri {
         // Finally, run everything.
         let mut cargo = BootstrapCommand::from(cargo);
         {
-            let _guard = builder.msg_sysroot_tool(Kind::Test, stage, "cargo-miri", host, target);
+            let _guard = builder.msg_rustc_tool(Kind::Test, stage, "cargo-miri", host, target);
             let _time = helpers::timeit(builder);
             cargo.run(builder);
         }
@@ -749,6 +799,12 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             SourceType::InTree,
             &[],
         );
+
+        // Used for `compiletest` self-tests to have the path to the *staged* compiler. Getting this
+        // right is important, as `compiletest` is intended to only support one target spec JSON
+        // format, namely that of the staged compiler.
+        cargo.env("TEST_RUSTC", builder.rustc(compiler));
+
         cargo.allow_features(COMPILETEST_ALLOW_FEATURES);
         run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder);
     }
@@ -756,7 +812,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Clippy {
-    host: TargetSelection,
+    compilers: RustcPrivateCompilers,
 }
 
 impl Step for Clippy {
@@ -769,23 +825,30 @@ impl Step for Clippy {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Clippy { host: run.target });
+        run.builder.ensure(Clippy {
+            compilers: RustcPrivateCompilers::new(
+                run.builder,
+                run.builder.top_stage,
+                run.builder.host_target,
+            ),
+        });
     }
 
     /// Runs `cargo test` for clippy.
     fn run(self, builder: &Builder<'_>) {
-        let stage = builder.top_stage;
-        let host = self.host;
+        let host = self.compilers.target();
+
         // We need to carefully distinguish the compiler that builds clippy, and the compiler
         // that is linked into the clippy being tested. `target_compiler` is the latter,
         // and it must also be used by clippy's test runner to build tests and their dependencies.
-        let target_compiler = builder.compiler(stage, host);
+        let compilers = self.compilers;
+        let target_compiler = compilers.target_compiler();
 
-        let tool_result = builder.ensure(tool::Clippy { compiler: target_compiler, target: host });
-        let tool_compiler = tool_result.build_compiler;
+        let tool_result = builder.ensure(tool::Clippy::from_compilers(compilers));
+        let build_compiler = tool_result.build_compiler;
         let mut cargo = tool::prepare_tool_cargo(
             builder,
-            tool_compiler,
+            build_compiler,
             Mode::ToolRustc,
             host,
             Kind::Test,
@@ -794,9 +857,10 @@ impl Step for Clippy {
             &[],
         );
 
-        cargo.env("RUSTC_TEST_SUITE", builder.rustc(tool_compiler));
-        cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(tool_compiler));
-        let host_libs = builder.stage_out(tool_compiler, Mode::ToolRustc).join(builder.cargo_dir());
+        cargo.env("RUSTC_TEST_SUITE", builder.rustc(build_compiler));
+        cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(build_compiler));
+        let host_libs =
+            builder.stage_out(build_compiler, Mode::ToolRustc).join(builder.cargo_dir());
         cargo.env("HOST_LIBS", host_libs);
 
         // Build the standard library that the tests can use.
@@ -825,8 +889,7 @@ impl Step for Clippy {
         cargo.add_rustc_lib_path(builder);
         let cargo = prepare_cargo_test(cargo, &[], &[], host, builder);
 
-        let _guard =
-            builder.msg_sysroot_tool(Kind::Test, tool_compiler.stage, "clippy", host, host);
+        let _guard = builder.msg_rustc_tool(Kind::Test, build_compiler.stage, "clippy", host, host);
 
         // Clippy reports errors if it blessed the outputs
         if cargo.allow_failure().run(builder) {
@@ -840,10 +903,7 @@ impl Step for Clippy {
     }
 }
 
-fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString {
-    // Configure PATH to find the right rustc. NB. we have to use PATH
-    // and not RUSTC because the Cargo test suite has tests that will
-    // fail if rustc is not spelled `rustc`.
+fn bin_path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString {
     let path = builder.sysroot(compiler).join("bin");
     let old_path = env::var_os("PATH").unwrap_or_default();
     env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
@@ -878,7 +938,7 @@ impl Step for RustdocTheme {
             .env("RUSTC_SYSROOT", builder.sysroot(self.compiler))
             .env("RUSTDOC_LIBDIR", builder.sysroot_target_libdir(self.compiler, self.compiler.host))
             .env("CFG_RELEASE_CHANNEL", &builder.config.channel)
-            .env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
+            .env("RUSTDOC_REAL", builder.rustdoc_for_compiler(self.compiler))
             .env("RUSTC_BOOTSTRAP", "1");
         cmd.args(linker_args(builder, self.compiler.host, LldThreads::No, self.compiler.stage));
 
@@ -1037,7 +1097,11 @@ impl Step for RustdocGUI {
         let mut cmd = builder.tool_cmd(Tool::RustdocGUITest);
 
         let out_dir = builder.test_out(self.target).join("rustdoc-gui");
-        build_stamp::clear_if_dirty(builder, &out_dir, &builder.rustdoc(self.compiler));
+        build_stamp::clear_if_dirty(
+            builder,
+            &out_dir,
+            &builder.rustdoc_for_compiler(self.compiler),
+        );
 
         if let Some(src) = builder.config.src.to_str() {
             cmd.arg("--rust-src").arg(src);
@@ -1053,7 +1117,7 @@ impl Step for RustdocGUI {
 
         cmd.arg("--jobs").arg(builder.jobs().to_string());
 
-        cmd.env("RUSTDOC", builder.rustdoc(self.compiler))
+        cmd.env("RUSTDOC", builder.rustdoc_for_compiler(self.compiler))
             .env("RUSTC", builder.rustc(self.compiler));
 
         add_rustdoc_cargo_linker_args(
@@ -1089,7 +1153,7 @@ impl Step for RustdocGUI {
         }
 
         let _time = helpers::timeit(builder);
-        let _guard = builder.msg_sysroot_tool(
+        let _guard = builder.msg_rustc_tool(
             Kind::Test,
             self.compiler.stage,
             "rustdoc-gui",
@@ -1657,7 +1721,11 @@ 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 query_compiler;
         let (stage, stage_id) = if suite == "ui-fulldeps" && compiler.stage == 1 {
+            // Even when using the stage 0 compiler, we also need to provide the stage 1 compiler
+            // so that compiletest can query it for target information.
+            query_compiler = Some(compiler);
             // At stage 0 (stage - 1) we are using the stage0 compiler. Using `self.target` can lead
             // finding an incorrect compiler path on cross-targets, as the stage 0 is always equal to
             // `build.build` in the configuration.
@@ -1666,6 +1734,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             let test_stage = compiler.stage + 1;
             (test_stage, format!("stage{test_stage}-{build}"))
         } else {
+            query_compiler = None;
             let stage = compiler.stage;
             (stage, format!("stage{stage}-{target}"))
         };
@@ -1710,6 +1779,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         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));
+        if let Some(query_compiler) = query_compiler {
+            cmd.arg("--query-rustc-path").arg(builder.rustc(query_compiler));
+        }
 
         // Minicore auxiliary lib for `no_core` tests that need `core` stubs in cross-compilation
         // scenarios.
@@ -1723,7 +1795,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
                 // If we're using `--stage 0`, we should provide the bootstrap cargo.
                 builder.initial_cargo.clone()
             } else {
-                builder.ensure(tool::Cargo { compiler, target: compiler.host }).tool_path
+                builder.ensure(tool::Cargo::from_build_compiler(compiler, compiler.host)).tool_path
             };
 
             cmd.arg("--cargo-path").arg(cargo_path);
@@ -1742,7 +1814,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             || mode == "rustdoc-json"
             || suite == "coverage-run-rustdoc"
         {
-            cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler));
+            cmd.arg("--rustdoc-path").arg(builder.rustdoc_for_compiler(compiler));
         }
 
         if mode == "rustdoc-json" {
@@ -1786,7 +1858,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target));
 
         if let Some(codegen_backend) = builder.config.default_codegen_backend(compiler.host) {
-            cmd.arg("--codegen-backend").arg(&codegen_backend);
+            // Tells compiletest which codegen backend is used by default by the compiler.
+            // It is used to e.g. ignore tests that don't support that codegen backend.
+            cmd.arg("--codegen-backend").arg(codegen_backend.name());
         }
 
         if builder.build.config.llvm_enzyme {
@@ -2256,7 +2330,7 @@ impl BookTest {
 
         // mdbook just executes a binary named "rustdoc", so we need to update
         // PATH so that it points to our rustdoc.
-        let mut rustdoc_path = builder.rustdoc(compiler);
+        let mut rustdoc_path = builder.rustdoc_for_compiler(compiler);
         rustdoc_path.pop();
         let old_path = env::var_os("PATH").unwrap_or_default();
         let new_path = env::join_paths(iter::once(rustdoc_path).chain(env::split_paths(&old_path)))
@@ -2579,7 +2653,7 @@ fn run_cargo_test<'a>(
     let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, target, builder);
     let _time = helpers::timeit(builder);
     let _group = description.into().and_then(|what| {
-        builder.msg_sysroot_tool(Kind::Test, compiler.stage, what, compiler.host, target)
+        builder.msg_rustc_tool(Kind::Test, compiler.stage, what, compiler.host, target)
     });
 
     #[cfg(feature = "build-metrics")]
@@ -3406,7 +3480,7 @@ impl Step for CodegenCranelift {
             return;
         }
 
-        if !builder.config.codegen_backends(run.target).contains(&"cranelift".to_owned()) {
+        if !builder.config.codegen_backends(run.target).contains(&CodegenBackendKind::Cranelift) {
             builder.info("cranelift not in rust.codegen-backends. skipping");
             return;
         }
@@ -3533,7 +3607,7 @@ impl Step for CodegenGCC {
             return;
         }
 
-        if !builder.config.codegen_backends(run.target).contains(&"gcc".to_owned()) {
+        if !builder.config.codegen_backends(run.target).contains(&CodegenBackendKind::Gcc) {
             builder.info("gcc not in rust.codegen-backends. skipping");
             return;
         }
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index f5fa33b98f3..e3f49fa126e 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -71,13 +71,9 @@ impl Builder<'_> {
     ) -> Option<gha::Group> {
         match mode {
             // depends on compiler stage, different to host compiler
-            Mode::ToolRustc => self.msg_sysroot_tool(
-                kind,
-                build_stage,
-                format_args!("tool {tool}"),
-                *host,
-                *target,
-            ),
+            Mode::ToolRustc => {
+                self.msg_rustc_tool(kind, build_stage, format_args!("tool {tool}"), *host, *target)
+            }
             // doesn't depend on compiler, same as host compiler
             _ => self.msg(kind, build_stage, format_args!("tool {tool}"), *host, *target),
         }
@@ -90,11 +86,8 @@ impl Builder<'_> {
 pub struct ToolBuildResult {
     /// Artifact path of the corresponding tool that was built.
     pub tool_path: PathBuf,
-    /// Compiler used to build the tool. For non-`ToolRustc` tools this is equal to `target_compiler`.
-    /// For `ToolRustc` this is one stage before of the `target_compiler`.
+    /// Compiler used to build the tool.
     pub build_compiler: Compiler,
-    /// Target compiler passed to `Step`.
-    pub target_compiler: Compiler,
 }
 
 impl Step for ToolBuild {
@@ -108,22 +101,15 @@ impl Step for ToolBuild {
     ///
     /// This will build the specified tool with the specified `host` compiler in
     /// `stage` into the normal cargo output directory.
-    fn run(mut self, builder: &Builder<'_>) -> ToolBuildResult {
+    fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
         let target = self.target;
         let mut tool = self.tool;
         let path = self.path;
 
-        let target_compiler = self.build_compiler;
-        self.build_compiler = if self.mode == Mode::ToolRustc {
-            get_tool_rustc_compiler(builder, self.build_compiler)
-        } else {
-            self.build_compiler
-        };
-
         match self.mode {
             Mode::ToolRustc => {
-                // If compiler was forced, its artifacts should have been prepared earlier.
-                if !self.build_compiler.is_forced_compiler() {
+                // FIXME: remove this, it's only needed for download-rustc...
+                if !self.build_compiler.is_forced_compiler() && builder.download_rustc() {
                     builder.std(self.build_compiler, self.build_compiler.host);
                     builder.ensure(compile::Rustc::new(self.build_compiler, target));
                 }
@@ -184,8 +170,7 @@ impl Step for ToolBuild {
             Kind::Build,
             self.mode,
             self.tool,
-            // A stage N tool is built with the stage N-1 compiler.
-            self.build_compiler.stage + 1,
+            self.build_compiler.stage,
             &self.build_compiler.host,
             &self.target,
         );
@@ -216,7 +201,7 @@ impl Step for ToolBuild {
                     .join(format!("lib{tool}.rlib")),
             };
 
-            ToolBuildResult { tool_path, build_compiler: self.build_compiler, target_compiler }
+            ToolBuildResult { tool_path, build_compiler: self.build_compiler }
         }
     }
 }
@@ -346,27 +331,6 @@ pub fn prepare_tool_cargo(
     cargo
 }
 
-/// Handle stage-off logic for `ToolRustc` tools when necessary.
-pub(crate) fn get_tool_rustc_compiler(
-    builder: &Builder<'_>,
-    target_compiler: Compiler,
-) -> Compiler {
-    if target_compiler.is_forced_compiler() {
-        return target_compiler;
-    }
-
-    if builder.download_rustc() && target_compiler.stage == 1 {
-        // We shouldn't drop to stage0 compiler when using CI rustc.
-        return builder.compiler(1, builder.config.host_target);
-    }
-
-    // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise
-    // we'd have stageN/bin/rustc and stageN/bin/$rustc_tool be effectively different stage
-    // compilers, which isn't what we want. Rustc tools should be linked in the same way as the
-    // compiler it's paired with, so it must be built with the previous stage compiler.
-    builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.host_target)
-}
-
 /// Determines how to build a `ToolTarget`, i.e. which compiler should be used to compile it.
 /// The compiler stage is automatically bumped if we need to cross-compile a stage 1 tool.
 pub enum ToolTargetBuildMode {
@@ -719,15 +683,21 @@ impl Step for RemoteTestServer {
     }
 }
 
-#[derive(Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
+/// Represents `Rustdoc` that either comes from the external stage0 sysroot or that is built
+/// locally.
+/// Rustdoc is special, because it both essentially corresponds to a `Compiler` (that can be
+/// externally provided), but also to a `ToolRustc` tool.
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct Rustdoc {
-    /// This should only ever be 0 or 2.
-    /// We sometimes want to reference the "bootstrap" rustdoc, which is why this option is here.
-    pub compiler: Compiler,
+    /// If the stage of `target_compiler` is `0`, then rustdoc is externally provided.
+    /// Otherwise it is built locally.
+    pub target_compiler: Compiler,
 }
 
 impl Step for Rustdoc {
-    type Output = ToolBuildResult;
+    /// Path to the built rustdoc binary.
+    type Output = PathBuf;
+
     const DEFAULT: bool = true;
     const ONLY_HOSTS: bool = true;
 
@@ -736,26 +706,25 @@ impl Step for Rustdoc {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder
-            .ensure(Rustdoc { compiler: run.builder.compiler(run.builder.top_stage, run.target) });
+        run.builder.ensure(Rustdoc {
+            target_compiler: run.builder.compiler(run.builder.top_stage, run.target),
+        });
     }
 
-    fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
-        let target_compiler = self.compiler;
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let target_compiler = self.target_compiler;
         let target = target_compiler.host;
 
+        // If stage is 0, we use a prebuilt rustdoc from stage0
         if target_compiler.stage == 0 {
             if !target_compiler.is_snapshot(builder) {
                 panic!("rustdoc in stage 0 must be snapshot rustdoc");
             }
 
-            return ToolBuildResult {
-                tool_path: builder.initial_rustdoc.clone(),
-                build_compiler: target_compiler,
-                target_compiler,
-            };
+            return builder.initial_rustdoc.clone();
         }
 
+        // If stage is higher, we build rustdoc instead
         let bin_rustdoc = || {
             let sysroot = builder.sysroot(target_compiler);
             let bindir = sysroot.join("bin");
@@ -767,10 +736,7 @@ impl Step for Rustdoc {
 
         // If CI rustc is enabled and we haven't modified the rustdoc sources,
         // use the precompiled rustdoc from CI rustc's sysroot to speed up bootstrapping.
-        if builder.download_rustc()
-            && target_compiler.stage > 0
-            && builder.rust_info().is_managed_git_subrepository()
-        {
+        if builder.download_rustc() && builder.rust_info().is_managed_git_subrepository() {
             let files_to_track = &["src/librustdoc", "src/tools/rustdoc", "src/rustdoc-json-types"];
 
             // Check if unchanged
@@ -783,12 +749,7 @@ impl Step for Rustdoc {
 
                 let bin_rustdoc = bin_rustdoc();
                 builder.copy_link(&precompiled_rustdoc, &bin_rustdoc, FileType::Executable);
-
-                return ToolBuildResult {
-                    tool_path: bin_rustdoc,
-                    build_compiler: target_compiler,
-                    target_compiler,
-                };
+                return bin_rustdoc;
             }
         }
 
@@ -804,9 +765,10 @@ impl Step for Rustdoc {
             extra_features.push("jemalloc".to_string());
         }
 
-        let ToolBuildResult { tool_path, build_compiler, target_compiler } =
-            builder.ensure(ToolBuild {
-                build_compiler: target_compiler,
+        let compilers = RustcPrivateCompilers::from_target_compiler(builder, target_compiler);
+        let tool_path = builder
+            .ensure(ToolBuild {
+                build_compiler: compilers.build_compiler,
                 target,
                 // Cargo adds a number of paths to the dylib search path on windows, which results in
                 // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
@@ -819,38 +781,41 @@ impl Step for Rustdoc {
                 allow_features: "",
                 cargo_args: Vec::new(),
                 artifact_kind: ToolArtifactKind::Binary,
-            });
-
-        // don't create a stage0-sysroot/bin directory.
-        if target_compiler.stage > 0 {
-            if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None {
-                // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into
-                // our final binaries
-                compile::strip_debug(builder, target, &tool_path);
-            }
-            let bin_rustdoc = bin_rustdoc();
-            builder.copy_link(&tool_path, &bin_rustdoc, FileType::Executable);
-            ToolBuildResult { tool_path: bin_rustdoc, build_compiler, target_compiler }
-        } else {
-            ToolBuildResult { tool_path, build_compiler, target_compiler }
+            })
+            .tool_path;
+
+        if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None {
+            // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into
+            // our final binaries
+            compile::strip_debug(builder, target, &tool_path);
         }
+        let bin_rustdoc = bin_rustdoc();
+        builder.copy_link(&tool_path, &bin_rustdoc, FileType::Executable);
+        bin_rustdoc
     }
 
     fn metadata(&self) -> Option<StepMetadata> {
         Some(
-            StepMetadata::build("rustdoc", self.compiler.host)
-                // rustdoc is ToolRustc, so stage N rustdoc is built by stage N-1 rustc
-                // FIXME: make this stage deduction automatic somehow
-                // FIXME: log the compiler that actually built ToolRustc steps
-                .stage(self.compiler.stage.saturating_sub(1)),
+            StepMetadata::build("rustdoc", self.target_compiler.host)
+                .stage(self.target_compiler.stage),
         )
     }
 }
 
+/// Builds the cargo tool.
+/// Note that it can be built using a stable compiler.
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct Cargo {
-    pub compiler: Compiler,
-    pub target: TargetSelection,
+    build_compiler: Compiler,
+    target: TargetSelection,
+}
+
+impl Cargo {
+    /// Returns `Cargo` that will be **compiled** by the passed compiler, for the given
+    /// `target`.
+    pub fn from_build_compiler(build_compiler: Compiler, target: TargetSelection) -> Self {
+        Self { build_compiler, target }
+    }
 }
 
 impl Step for Cargo {
@@ -865,7 +830,10 @@ impl Step for Cargo {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Cargo {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
+            build_compiler: get_tool_target_compiler(
+                run.builder,
+                ToolTargetBuildMode::Build(run.target),
+            ),
             target: run.target,
         });
     }
@@ -873,19 +841,28 @@ impl Step for Cargo {
     fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
         builder.build.require_submodule("src/tools/cargo", None);
 
+        builder.std(self.build_compiler, self.target);
         builder.ensure(ToolBuild {
-            build_compiler: self.compiler,
+            build_compiler: self.build_compiler,
             target: self.target,
             tool: "cargo",
-            mode: Mode::ToolRustc,
+            mode: Mode::ToolTarget,
             path: "src/tools/cargo",
             source_type: SourceType::Submodule,
             extra_features: Vec::new(),
-            allow_features: "",
+            // Cargo is compilable with a stable compiler, but since we run in bootstrap,
+            // with RUSTC_BOOTSTRAP being set, some "clever" build scripts enable specialization
+            // based on this, which breaks stuff. We thus have to explicitly allow these features
+            // here.
+            allow_features: "min_specialization,specialization",
             cargo_args: Vec::new(),
             artifact_kind: ToolArtifactKind::Binary,
         })
     }
+
+    fn metadata(&self) -> Option<StepMetadata> {
+        Some(StepMetadata::build("cargo", self.target).built_by(self.build_compiler))
+    }
 }
 
 /// Represents a built LldWrapper, the `lld-wrapper` tool itself, and a directory
@@ -1066,8 +1043,13 @@ impl Step for WasmComponentLd {
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct RustAnalyzer {
-    pub compiler: Compiler,
-    pub target: TargetSelection,
+    compilers: RustcPrivateCompilers,
+}
+
+impl RustAnalyzer {
+    pub fn from_compilers(compilers: RustcPrivateCompilers) -> Self {
+        Self { compilers }
+    }
 }
 
 impl RustAnalyzer {
@@ -1086,15 +1068,16 @@ impl Step for RustAnalyzer {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(RustAnalyzer {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
-            target: run.target,
+            compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target),
         });
     }
 
     fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
+        let build_compiler = self.compilers.build_compiler;
+        let target = self.compilers.target();
         builder.ensure(ToolBuild {
-            build_compiler: self.compiler,
-            target: self.target,
+            build_compiler,
+            target,
             tool: "rust-analyzer",
             mode: Mode::ToolRustc,
             path: "src/tools/rust-analyzer",
@@ -1105,16 +1088,29 @@ impl Step for RustAnalyzer {
             artifact_kind: ToolArtifactKind::Binary,
         })
     }
+
+    fn metadata(&self) -> Option<StepMetadata> {
+        Some(
+            StepMetadata::build("rust-analyzer", self.compilers.target())
+                .built_by(self.compilers.build_compiler),
+        )
+    }
 }
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct RustAnalyzerProcMacroSrv {
-    pub compiler: Compiler,
-    pub target: TargetSelection,
+    compilers: RustcPrivateCompilers,
+}
+
+impl RustAnalyzerProcMacroSrv {
+    pub fn from_compilers(compilers: RustcPrivateCompilers) -> Self {
+        Self { compilers }
+    }
 }
 
 impl Step for RustAnalyzerProcMacroSrv {
-    type Output = Option<ToolBuildResult>;
+    type Output = ToolBuildResult;
+
     const DEFAULT: bool = true;
     const ONLY_HOSTS: bool = true;
 
@@ -1131,15 +1127,14 @@ impl Step for RustAnalyzerProcMacroSrv {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(RustAnalyzerProcMacroSrv {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
-            target: run.target,
+            compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target),
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> Option<ToolBuildResult> {
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
         let tool_result = builder.ensure(ToolBuild {
-            build_compiler: self.compiler,
-            target: self.target,
+            build_compiler: self.compilers.build_compiler,
+            target: self.compilers.target(),
             tool: "rust-analyzer-proc-macro-srv",
             mode: Mode::ToolRustc,
             path: "src/tools/rust-analyzer/crates/proc-macro-srv-cli",
@@ -1152,7 +1147,7 @@ impl Step for RustAnalyzerProcMacroSrv {
 
         // Copy `rust-analyzer-proc-macro-srv` to `<sysroot>/libexec/`
         // so that r-a can use it.
-        let libexec_path = builder.sysroot(self.compiler).join("libexec");
+        let libexec_path = builder.sysroot(self.compilers.target_compiler).join("libexec");
         t!(fs::create_dir_all(&libexec_path));
         builder.copy_link(
             &tool_result.tool_path,
@@ -1160,7 +1155,14 @@ impl Step for RustAnalyzerProcMacroSrv {
             FileType::Executable,
         );
 
-        Some(tool_result)
+        tool_result
+    }
+
+    fn metadata(&self) -> Option<StepMetadata> {
+        Some(
+            StepMetadata::build("rust-analyzer-proc-macro-srv", self.compilers.target())
+                .built_by(self.compilers.build_compiler),
+        )
     }
 }
 
@@ -1302,7 +1304,92 @@ impl Step for LibcxxVersionTool {
     }
 }
 
-macro_rules! tool_extended {
+/// Represents which compilers are involved in the compilation of a tool
+/// that depends on compiler internals (`rustc_private`).
+/// Their compilation looks like this:
+///
+/// - `build_compiler` (stage N-1) builds `target_compiler` (stage N) to produce .rlibs
+///     - These .rlibs are copied into the sysroot of `build_compiler`
+/// - `build_compiler` (stage N-1) builds `<tool>` (stage N)
+///     - `<tool>` links to .rlibs from `target_compiler`
+///
+/// Eventually, this could also be used for .rmetas and check builds, but so far we only deal with
+/// normal builds here.
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+pub struct RustcPrivateCompilers {
+    /// Compiler that builds the tool and that builds `target_compiler`.
+    build_compiler: Compiler,
+    /// Compiler to which .rlib artifacts the tool links to.
+    /// The host target of this compiler corresponds to the target of the tool.
+    target_compiler: Compiler,
+}
+
+impl RustcPrivateCompilers {
+    /// Create compilers for a `rustc_private` tool with the given `stage` and for the given
+    /// `target`.
+    pub fn new(builder: &Builder<'_>, stage: u32, target: TargetSelection) -> Self {
+        let build_compiler = Self::build_compiler_from_stage(builder, stage);
+
+        // This is the compiler we'll link to
+        // FIXME: make 100% sure that `target_compiler` was indeed built with `build_compiler`...
+        let target_compiler = builder.compiler(build_compiler.stage + 1, target);
+
+        Self { build_compiler, target_compiler }
+    }
+
+    pub fn from_build_and_target_compiler(
+        build_compiler: Compiler,
+        target_compiler: Compiler,
+    ) -> Self {
+        Self { build_compiler, target_compiler }
+    }
+
+    /// Create rustc tool compilers from the build compiler.
+    pub fn from_build_compiler(
+        builder: &Builder<'_>,
+        build_compiler: Compiler,
+        target: TargetSelection,
+    ) -> Self {
+        let target_compiler = builder.compiler(build_compiler.stage + 1, target);
+        Self { build_compiler, target_compiler }
+    }
+
+    /// Create rustc tool compilers from the target compiler.
+    pub fn from_target_compiler(builder: &Builder<'_>, target_compiler: Compiler) -> Self {
+        Self {
+            build_compiler: Self::build_compiler_from_stage(builder, target_compiler.stage),
+            target_compiler,
+        }
+    }
+
+    fn build_compiler_from_stage(builder: &Builder<'_>, stage: u32) -> Compiler {
+        assert!(stage > 0);
+
+        if builder.download_rustc() && stage == 1 {
+            // We shouldn't drop to stage0 compiler when using CI rustc.
+            builder.compiler(1, builder.config.host_target)
+        } else {
+            builder.compiler(stage - 1, builder.config.host_target)
+        }
+    }
+
+    pub fn build_compiler(&self) -> Compiler {
+        self.build_compiler
+    }
+
+    pub fn target_compiler(&self) -> Compiler {
+        self.target_compiler
+    }
+
+    /// Target of the tool being compiled
+    pub fn target(&self) -> TargetSelection {
+        self.target_compiler.host
+    }
+}
+
+/// Creates a step that builds an extended `Mode::ToolRustc` tool
+/// and installs it into the sysroot of a corresponding compiler.
+macro_rules! tool_rustc_extended {
     (
         $name:ident {
             path: $path:expr,
@@ -1316,8 +1403,15 @@ macro_rules! tool_extended {
     ) => {
         #[derive(Debug, Clone, Hash, PartialEq, Eq)]
         pub struct $name {
-            pub compiler: Compiler,
-            pub target: TargetSelection,
+            compilers: RustcPrivateCompilers,
+        }
+
+        impl $name {
+            pub fn from_compilers(compilers: RustcPrivateCompilers) -> Self {
+                Self {
+                    compilers,
+                }
+            }
         }
 
         impl Step for $name {
@@ -1326,7 +1420,7 @@ macro_rules! tool_extended {
             const ONLY_HOSTS: bool = true;
 
             fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-                should_run_tool_build_step(
+                should_run_extended_rustc_tool(
                     run,
                     $tool_name,
                     $path,
@@ -1336,17 +1430,15 @@ macro_rules! tool_extended {
 
             fn make_run(run: RunConfig<'_>) {
                 run.builder.ensure($name {
-                    compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
-                    target: run.target,
+                    compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target),
                 });
             }
 
             fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
-                let Self { compiler, target } = self;
-                run_tool_build_step(
+                let Self { compilers } = self;
+                build_extended_rustc_tool(
                     builder,
-                    compiler,
-                    target,
+                    compilers,
                     $tool_name,
                     $path,
                     None $( .or(Some(&$add_bins_to_sysroot)) )?,
@@ -1356,18 +1448,16 @@ macro_rules! tool_extended {
             }
 
             fn metadata(&self) -> Option<StepMetadata> {
-                // FIXME: refactor extended tool steps to make the build_compiler explicit,
-                // it is offset by one now for rustc tools
                 Some(
-                    StepMetadata::build($tool_name, self.target)
-                        .built_by(self.compiler.with_stage(self.compiler.stage.saturating_sub(1)))
+                    StepMetadata::build($tool_name, self.compilers.target())
+                        .built_by(self.compilers.build_compiler)
                 )
             }
         }
     }
 }
 
-fn should_run_tool_build_step<'a>(
+fn should_run_extended_rustc_tool<'a>(
     run: ShouldRun<'a>,
     tool_name: &'static str,
     path: &'static str,
@@ -1391,39 +1481,38 @@ fn should_run_tool_build_step<'a>(
     )
 }
 
-#[expect(clippy::too_many_arguments)] // silence overeager clippy lint
-fn run_tool_build_step(
+fn build_extended_rustc_tool(
     builder: &Builder<'_>,
-    compiler: Compiler,
-    target: TargetSelection,
+    compilers: RustcPrivateCompilers,
     tool_name: &'static str,
     path: &'static str,
     add_bins_to_sysroot: Option<&[&str]>,
     add_features: Option<fn(&Builder<'_>, TargetSelection, &mut Vec<String>)>,
     cargo_args: Option<&[&'static str]>,
 ) -> ToolBuildResult {
+    let target = compilers.target();
     let mut extra_features = Vec::new();
     if let Some(func) = add_features {
         func(builder, target, &mut extra_features);
     }
 
-    let ToolBuildResult { tool_path, build_compiler, target_compiler } =
-        builder.ensure(ToolBuild {
-            build_compiler: compiler,
-            target,
-            tool: tool_name,
-            mode: Mode::ToolRustc,
-            path,
-            extra_features,
-            source_type: SourceType::InTree,
-            allow_features: "",
-            cargo_args: cargo_args.unwrap_or_default().iter().map(|s| String::from(*s)).collect(),
-            artifact_kind: ToolArtifactKind::Binary,
-        });
-
+    let build_compiler = compilers.build_compiler;
+    let ToolBuildResult { tool_path, .. } = builder.ensure(ToolBuild {
+        build_compiler,
+        target,
+        tool: tool_name,
+        mode: Mode::ToolRustc,
+        path,
+        extra_features,
+        source_type: SourceType::InTree,
+        allow_features: "",
+        cargo_args: cargo_args.unwrap_or_default().iter().map(|s| String::from(*s)).collect(),
+        artifact_kind: ToolArtifactKind::Binary,
+    });
+
+    let target_compiler = compilers.target_compiler;
     if let Some(add_bins_to_sysroot) = add_bins_to_sysroot
         && !add_bins_to_sysroot.is_empty()
-        && target_compiler.stage > 0
     {
         let bindir = builder.sysroot(target_compiler).join("bin");
         t!(fs::create_dir_all(&bindir));
@@ -1435,25 +1524,25 @@ fn run_tool_build_step(
 
         // Return a path into the bin dir.
         let path = bindir.join(exe(tool_name, target_compiler.host));
-        ToolBuildResult { tool_path: path, build_compiler, target_compiler }
+        ToolBuildResult { tool_path: path, build_compiler }
     } else {
-        ToolBuildResult { tool_path, build_compiler, target_compiler }
+        ToolBuildResult { tool_path, build_compiler }
     }
 }
 
-tool_extended!(Cargofmt {
+tool_rustc_extended!(Cargofmt {
     path: "src/tools/rustfmt",
     tool_name: "cargo-fmt",
     stable: true,
     add_bins_to_sysroot: ["cargo-fmt"]
 });
-tool_extended!(CargoClippy {
+tool_rustc_extended!(CargoClippy {
     path: "src/tools/clippy",
     tool_name: "cargo-clippy",
     stable: true,
     add_bins_to_sysroot: ["cargo-clippy"]
 });
-tool_extended!(Clippy {
+tool_rustc_extended!(Clippy {
     path: "src/tools/clippy",
     tool_name: "clippy-driver",
     stable: true,
@@ -1464,7 +1553,7 @@ tool_extended!(Clippy {
         }
     }
 });
-tool_extended!(Miri {
+tool_rustc_extended!(Miri {
     path: "src/tools/miri",
     tool_name: "miri",
     stable: false,
@@ -1472,13 +1561,13 @@ tool_extended!(Miri {
     // Always compile also tests when building miri. Otherwise feature unification can cause rebuilds between building and testing miri.
     cargo_args: &["--all-targets"],
 });
-tool_extended!(CargoMiri {
+tool_rustc_extended!(CargoMiri {
     path: "src/tools/miri/cargo-miri",
     tool_name: "cargo-miri",
     stable: false,
     add_bins_to_sysroot: ["cargo-miri"]
 });
-tool_extended!(Rustfmt {
+tool_rustc_extended!(Rustfmt {
     path: "src/tools/rustfmt",
     tool_name: "rustfmt",
     stable: true,
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index badd5f24dba..1d0c9da694f 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -508,7 +508,7 @@ impl Builder<'_> {
                 }
                 _ => panic!("doc mode {mode:?} not expected"),
             };
-            let rustdoc = self.rustdoc(compiler);
+            let rustdoc = self.rustdoc_for_compiler(compiler);
             build_stamp::clear_if_dirty(self, &my_out, &rustdoc);
         }
 
@@ -822,7 +822,7 @@ impl Builder<'_> {
         }
 
         let rustdoc_path = match cmd_kind {
-            Kind::Doc | Kind::Test | Kind::MiriTest => self.rustdoc(compiler),
+            Kind::Doc | Kind::Test | Kind::MiriTest => self.rustdoc_for_compiler(compiler),
             _ => PathBuf::from("/path/to/nowhere/rustdoc/not/required"),
         };
 
@@ -1286,7 +1286,7 @@ impl Builder<'_> {
 
             if let Some(limit) = limit
                 && (build_compiler_stage == 0
-                    || self.config.default_codegen_backend(target).unwrap_or_default() == "llvm")
+                    || self.config.default_codegen_backend(target).unwrap_or_default().is_llvm())
             {
                 rustflags.arg(&format!("-Cllvm-args=-import-instr-limit={limit}"));
             }
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 020622d1c12..f84565fccfd 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -16,6 +16,7 @@ use tracing::instrument;
 pub use self::cargo::{Cargo, cargo_profile_var};
 pub use crate::Compiler;
 use crate::core::build_steps::compile::{Std, StdLink};
+use crate::core::build_steps::tool::RustcPrivateCompilers;
 use crate::core::build_steps::{
     check, clean, clippy, compile, dist, doc, gcc, install, llvm, run, setup, test, tool, vendor,
 };
@@ -77,7 +78,7 @@ impl Deref for Builder<'_> {
 /// type's [`Debug`] implementation.
 ///
 /// (Trying to debug-print `dyn Any` results in the unhelpful `"Any { .. }"`.)
-trait AnyDebug: Any + Debug {}
+pub trait AnyDebug: Any + Debug {}
 impl<T: Any + Debug> AnyDebug for T {}
 impl dyn AnyDebug {
     /// Equivalent to `<dyn Any>::downcast_ref`.
@@ -141,7 +142,7 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
 #[allow(unused)]
 #[derive(Debug, PartialEq, Eq)]
 pub struct StepMetadata {
-    name: &'static str,
+    name: String,
     kind: Kind,
     target: TargetSelection,
     built_by: Option<Compiler>,
@@ -151,28 +152,28 @@ pub struct StepMetadata {
 }
 
 impl StepMetadata {
-    pub fn build(name: &'static str, target: TargetSelection) -> Self {
+    pub fn build(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Build)
     }
 
-    pub fn check(name: &'static str, target: TargetSelection) -> Self {
+    pub fn check(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Check)
     }
 
-    pub fn doc(name: &'static str, target: TargetSelection) -> Self {
+    pub fn doc(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Doc)
     }
 
-    pub fn dist(name: &'static str, target: TargetSelection) -> Self {
+    pub fn dist(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Dist)
     }
 
-    pub fn test(name: &'static str, target: TargetSelection) -> Self {
+    pub fn test(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Test)
     }
 
-    fn new(name: &'static str, target: TargetSelection, kind: Kind) -> Self {
-        Self { name, kind, target, built_by: None, stage: None, metadata: None }
+    fn new(name: &str, target: TargetSelection, kind: Kind) -> Self {
+        Self { name: name.to_string(), kind, target, built_by: None, stage: None, metadata: None }
     }
 
     pub fn built_by(mut self, compiler: Compiler) -> Self {
@@ -197,6 +198,14 @@ impl StepMetadata {
             // For everything else, a stage N things gets built by a stage N-1 compiler.
             .map(|compiler| if self.name == "std" { compiler.stage } else { compiler.stage + 1 }))
     }
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+
+    pub fn get_target(&self) -> TargetSelection {
+        self.target
+    }
 }
 
 pub struct RunConfig<'a> {
@@ -1535,8 +1544,11 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
             .map(|entry| entry.path())
     }
 
-    pub fn rustdoc(&self, compiler: Compiler) -> PathBuf {
-        self.ensure(tool::Rustdoc { compiler }).tool_path
+    /// Returns a path to `Rustdoc` that "belongs" to the `target_compiler`.
+    /// It can be either a stage0 rustdoc or a locally built rustdoc that *links* to
+    /// `target_compiler`.
+    pub fn rustdoc_for_compiler(&self, target_compiler: Compiler) -> PathBuf {
+        self.ensure(tool::Rustdoc { target_compiler })
     }
 
     pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> BootstrapCommand {
@@ -1552,10 +1564,13 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
             return cmd;
         }
 
-        let _ =
-            self.ensure(tool::Clippy { compiler: run_compiler, target: self.build.host_target });
-        let cargo_clippy = self
-            .ensure(tool::CargoClippy { compiler: run_compiler, target: self.build.host_target });
+        // FIXME: double check that `run_compiler`'s stage is what we want to use
+        let compilers =
+            RustcPrivateCompilers::new(self, run_compiler.stage, self.build.host_target);
+        assert_eq!(run_compiler, compilers.target_compiler());
+
+        let _ = self.ensure(tool::Clippy::from_compilers(compilers));
+        let cargo_clippy = self.ensure(tool::CargoClippy::from_compilers(compilers));
         let mut dylib_path = helpers::dylib_path();
         dylib_path.insert(0, self.sysroot(run_compiler).join("lib"));
 
@@ -1567,11 +1582,14 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
 
     pub fn cargo_miri_cmd(&self, run_compiler: Compiler) -> BootstrapCommand {
         assert!(run_compiler.stage > 0, "miri can not be invoked at stage 0");
+
+        let compilers =
+            RustcPrivateCompilers::new(self, run_compiler.stage, self.build.host_target);
+        assert_eq!(run_compiler, compilers.target_compiler());
+
         // Prepare the tools
-        let miri =
-            self.ensure(tool::Miri { compiler: run_compiler, target: self.build.host_target });
-        let cargo_miri =
-            self.ensure(tool::CargoMiri { compiler: run_compiler, target: self.build.host_target });
+        let miri = self.ensure(tool::Miri::from_compilers(compilers));
+        let cargo_miri = self.ensure(tool::CargoMiri::from_compilers(compilers));
         // Invoke cargo-miri, make sure it can find miri and cargo.
         let mut cmd = command(cargo_miri.tool_path);
         cmd.env("MIRI", &miri.tool_path);
@@ -1596,7 +1614,7 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
             // equivalently to rustc.
             .env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler))
             .env("CFG_RELEASE_CHANNEL", &self.config.channel)
-            .env("RUSTDOC_REAL", self.rustdoc(compiler))
+            .env("RUSTDOC_REAL", self.rustdoc_for_compiler(compiler))
             .env("RUSTC_BOOTSTRAP", "1");
 
         cmd.arg("-Wrustdoc::invalid_codeblock_attributes");
@@ -1657,9 +1675,24 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
             if let Some(out) = self.cache.get(&step) {
                 self.verbose_than(1, || println!("{}c {:?}", "  ".repeat(stack.len()), step));
 
+                #[cfg(feature = "tracing")]
+                {
+                    if let Some(parent) = stack.last() {
+                        let mut graph = self.build.step_graph.borrow_mut();
+                        graph.register_cached_step(&step, parent, self.config.dry_run());
+                    }
+                }
                 return out;
             }
             self.verbose_than(1, || println!("{}> {:?}", "  ".repeat(stack.len()), step));
+
+            #[cfg(feature = "tracing")]
+            {
+                let parent = stack.last();
+                let mut graph = self.build.step_graph.borrow_mut();
+                graph.register_step_execution(&step, parent, self.config.dry_run());
+            }
+
             stack.push(Box::new(step.clone()));
         }
 
@@ -1705,11 +1738,11 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
     /// Ensure that a given step is built *only if it's supposed to be built by default*, returning
     /// its output. This will cache the step, so it's safe (and good!) to call this as often as
     /// needed to ensure that all dependencies are build.
-    pub(crate) fn ensure_if_default<T, S: Step<Output = Option<T>>>(
+    pub(crate) fn ensure_if_default<T, S: Step<Output = T>>(
         &'a self,
         step: S,
         kind: Kind,
-    ) -> S::Output {
+    ) -> Option<S::Output> {
         let desc = StepDescription::from::<S>(kind);
         let should_run = (desc.should_run)(ShouldRun::new(self, desc.kind));
 
@@ -1721,7 +1754,7 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
         }
 
         // Only execute if it's supposed to run as default
-        if desc.default && should_run.is_really_default() { self.ensure(step) } else { None }
+        if desc.default && should_run.is_really_default() { Some(self.ensure(step)) } else { None }
     }
 
     /// Checks if any of the "should_run" paths is in the `Builder` paths.
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 6ea5d4e6553..139ddc9ed24 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -279,13 +279,6 @@ mod defaults {
             first(cache.all::<tool::ErrorIndex>()),
             &[tool::ErrorIndex { compiler: Compiler::new(1, a) }]
         );
-        // docs should be built with the stage0 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::new(1, a) },]
-        );
     }
 }
 
@@ -337,12 +330,6 @@ mod dist {
             first(builder.cache.all::<tool::ErrorIndex>()),
             &[tool::ErrorIndex { compiler: Compiler::new(1, a) }]
         );
-        // 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::new(2, a) },]
-        );
     }
 }
 
@@ -569,36 +556,6 @@ fn test_is_builder_target() {
     }
 }
 
-#[test]
-fn test_get_tool_rustc_compiler() {
-    let mut config = configure("build", &[], &[]);
-    config.download_rustc_commit = None;
-    let build = Build::new(config);
-    let builder = Builder::new(&build);
-
-    let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1);
-
-    let compiler = Compiler::new(2, target_triple_1);
-    let expected = Compiler::new(1, target_triple_1);
-    let actual = tool::get_tool_rustc_compiler(&builder, compiler);
-    assert_eq!(expected, actual);
-
-    let compiler = Compiler::new(1, target_triple_1);
-    let expected = Compiler::new(0, target_triple_1);
-    let actual = tool::get_tool_rustc_compiler(&builder, compiler);
-    assert_eq!(expected, actual);
-
-    let mut config = configure("build", &[], &[]);
-    config.download_rustc_commit = Some("".to_owned());
-    let build = Build::new(config);
-    let builder = Builder::new(&build);
-
-    let compiler = Compiler::new(1, target_triple_1);
-    let expected = Compiler::new(1, target_triple_1);
-    let actual = tool::get_tool_rustc_compiler(&builder, compiler);
-    assert_eq!(expected, actual);
-}
-
 /// When bootstrap detects a step dependency cycle (which is a bug), its panic
 /// message should show the actual steps on the stack, not just several copies
 /// of `Any { .. }`.
@@ -657,7 +614,7 @@ mod snapshot {
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
-        [build] rustdoc 0 <host>
+        [build] rustdoc 1 <host>
         ");
     }
 
@@ -680,10 +637,10 @@ mod snapshot {
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 1 <host> -> std 1 <target1>
         [build] rustc 2 <host> -> std 2 <target1>
-        [build] rustdoc 1 <host>
+        [build] rustdoc 2 <host>
         [build] llvm <target1>
         [build] rustc 1 <host> -> rustc 2 <target1>
-        [build] rustdoc 1 <target1>
+        [build] rustdoc 2 <target1>
         ");
     }
 
@@ -763,6 +720,23 @@ mod snapshot {
     }
 
     #[test]
+    fn build_compiler_codegen_backend() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx
+                .config("build")
+                .args(&["--set", "rust.codegen-backends=['llvm', 'cranelift']"])
+                .render_steps(), @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustdoc 1 <host>
+        "
+        );
+    }
+
+    #[test]
     fn build_compiler_tools() {
         let ctx = TestCtx::new();
         insta::assert_snapshot!(
@@ -780,7 +754,7 @@ mod snapshot {
         [build] rustc 1 <host> -> LldWrapper 2 <host>
         [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <host>
         [build] rustc 2 <host> -> std 2 <host>
-        [build] rustdoc 1 <host>
+        [build] rustdoc 2 <host>
         "
         );
     }
@@ -809,7 +783,7 @@ mod snapshot {
         [build] rustc 1 <host> -> rustc 2 <target1>
         [build] rustc 1 <host> -> LldWrapper 2 <target1>
         [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <target1>
-        [build] rustdoc 1 <target1>
+        [build] rustdoc 2 <target1>
         "
         );
     }
@@ -998,8 +972,8 @@ mod snapshot {
             .render_steps(), @r"
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
-        [build] rustdoc 0 <host>
-        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 1 <host>
+        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         ");
     }
 
@@ -1027,6 +1001,15 @@ mod snapshot {
     }
 
     #[test]
+    fn build_cargo() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("build")
+                .paths(&["cargo"])
+            .render_steps(), @"[build] rustc 0 <host> -> cargo 1 <host>");
+    }
+
+    #[test]
     fn dist_default_stage() {
         let ctx = TestCtx::new();
         assert_eq!(ctx.config("dist").path("compiler").create_config().stage, 2);
@@ -1047,8 +1030,8 @@ mod snapshot {
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
-        [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 2 <host>
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
@@ -1089,24 +1072,27 @@ mod snapshot {
         [build] rustc 1 <host> -> LldWrapper 2 <host>
         [build] rustc 1 <host> -> WasmComponentLd 2 <host>
         [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <host>
-        [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 2 <host>
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
         [dist] docs <host>
         [doc] std 2 <host> crates=[]
         [dist] mingw <host>
+        [build] rustc 1 <host> -> rust-analyzer-proc-macro-srv 2 <host>
         [build] rustc 0 <host> -> GenerateCopyright 1 <host>
         [dist] rustc <host>
         [dist] rustc 1 <host> -> std 1 <host>
         [dist] src <>
-        [build] rustc 0 <host> -> rustfmt 1 <host>
-        [build] rustc 0 <host> -> cargo-fmt 1 <host>
-        [build] rustc 0 <host> -> clippy-driver 1 <host>
-        [build] rustc 0 <host> -> cargo-clippy 1 <host>
-        [build] rustc 0 <host> -> miri 1 <host>
-        [build] rustc 0 <host> -> cargo-miri 1 <host>
+        [build] rustc 1 <host> -> cargo 2 <host>
+        [build] rustc 1 <host> -> rust-analyzer 2 <host>
+        [build] rustc 1 <host> -> rustfmt 2 <host>
+        [build] rustc 1 <host> -> cargo-fmt 2 <host>
+        [build] rustc 1 <host> -> clippy-driver 2 <host>
+        [build] rustc 1 <host> -> cargo-clippy 2 <host>
+        [build] rustc 1 <host> -> miri 2 <host>
+        [build] rustc 1 <host> -> cargo-miri 2 <host>
         ");
     }
 
@@ -1125,9 +1111,9 @@ mod snapshot {
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
-        [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 2 <host>
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
@@ -1162,8 +1148,8 @@ mod snapshot {
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
-        [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 2 <host>
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 1 <host> -> std 1 <target1>
@@ -1176,7 +1162,7 @@ mod snapshot {
         [dist] rustc <host>
         [build] llvm <target1>
         [build] rustc 1 <host> -> rustc 2 <target1>
-        [build] rustdoc 1 <target1>
+        [build] rustdoc 2 <target1>
         [dist] rustc <target1>
         [dist] rustc 1 <host> -> std 1 <host>
         [dist] src <>
@@ -1199,9 +1185,9 @@ mod snapshot {
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
-        [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 2 <host>
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 1 <host> -> std 1 <target1>
@@ -1217,7 +1203,7 @@ mod snapshot {
         [dist] rustc <host>
         [build] llvm <target1>
         [build] rustc 1 <host> -> rustc 2 <target1>
-        [build] rustdoc 1 <target1>
+        [build] rustdoc 2 <target1>
         [dist] rustc <target1>
         [dist] rustc 1 <host> -> std 1 <host>
         [dist] rustc 1 <host> -> std 1 <target1>
@@ -1241,8 +1227,8 @@ mod snapshot {
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
-        [build] rustdoc 1 <host>
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 2 <host>
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
         [dist] docs <target1>
@@ -1273,8 +1259,8 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustc 1 <host> -> WasmComponentLd 2 <host>
-        [build] rustdoc 1 <host>
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 2 <host>
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 1 <host> -> std 1 <target1>
         [build] rustc 2 <host> -> std 2 <target1>
@@ -1286,17 +1272,20 @@ mod snapshot {
         [build] llvm <target1>
         [build] rustc 1 <host> -> rustc 2 <target1>
         [build] rustc 1 <host> -> WasmComponentLd 2 <target1>
-        [build] rustdoc 1 <target1>
+        [build] rustdoc 2 <target1>
+        [build] rustc 1 <host> -> rust-analyzer-proc-macro-srv 2 <target1>
         [build] rustc 0 <host> -> GenerateCopyright 1 <host>
         [dist] rustc <target1>
         [dist] rustc 1 <host> -> std 1 <target1>
         [dist] src <>
-        [build] rustc 0 <host> -> rustfmt 1 <target1>
-        [build] rustc 0 <host> -> cargo-fmt 1 <target1>
-        [build] rustc 0 <host> -> clippy-driver 1 <target1>
-        [build] rustc 0 <host> -> cargo-clippy 1 <target1>
-        [build] rustc 0 <host> -> miri 1 <target1>
-        [build] rustc 0 <host> -> cargo-miri 1 <target1>
+        [build] rustc 1 <host> -> cargo 2 <target1>
+        [build] rustc 1 <host> -> rust-analyzer 2 <target1>
+        [build] rustc 1 <host> -> rustfmt 2 <target1>
+        [build] rustc 1 <host> -> cargo-fmt 2 <target1>
+        [build] rustc 1 <host> -> clippy-driver 2 <target1>
+        [build] rustc 1 <host> -> cargo-clippy 2 <target1>
+        [build] rustc 1 <host> -> miri 2 <target1>
+        [build] rustc 1 <host> -> cargo-miri 2 <target1>
         [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <target1>
         ");
     }
@@ -1309,8 +1298,8 @@ mod snapshot {
                 .path("compiler")
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> cranelift 1 <host>
-        [check] rustc 0 <host> -> gcc 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
         ");
     }
 
@@ -1341,8 +1330,8 @@ mod snapshot {
                 .stage(1)
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> cranelift 1 <host>
-        [check] rustc 0 <host> -> gcc 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
         ");
     }
 
@@ -1358,8 +1347,8 @@ mod snapshot {
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
         [check] rustc 1 <host> -> rustc 2 <host>
-        [check] rustc 1 <host> -> cranelift 2 <host>
-        [check] rustc 1 <host> -> gcc 2 <host>
+        [check] rustc 1 <host> -> rustc_codegen_cranelift 2 <host>
+        [check] rustc 1 <host> -> rustc_codegen_gcc 2 <host>
         ");
     }
 
@@ -1377,8 +1366,8 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <target1>
         [check] rustc 1 <host> -> rustc 2 <target1>
         [check] rustc 1 <host> -> Rustdoc 2 <target1>
-        [check] rustc 1 <host> -> cranelift 2 <target1>
-        [check] rustc 1 <host> -> gcc 2 <target1>
+        [check] rustc 1 <host> -> rustc_codegen_cranelift 2 <target1>
+        [check] rustc 1 <host> -> rustc_codegen_gcc 2 <target1>
         [check] rustc 1 <host> -> Clippy 2 <target1>
         [check] rustc 1 <host> -> Miri 2 <target1>
         [check] rustc 1 <host> -> CargoMiri 2 <target1>
@@ -1472,8 +1461,8 @@ mod snapshot {
                 .args(&args)
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> cranelift 1 <host>
-        [check] rustc 0 <host> -> gcc 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
         ");
     }
 
@@ -1557,8 +1546,8 @@ mod snapshot {
                 .path("rustc_codegen_cranelift")
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> cranelift 1 <host>
-        [check] rustc 0 <host> -> gcc 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
         ");
     }
 
@@ -1611,6 +1600,58 @@ mod snapshot {
     }
 
     #[test]
+    fn test_cargo_stage_1() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("test")
+                .path("cargo")
+                .render_steps(), @r"
+        [build] rustc 0 <host> -> cargo 1 <host>
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustdoc 1 <host>
+        [build] rustdoc 0 <host>
+        ");
+    }
+
+    #[test]
+    fn test_cargo_stage_2() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("test")
+                .path("cargo")
+                .stage(2)
+                .render_steps(), @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustc 1 <host> -> cargo 2 <host>
+        [build] rustc 1 <host> -> rustc 2 <host>
+        [build] rustc 2 <host> -> std 2 <host>
+        [build] rustdoc 2 <host>
+        [build] rustdoc 1 <host>
+        ");
+    }
+
+    #[test]
+    fn test_cargotest() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("test")
+                .path("cargotest")
+                .render_steps(), @r"
+        [build] rustc 0 <host> -> cargo 1 <host>
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustc 0 <host> -> CargoTest 1 <host>
+        [build] rustdoc 1 <host>
+        [test] cargotest 1 <host>
+        ");
+    }
+
+    #[test]
     fn doc_library() {
         let ctx = TestCtx::new();
         insta::assert_snapshot!(
@@ -1619,8 +1660,8 @@ mod snapshot {
                 .render_steps(), @r"
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
-        [build] rustdoc 0 <host>
-        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [build] rustdoc 1 <host>
+        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         ");
     }
 
@@ -1633,7 +1674,7 @@ mod snapshot {
                 .render_steps(), @r"
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
-        [build] rustdoc 0 <host>
+        [build] rustdoc 1 <host>
         [doc] std 1 <host> crates=[core]
         ");
     }
@@ -1648,7 +1689,7 @@ mod snapshot {
                 .render_steps(), @r"
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
-        [build] rustdoc 0 <host>
+        [build] rustdoc 1 <host>
         [doc] std 1 <host> crates=[core]
         ");
     }
@@ -1678,7 +1719,7 @@ mod snapshot {
                 .render_steps(), @r"
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
-        [build] rustdoc 0 <host>
+        [build] rustdoc 1 <host>
         [doc] std 1 <host> crates=[alloc,core]
         ");
     }
@@ -1694,10 +1735,105 @@ mod snapshot {
                 .render_steps(), @r"
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
-        [build] rustdoc 0 <host>
+        [build] rustdoc 1 <host>
         [doc] std 1 <target1> crates=[alloc,core]
         ");
     }
+
+    #[test]
+    fn doc_compiler_stage_0() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("doc")
+                .path("compiler")
+                .stage(0)
+                .render_steps(), @r"
+        [build] rustdoc 0 <host>
+        [build] llvm <host>
+        [doc] rustc 0 <host>
+        ");
+    }
+
+    #[test]
+    fn doc_compiler_stage_1() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("doc")
+                .path("compiler")
+                .stage(1)
+                .render_steps(), @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustdoc 1 <host>
+        [doc] rustc 1 <host>
+        ");
+    }
+
+    #[test]
+    fn doc_compiler_stage_2() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("doc")
+                .path("compiler")
+                .stage(2)
+                .render_steps(), @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustc 1 <host> -> rustc 2 <host>
+        [build] rustc 2 <host> -> std 2 <host>
+        [build] rustdoc 2 <host>
+        [doc] rustc 2 <host>
+        ");
+    }
+
+    #[test]
+    fn doc_compiletest_stage_0() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("doc")
+                .path("src/tools/compiletest")
+                .stage(0)
+                .render_steps(), @r"
+        [build] rustdoc 0 <host>
+        [doc] Compiletest <host>
+        ");
+    }
+
+    #[test]
+    fn doc_compiletest_stage_1() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("doc")
+                .path("src/tools/compiletest")
+                .stage(1)
+                .render_steps(), @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustdoc 1 <host>
+        [doc] Compiletest <host>
+        ");
+    }
+
+    #[test]
+    fn doc_compiletest_stage_2() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx.config("doc")
+                .path("src/tools/compiletest")
+                .stage(2)
+                .render_steps(), @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustc 1 <host> -> rustc 2 <host>
+        [build] rustc 2 <host> -> std 2 <host>
+        [build] rustdoc 2 <host>
+        [doc] Compiletest <host>
+        ");
+    }
 }
 
 struct ExecutedSteps {
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 78abdd7f9b8..6055876c475 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -51,7 +51,7 @@ use crate::core::download::{
 use crate::utils::channel;
 use crate::utils::exec::{ExecutionContext, command};
 use crate::utils::helpers::{exe, get_host_target};
-use crate::{GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, t};
+use crate::{CodegenBackendKind, GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, t};
 
 /// Each path in this list is considered "allowed" in the `download-rustc="if-unchanged"` logic.
 /// This means they can be modified and changes to these paths should never trigger a compiler build
@@ -208,7 +208,7 @@ pub struct Config {
     pub rustc_default_linker: Option<String>,
     pub rust_optimize_tests: bool,
     pub rust_dist_src: bool,
-    pub rust_codegen_backends: Vec<String>,
+    pub rust_codegen_backends: Vec<CodegenBackendKind>,
     pub rust_verify_llvm_ir: bool,
     pub rust_thin_lto_import_instr_limit: Option<u32>,
     pub rust_randomize_layout: bool,
@@ -350,7 +350,7 @@ impl Config {
             channel: "dev".to_string(),
             codegen_tests: true,
             rust_dist_src: true,
-            rust_codegen_backends: vec!["llvm".to_owned()],
+            rust_codegen_backends: vec![CodegenBackendKind::Llvm],
             deny_warnings: true,
             bindir: "bin".into(),
             dist_include_mingw_linker: true,
@@ -1747,7 +1747,7 @@ impl Config {
             .unwrap_or(self.profiler)
     }
 
-    pub fn codegen_backends(&self, target: TargetSelection) -> &[String] {
+    pub fn codegen_backends(&self, target: TargetSelection) -> &[CodegenBackendKind] {
         self.target_config
             .get(&target)
             .and_then(|cfg| cfg.codegen_backends.as_deref())
@@ -1758,7 +1758,7 @@ impl Config {
         self.target_config.get(&target).and_then(|cfg| cfg.jemalloc).unwrap_or(self.jemalloc)
     }
 
-    pub fn default_codegen_backend(&self, target: TargetSelection) -> Option<String> {
+    pub fn default_codegen_backend(&self, target: TargetSelection) -> Option<CodegenBackendKind> {
         self.codegen_backends(target).first().cloned()
     }
 
@@ -1774,7 +1774,7 @@ impl Config {
     }
 
     pub fn llvm_enabled(&self, target: TargetSelection) -> bool {
-        self.codegen_backends(target).contains(&"llvm".to_owned())
+        self.codegen_backends(target).contains(&CodegenBackendKind::Llvm)
     }
 
     pub fn llvm_libunwind(&self, target: TargetSelection) -> LlvmLibunwind {
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
index c136bd4a6f9..03da993a17d 100644
--- a/src/bootstrap/src/core/config/toml/rust.rs
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -11,7 +11,9 @@ use crate::core::config::{
     DebuginfoLevel, Merge, ReplaceOpt, RustcLto, StringOrBool, set, threads_from_config,
 };
 use crate::flags::Warnings;
-use crate::{BTreeSet, Config, HashSet, PathBuf, TargetSelection, define_config, exit};
+use crate::{
+    BTreeSet, CodegenBackendKind, Config, HashSet, PathBuf, TargetSelection, define_config, exit,
+};
 
 define_config! {
     /// TOML representation of how the Rust build is configured.
@@ -389,9 +391,13 @@ pub fn check_incompatible_options_for_ci_rustc(
     Ok(())
 }
 
-pub(crate) const VALID_CODEGEN_BACKENDS: &[&str] = &["llvm", "cranelift", "gcc"];
+pub(crate) const BUILTIN_CODEGEN_BACKENDS: &[&str] = &["llvm", "cranelift", "gcc"];
 
-pub(crate) fn validate_codegen_backends(backends: Vec<String>, section: &str) -> Vec<String> {
+pub(crate) fn parse_codegen_backends(
+    backends: Vec<String>,
+    section: &str,
+) -> Vec<CodegenBackendKind> {
+    let mut found_backends = vec![];
     for backend in &backends {
         if let Some(stripped) = backend.strip_prefix(CODEGEN_BACKEND_PREFIX) {
             panic!(
@@ -400,14 +406,21 @@ pub(crate) fn validate_codegen_backends(backends: Vec<String>, section: &str) ->
                 Please, use '{stripped}' instead."
             )
         }
-        if !VALID_CODEGEN_BACKENDS.contains(&backend.as_str()) {
+        if !BUILTIN_CODEGEN_BACKENDS.contains(&backend.as_str()) {
             println!(
                 "HELP: '{backend}' for '{section}.codegen-backends' might fail. \
-                List of known good values: {VALID_CODEGEN_BACKENDS:?}"
+                List of known codegen backends: {BUILTIN_CODEGEN_BACKENDS:?}"
             );
         }
+        let backend = match backend.as_str() {
+            "llvm" => CodegenBackendKind::Llvm,
+            "cranelift" => CodegenBackendKind::Cranelift,
+            "gcc" => CodegenBackendKind::Gcc,
+            backend => CodegenBackendKind::Custom(backend.to_string()),
+        };
+        found_backends.push(backend);
     }
-    backends
+    found_backends
 }
 
 #[cfg(not(test))]
@@ -609,7 +622,7 @@ impl Config {
                 llvm_libunwind.map(|v| v.parse().expect("failed to parse rust.llvm-libunwind"));
             set(
                 &mut self.rust_codegen_backends,
-                codegen_backends.map(|backends| validate_codegen_backends(backends, "rust")),
+                codegen_backends.map(|backends| parse_codegen_backends(backends, "rust")),
             );
 
             self.rust_codegen_units = codegen_units.map(threads_from_config);
diff --git a/src/bootstrap/src/core/config/toml/target.rs b/src/bootstrap/src/core/config/toml/target.rs
index 337276948b3..9dedadff3a1 100644
--- a/src/bootstrap/src/core/config/toml/target.rs
+++ b/src/bootstrap/src/core/config/toml/target.rs
@@ -16,9 +16,9 @@ use std::collections::HashMap;
 
 use serde::{Deserialize, Deserializer};
 
-use crate::core::config::toml::rust::validate_codegen_backends;
+use crate::core::config::toml::rust::parse_codegen_backends;
 use crate::core::config::{LlvmLibunwind, Merge, ReplaceOpt, SplitDebuginfo, StringOrBool};
-use crate::{Config, HashSet, PathBuf, TargetSelection, define_config, exit};
+use crate::{CodegenBackendKind, Config, HashSet, PathBuf, TargetSelection, define_config, exit};
 
 define_config! {
     /// TOML representation of how each build target is configured.
@@ -76,7 +76,7 @@ pub struct Target {
     pub qemu_rootfs: Option<PathBuf>,
     pub runner: Option<String>,
     pub no_std: bool,
-    pub codegen_backends: Option<Vec<String>>,
+    pub codegen_backends: Option<Vec<CodegenBackendKind>>,
     pub optimized_compiler_builtins: Option<bool>,
     pub jemalloc: Option<bool>,
 }
@@ -144,7 +144,7 @@ impl Config {
                 target.jemalloc = cfg.jemalloc;
                 if let Some(backends) = cfg.codegen_backends {
                     target.codegen_backends =
-                        Some(validate_codegen_backends(backends, &format!("target.{triple}")))
+                        Some(parse_codegen_backends(backends, &format!("target.{triple}")))
                 }
 
                 target.split_debuginfo = cfg.split_debuginfo.as_ref().map(|v| {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 51a84ad5272..42192f1d721 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -123,6 +123,46 @@ impl PartialEq for Compiler {
     }
 }
 
+/// Represents a codegen backend.
+#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
+pub enum CodegenBackendKind {
+    #[default]
+    Llvm,
+    Cranelift,
+    Gcc,
+    Custom(String),
+}
+
+impl CodegenBackendKind {
+    /// Name of the codegen backend, as identified in the `compiler` directory
+    /// (`rustc_codegen_<name>`).
+    pub fn name(&self) -> &str {
+        match self {
+            CodegenBackendKind::Llvm => "llvm",
+            CodegenBackendKind::Cranelift => "cranelift",
+            CodegenBackendKind::Gcc => "gcc",
+            CodegenBackendKind::Custom(name) => name,
+        }
+    }
+
+    /// Name of the codegen backend's crate, e.g. `rustc_codegen_cranelift`.
+    pub fn crate_name(&self) -> String {
+        format!("rustc_codegen_{}", self.name())
+    }
+
+    pub fn is_llvm(&self) -> bool {
+        matches!(self, Self::Llvm)
+    }
+
+    pub fn is_cranelift(&self) -> bool {
+        matches!(self, Self::Cranelift)
+    }
+
+    pub fn is_gcc(&self) -> bool {
+        matches!(self, Self::Gcc)
+    }
+}
+
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
 pub enum DocTests {
     /// Run normal tests and doc tests (default).
@@ -148,7 +188,6 @@ pub enum GitRepo {
 /// although most functions are implemented as free functions rather than
 /// methods specifically on this structure itself (to make it easier to
 /// organize).
-#[derive(Clone)]
 pub struct Build {
     /// User-specified configuration from `bootstrap.toml`.
     config: Config,
@@ -204,6 +243,9 @@ pub struct Build {
 
     #[cfg(feature = "build-metrics")]
     metrics: crate::utils::metrics::BuildMetrics,
+
+    #[cfg(feature = "tracing")]
+    step_graph: std::cell::RefCell<crate::utils::step_graph::StepGraph>,
 }
 
 #[derive(Debug, Clone)]
@@ -507,6 +549,9 @@ impl Build {
 
             #[cfg(feature = "build-metrics")]
             metrics: crate::utils::metrics::BuildMetrics::init(),
+
+            #[cfg(feature = "tracing")]
+            step_graph: std::cell::RefCell::new(crate::utils::step_graph::StepGraph::default()),
         };
 
         // If local-rust is the same major.minor as the current version, then force a
@@ -1060,17 +1105,6 @@ impl Build {
         self.msg(Kind::Doc, compiler.stage, what, compiler.host, target.into())
     }
 
-    #[must_use = "Groups should not be dropped until the Step finishes running"]
-    #[track_caller]
-    fn msg_build(
-        &self,
-        compiler: Compiler,
-        what: impl Display,
-        target: impl Into<Option<TargetSelection>>,
-    ) -> Option<gha::Group> {
-        self.msg(Kind::Build, compiler.stage, what, compiler.host, target)
-    }
-
     /// Return a `Group` guard for a [`Step`] that is built for each `--stage`.
     ///
     /// [`Step`]: crate::core::builder::Step
@@ -1117,20 +1151,21 @@ impl Build {
 
     #[must_use = "Groups should not be dropped until the Step finishes running"]
     #[track_caller]
-    fn msg_sysroot_tool(
+    fn msg_rustc_tool(
         &self,
         action: impl Into<Kind>,
-        stage: u32,
+        build_stage: u32,
         what: impl Display,
         host: TargetSelection,
         target: TargetSelection,
     ) -> Option<gha::Group> {
         let action = action.into().description();
         let msg = |fmt| format!("{action} {what} {fmt}");
+
         let msg = if host == target {
-            msg(format_args!("(stage{stage} -> stage{}, {target})", stage + 1))
+            msg(format_args!("(stage{build_stage} -> stage{}, {target})", build_stage + 1))
         } else {
-            msg(format_args!("(stage{stage}:{host} -> stage{}:{target})", stage + 1))
+            msg(format_args!("(stage{build_stage}:{host} -> stage{}:{target})", build_stage + 1))
         };
         self.group(&msg)
     }
@@ -1984,6 +2019,11 @@ to download LLVM rather than building it.
     pub fn report_summary(&self, start_time: Instant) {
         self.config.exec_ctx.profiler().report_summary(start_time);
     }
+
+    #[cfg(feature = "tracing")]
+    pub fn report_step_graph(self) {
+        self.step_graph.into_inner().store_to_dot_files();
+    }
 }
 
 impl AsRef<ExecutionContext> for Build {
diff --git a/src/bootstrap/src/utils/build_stamp.rs b/src/bootstrap/src/utils/build_stamp.rs
index f43d860893f..bd4eb790ae5 100644
--- a/src/bootstrap/src/utils/build_stamp.rs
+++ b/src/bootstrap/src/utils/build_stamp.rs
@@ -10,7 +10,7 @@ use sha2::digest::Digest;
 use crate::core::builder::Builder;
 use crate::core::config::TargetSelection;
 use crate::utils::helpers::{hex_encode, mtime};
-use crate::{Compiler, Mode, helpers, t};
+use crate::{CodegenBackendKind, Compiler, Mode, helpers, t};
 
 #[cfg(test)]
 mod tests;
@@ -129,10 +129,10 @@ pub fn codegen_backend_stamp(
     builder: &Builder<'_>,
     compiler: Compiler,
     target: TargetSelection,
-    backend: &str,
+    backend: &CodegenBackendKind,
 ) -> BuildStamp {
     BuildStamp::new(&builder.cargo_out(compiler, Mode::Codegen, target))
-        .with_prefix(&format!("librustc_codegen_{backend}"))
+        .with_prefix(&format!("lib{}", backend.crate_name()))
 }
 
 /// Cargo's output path for the standard library in a given stage, compiled
diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs
index 169fcec303e..97d8d274e8f 100644
--- a/src/bootstrap/src/utils/mod.rs
+++ b/src/bootstrap/src/utils/mod.rs
@@ -19,5 +19,8 @@ pub(crate) mod tracing;
 #[cfg(feature = "build-metrics")]
 pub(crate) mod metrics;
 
+#[cfg(feature = "tracing")]
+pub(crate) mod step_graph;
+
 #[cfg(test)]
 pub(crate) mod tests;
diff --git a/src/bootstrap/src/utils/step_graph.rs b/src/bootstrap/src/utils/step_graph.rs
new file mode 100644
index 00000000000..c45825a4222
--- /dev/null
+++ b/src/bootstrap/src/utils/step_graph.rs
@@ -0,0 +1,182 @@
+use std::collections::{HashMap, HashSet};
+use std::fmt::Debug;
+use std::io::BufWriter;
+
+use crate::core::builder::{AnyDebug, Step};
+
+/// Records the executed steps and their dependencies in a directed graph,
+/// which can then be rendered into a DOT file for visualization.
+///
+/// The graph visualizes the first execution of a step with a solid edge,
+/// and cached executions of steps with a dashed edge.
+/// If you only want to see first executions, you can modify the code in `DotGraph` to
+/// always set `cached: false`.
+#[derive(Default)]
+pub struct StepGraph {
+    /// We essentially store one graph per dry run mode.
+    graphs: HashMap<String, DotGraph>,
+}
+
+impl StepGraph {
+    pub fn register_step_execution<S: Step>(
+        &mut self,
+        step: &S,
+        parent: Option<&Box<dyn AnyDebug>>,
+        dry_run: bool,
+    ) {
+        let key = get_graph_key(dry_run);
+        let graph = self.graphs.entry(key.to_string()).or_insert_with(|| DotGraph::default());
+
+        // The debug output of the step sort of serves as the unique identifier of it.
+        // We use it to access the node ID of parents to generate edges.
+        // We could probably also use addresses on the heap from the `Box`, but this seems less
+        // magical.
+        let node_key = render_step(step);
+
+        let label = if let Some(metadata) = step.metadata() {
+            format!(
+                "{}{} [{}]",
+                metadata.get_name(),
+                metadata.get_stage().map(|s| format!(" stage {s}")).unwrap_or_default(),
+                metadata.get_target()
+            )
+        } else {
+            let type_name = std::any::type_name::<S>();
+            type_name
+                .strip_prefix("bootstrap::core::")
+                .unwrap_or(type_name)
+                .strip_prefix("build_steps::")
+                .unwrap_or(type_name)
+                .to_string()
+        };
+
+        let node = Node { label, tooltip: node_key.clone() };
+        let node_handle = graph.add_node(node_key, node);
+
+        if let Some(parent) = parent {
+            let parent_key = render_step(parent);
+            if let Some(src_node_handle) = graph.get_handle_by_key(&parent_key) {
+                graph.add_edge(src_node_handle, node_handle);
+            }
+        }
+    }
+
+    pub fn register_cached_step<S: Step>(
+        &mut self,
+        step: &S,
+        parent: &Box<dyn AnyDebug>,
+        dry_run: bool,
+    ) {
+        let key = get_graph_key(dry_run);
+        let graph = self.graphs.get_mut(key).unwrap();
+
+        let node_key = render_step(step);
+        let parent_key = render_step(parent);
+
+        if let Some(src_node_handle) = graph.get_handle_by_key(&parent_key) {
+            if let Some(dst_node_handle) = graph.get_handle_by_key(&node_key) {
+                graph.add_cached_edge(src_node_handle, dst_node_handle);
+            }
+        }
+    }
+
+    pub fn store_to_dot_files(self) {
+        for (key, graph) in self.graphs.into_iter() {
+            let filename = format!("bootstrap-steps{key}.dot");
+            graph.render(&filename).unwrap();
+        }
+    }
+}
+
+fn get_graph_key(dry_run: bool) -> &'static str {
+    if dry_run { ".dryrun" } else { "" }
+}
+
+struct Node {
+    label: String,
+    tooltip: String,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
+struct NodeHandle(usize);
+
+/// Represents a dependency between two bootstrap steps.
+#[derive(PartialEq, Eq, Hash, PartialOrd, Ord)]
+struct Edge {
+    src: NodeHandle,
+    dst: NodeHandle,
+    // Was the corresponding execution of a step cached, or was the step actually executed?
+    cached: bool,
+}
+
+// We could use a library for this, but they either:
+// - require lifetimes, which gets annoying (dot_writer)
+// - don't support tooltips (dot_graph)
+// - have a lot of dependencies (graphviz_rust)
+// - only have SVG export (layout-rs)
+// - use a builder pattern that is very annoying to use here (tabbycat)
+#[derive(Default)]
+struct DotGraph {
+    nodes: Vec<Node>,
+    /// The `NodeHandle` represents an index within `self.nodes`
+    edges: HashSet<Edge>,
+    key_to_index: HashMap<String, NodeHandle>,
+}
+
+impl DotGraph {
+    fn add_node(&mut self, key: String, node: Node) -> NodeHandle {
+        let handle = NodeHandle(self.nodes.len());
+        self.nodes.push(node);
+        self.key_to_index.insert(key, handle);
+        handle
+    }
+
+    fn add_edge(&mut self, src: NodeHandle, dst: NodeHandle) {
+        self.edges.insert(Edge { src, dst, cached: false });
+    }
+
+    fn add_cached_edge(&mut self, src: NodeHandle, dst: NodeHandle) {
+        // There's no point in rendering both cached and uncached edge
+        let uncached = Edge { src, dst, cached: false };
+        if !self.edges.contains(&uncached) {
+            self.edges.insert(Edge { src, dst, cached: true });
+        }
+    }
+
+    fn get_handle_by_key(&self, key: &str) -> Option<NodeHandle> {
+        self.key_to_index.get(key).copied()
+    }
+
+    fn render(&self, path: &str) -> std::io::Result<()> {
+        use std::io::Write;
+
+        let mut file = BufWriter::new(std::fs::File::create(path)?);
+        writeln!(file, "digraph bootstrap_steps {{")?;
+        for (index, node) in self.nodes.iter().enumerate() {
+            writeln!(
+                file,
+                r#"{index} [label="{}", tooltip="{}"]"#,
+                escape(&node.label),
+                escape(&node.tooltip)
+            )?;
+        }
+
+        let mut edges: Vec<&Edge> = self.edges.iter().collect();
+        edges.sort();
+        for edge in edges {
+            let style = if edge.cached { "dashed" } else { "solid" };
+            writeln!(file, r#"{} -> {} [style="{style}"]"#, edge.src.0, edge.dst.0)?;
+        }
+
+        writeln!(file, "}}")
+    }
+}
+
+fn render_step(step: &dyn Debug) -> String {
+    format!("{step:?}")
+}
+
+/// Normalizes the string so that it can be rendered into a DOT file.
+fn escape(input: &str) -> String {
+    input.replace("\"", "\\\"")
+}
diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml
index daf5223cbd4..6eabb999fb0 100644
--- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml
+++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml
@@ -17,7 +17,6 @@ jobs:
       MDBOOK_VERSION: 0.4.48
       MDBOOK_LINKCHECK2_VERSION: 0.9.1
       MDBOOK_MERMAID_VERSION: 0.12.6
-      MDBOOK_TOC_VERSION: 0.11.2
       MDBOOK_OUTPUT__LINKCHECK__FOLLOW_WEB_LINKS: ${{ github.event_name != 'pull_request' }}
       DEPLOY_DIR: book/html
       BASE_SHA: ${{ github.event.pull_request.base.sha }}
@@ -34,7 +33,7 @@ jobs:
         with:
           path: |
             ~/.cargo/bin
-          key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ env.MDBOOK_TOC_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }}
+          key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }}
 
       - name: Restore cached Linkcheck
         if: github.event_name == 'schedule'
@@ -57,7 +56,6 @@ jobs:
         run: |
           cargo install mdbook --version ${{ env.MDBOOK_VERSION }}
           cargo install mdbook-linkcheck2 --version ${{ env.MDBOOK_LINKCHECK2_VERSION }}
-          cargo install mdbook-toc --version ${{ env.MDBOOK_TOC_VERSION }}
           cargo install mdbook-mermaid --version ${{ env.MDBOOK_MERMAID_VERSION }}
 
       - name: Check build
diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
index ad570ee4595..04d6469aeaa 100644
--- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
+++ b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
@@ -11,10 +11,11 @@ jobs:
     if: github.repository == 'rust-lang/rustc-dev-guide'
     uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
     with:
+      github-app-id: ${{ vars.APP_CLIENT_ID }}
       zulip-stream-id: 196385
       zulip-bot-email:  "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com"
       pr-base-branch: master
       branch-name: rustc-pull
     secrets:
       zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }}
-      token: ${{ secrets.GITHUB_TOKEN }}
+      github-app-secret: ${{ secrets.APP_PRIVATE_KEY }}
diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md
index 5932da467ab..1ad895aeda2 100644
--- a/src/doc/rustc-dev-guide/README.md
+++ b/src/doc/rustc-dev-guide/README.md
@@ -43,7 +43,7 @@ rustdocs][rustdocs].
 To build a local static HTML site, install [`mdbook`](https://github.com/rust-lang/mdBook) with:
 
 ```
-cargo install mdbook mdbook-linkcheck2 mdbook-toc mdbook-mermaid
+cargo install mdbook mdbook-linkcheck2 mdbook-mermaid
 ```
 
 and execute the following command in the root of the repository:
@@ -67,8 +67,8 @@ ENABLE_LINKCHECK=1 mdbook serve
 
 ### Table of Contents
 
-We use `mdbook-toc` to auto-generate TOCs for long sections. You can invoke the preprocessor by
-including the `<!-- toc -->` marker at the place where you want the TOC.
+Each page has a TOC that is automatically generated by `pagetoc.js`.
+There is an associated `pagetoc.css`, for styling.
 
 ## Synchronizing josh subtree with rustc
 
diff --git a/src/doc/rustc-dev-guide/book.toml b/src/doc/rustc-dev-guide/book.toml
index b84b1e7548a..daf237ed908 100644
--- a/src/doc/rustc-dev-guide/book.toml
+++ b/src/doc/rustc-dev-guide/book.toml
@@ -6,17 +6,18 @@ description = "A guide to developing the Rust compiler (rustc)"
 [build]
 create-missing = false
 
-[preprocessor.toc]
-command = "mdbook-toc"
-renderer = ["html"]
-
 [preprocessor.mermaid]
 command = "mdbook-mermaid"
 
 [output.html]
 git-repository-url = "https://github.com/rust-lang/rustc-dev-guide"
 edit-url-template = "https://github.com/rust-lang/rustc-dev-guide/edit/master/{path}"
-additional-js = ["mermaid.min.js", "mermaid-init.js"]
+additional-js = [
+  "mermaid.min.js",
+  "mermaid-init.js",
+  "pagetoc.js",
+]
+additional-css = ["pagetoc.css"]
 
 [output.html.search]
 use-boolean-and = true
diff --git a/src/doc/rustc-dev-guide/pagetoc.css b/src/doc/rustc-dev-guide/pagetoc.css
new file mode 100644
index 00000000000..fa709194f37
--- /dev/null
+++ b/src/doc/rustc-dev-guide/pagetoc.css
@@ -0,0 +1,84 @@
+/* Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL) */
+
+:root {
+    --toc-width: 270px;
+    --center-content-toc-shift: calc(-1 * var(--toc-width) / 2);
+}
+
+.nav-chapters {
+    /* adjust width of buttons that bring to the previous or the next page */
+    min-width: 50px;
+}
+
+@media only screen {
+    @media (max-width: 1179px) {
+        .sidebar-hidden #sidetoc {
+            display: none;
+        }
+    }
+
+    @media (max-width: 1439px) {
+        .sidebar-visible #sidetoc {
+            display: none;
+        }
+    }
+
+    @media (1180px <= width <= 1439px) {
+        .sidebar-hidden main {
+            position: relative;
+            left: var(--center-content-toc-shift);
+        }
+    }
+
+    @media (1440px <= width <= 1700px) {
+        .sidebar-visible main {
+            position: relative;
+            left: var(--center-content-toc-shift);
+        }
+    }
+
+    #sidetoc {
+        margin-left: calc(100% + 20px);
+    }
+    #pagetoc {
+        position: fixed;
+        /* adjust TOC width */
+        width: var(--toc-width);
+        height: calc(100vh - var(--menu-bar-height) - 0.67em * 4);
+        overflow: auto;
+    }
+    #pagetoc a {
+        border-left: 1px solid var(--sidebar-bg);
+        color: var(--fg);
+        display: block;
+        padding-bottom: 5px;
+        padding-top: 5px;
+        padding-left: 10px;
+        text-align: left;
+        text-decoration: none;
+    }
+    #pagetoc a:hover,
+    #pagetoc a.active {
+        background: var(--sidebar-bg);
+        color: var(--sidebar-active) !important;
+    }
+    #pagetoc .active {
+        background: var(--sidebar-bg);
+        color: var(--sidebar-active);
+    }
+    #pagetoc .pagetoc-H2 {
+        padding-left: 20px;
+    }
+    #pagetoc .pagetoc-H3 {
+        padding-left: 40px;
+    }
+    #pagetoc .pagetoc-H4 {
+        padding-left: 60px;
+    }
+}
+
+@media print {
+    #sidetoc {
+        display: none;
+    }
+}
diff --git a/src/doc/rustc-dev-guide/pagetoc.js b/src/doc/rustc-dev-guide/pagetoc.js
new file mode 100644
index 00000000000..927a5b10749
--- /dev/null
+++ b/src/doc/rustc-dev-guide/pagetoc.js
@@ -0,0 +1,104 @@
+// Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL)
+
+let activeHref = location.href;
+function updatePageToc(elem = undefined) {
+    let selectedPageTocElem = elem;
+    const pagetoc = document.getElementById("pagetoc");
+
+    function getRect(element) {
+        return element.getBoundingClientRect();
+    }
+
+    function overflowTop(container, element) {
+        return getRect(container).top - getRect(element).top;
+    }
+
+    function overflowBottom(container, element) {
+        return getRect(container).bottom - getRect(element).bottom;
+    }
+
+    // We've not selected a heading to highlight, and the URL needs updating
+    // so we need to find a heading based on the URL
+    if (selectedPageTocElem === undefined && location.href !== activeHref) {
+        activeHref = location.href;
+        for (const pageTocElement of pagetoc.children) {
+            if (pageTocElement.href === activeHref) {
+                selectedPageTocElem = pageTocElement;
+            }
+        }
+    }
+
+    // We still don't have a selected heading, let's try and find the most
+    // suitable heading based on the scroll position
+    if (selectedPageTocElem === undefined) {
+        const margin = window.innerHeight / 3;
+
+        const headers = document.getElementsByClassName("header");
+        for (let i = 0; i < headers.length; i++) {
+            const header = headers[i];
+            if (selectedPageTocElem === undefined && getRect(header).top >= 0) {
+                if (getRect(header).top < margin) {
+                    selectedPageTocElem = header;
+                } else {
+                    selectedPageTocElem = headers[Math.max(0, i - 1)];
+                }
+            }
+            // a very long last section's heading is over the screen
+            if (selectedPageTocElem === undefined && i === headers.length - 1) {
+                selectedPageTocElem = header;
+            }
+        }
+    }
+
+    // Remove the active flag from all pagetoc elements
+    for (const pageTocElement of pagetoc.children) {
+        pageTocElement.classList.remove("active");
+    }
+
+    // If we have a selected heading, set it to active and scroll to it
+    if (selectedPageTocElem !== undefined) {
+        for (const pageTocElement of pagetoc.children) {
+            if (selectedPageTocElem.href.localeCompare(pageTocElement.href) === 0) {
+                pageTocElement.classList.add("active");
+                if (overflowTop(pagetoc, pageTocElement) > 0) {
+                    pagetoc.scrollTop = pageTocElement.offsetTop;
+                }
+                if (overflowBottom(pagetoc, pageTocElement) < 0) {
+                    pagetoc.scrollTop -= overflowBottom(pagetoc, pageTocElement);
+                }
+            }
+        }
+    }
+}
+
+if (document.getElementById("sidetoc") === null &&
+    document.getElementsByClassName("header").length > 0) {
+    // The sidetoc element doesn't exist yet, let's create it
+
+    // Create the empty sidetoc and pagetoc elements
+    const sidetoc = document.createElement("div");
+    const pagetoc = document.createElement("div");
+    sidetoc.id = "sidetoc";
+    pagetoc.id = "pagetoc";
+    sidetoc.appendChild(pagetoc);
+
+    // And append them to the current DOM
+    const main = document.querySelector('main');
+    main.insertBefore(sidetoc, main.firstChild);
+
+    // Populate sidebar on load
+    window.addEventListener("load", () => {
+        for (const header of document.getElementsByClassName("header")) {
+            const link = document.createElement("a");
+            link.innerHTML = header.innerHTML;
+            link.href = header.hash;
+            link.classList.add("pagetoc-" + header.parentElement.tagName);
+            document.getElementById("pagetoc").appendChild(link);
+            link.onclick = () => updatePageToc(link);
+        }
+        updatePageToc();
+    });
+
+    // Update page table of contents selected heading on scroll
+    window.addEventListener("scroll", () => updatePageToc());
+}
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index b631041b6bf..e9f1626f1fd 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-2b5e239c6b86cde974b0ef0f8e23754fb08ff3c5
+383b9c447b61641e1f1a3850253944a897a60827
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index e3c0d50fcc7..9ded467d5cd 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -176,6 +176,7 @@
     - [Next-gen trait solving](./solve/trait-solving.md)
         - [Invariants of the type system](./solve/invariants.md)
         - [The solver](./solve/the-solver.md)
+        - [Candidate preference](./solve/candidate-preference.md)
         - [Canonicalization](./solve/canonicalization.md)
         - [Coinduction](./solve/coinduction.md)
         - [Caching](./solve/caching.md)
diff --git a/src/doc/rustc-dev-guide/src/appendix/humorust.md b/src/doc/rustc-dev-guide/src/appendix/humorust.md
index 6df3b212aa7..8681512ed56 100644
--- a/src/doc/rustc-dev-guide/src/appendix/humorust.md
+++ b/src/doc/rustc-dev-guide/src/appendix/humorust.md
@@ -3,7 +3,7 @@
 What's a project without a sense of humor? And frankly some of these are
 enlightening?
 
-- [Weird exprs test](https://github.com/rust-lang/rust/blob/master/tests/ui/weird-exprs.rs)
+- [Weird exprs test](https://github.com/rust-lang/rust/blob/master/tests/ui/expr/weird-exprs.rs)
 - [Ferris Rap](https://fitzgen.com/2018/12/13/rust-raps.html)
 - [The Genesis of Generic Germination](https://github.com/rust-lang/rust/pull/53645#issue-210543221)
 - [The Bastion of the Turbofish test](https://github.com/rust-lang/rust/blob/79d8a0fcefa5134db2a94739b1d18daa01fc6e9f/src/test/ui/bastion-of-the-turbofish.rs)
diff --git a/src/doc/rustc-dev-guide/src/asm.md b/src/doc/rustc-dev-guide/src/asm.md
index 1bb493e73d5..b5857d5465e 100644
--- a/src/doc/rustc-dev-guide/src/asm.md
+++ b/src/doc/rustc-dev-guide/src/asm.md
@@ -1,7 +1,5 @@
 # Inline assembly
 
-<!-- toc -->
-
 ## Overview
 
 Inline assembly in rustc mostly revolves around taking an `asm!` macro invocation and plumbing it
diff --git a/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md b/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
index 0f81d3cb48a..2fdda4eda99 100644
--- a/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
+++ b/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
@@ -1,7 +1,5 @@
 # Backend Agnostic Codegen
 
-<!-- toc -->
-
 [`rustc_codegen_ssa`]
 provides an abstract interface for all backends to implement,
 namely LLVM, [Cranelift], and [GCC].
diff --git a/src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md b/src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md
index c5ee00813a3..9ca4bcab078 100644
--- a/src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md
+++ b/src/doc/rustc-dev-guide/src/backend/implicit-caller-location.md
@@ -1,7 +1,5 @@
 # Implicit caller location
 
-<!-- toc -->
-
 Approved in [RFC 2091], this feature enables the accurate reporting of caller location during panics
 initiated from functions like `Option::unwrap`, `Result::expect`, and `Index::index`. This feature
 adds the [`#[track_caller]`][attr-reference] attribute for functions, the
diff --git a/src/doc/rustc-dev-guide/src/backend/monomorph.md b/src/doc/rustc-dev-guide/src/backend/monomorph.md
index 7ebb4d2b1e8..e9d98597ee0 100644
--- a/src/doc/rustc-dev-guide/src/backend/monomorph.md
+++ b/src/doc/rustc-dev-guide/src/backend/monomorph.md
@@ -1,7 +1,5 @@
 # Monomorphization
 
-<!-- toc -->
-
 As you probably know, Rust has a very expressive type system that has extensive
 support for generic types. But of course, assembly is not generic, so we need
 to figure out the concrete types of all the generics before the code can
diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
index 18c822aad79..ebef15d40ba 100644
--- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
+++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
@@ -1,7 +1,5 @@
 # Updating LLVM
 
-<!-- toc -->
-
 <!-- date-check: Aug 2024 -->
 Rust supports building against multiple LLVM versions:
 
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md b/src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md
index ad9c75d6296..95518fbc018 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/moves_and_initialization/move_paths.md
@@ -1,7 +1,5 @@
 # Move paths
 
-<!-- toc -->
-
 In reality, it's not enough to track initialization at the granularity
 of local variables. Rust also allows us to do moves and initialization
 at the field granularity:
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md
index 85e71b4fa42..0d55ab95583 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md
@@ -1,7 +1,5 @@
 # Region inference (NLL)
 
-<!-- toc -->
-
 The MIR-based region checking code is located in [the `rustc_mir::borrow_check`
 module][nll].
 
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md
index 4c30d25e040..c3f8c03cb29 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/constraint_propagation.md
@@ -1,7 +1,5 @@
 # Constraint propagation
 
-<!-- toc -->
-
 The main work of the region inference is **constraint propagation**,
 which is done in the [`propagate_constraints`] function.  There are
 three sorts of constraints that are used in NLL, and we'll explain how
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md
index fadfac40456..2d337dbc020 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/lifetime_parameters.md
@@ -1,7 +1,5 @@
 # Universal regions
 
-<!-- toc -->
-
 "Universal regions" is the name that the code uses to refer to "named
 lifetimes" -- e.g., lifetime parameters and `'static`. The name
 derives from the fact that such lifetimes are "universally quantified"
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
index fd7c87ffcea..2804c97724f 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
@@ -1,7 +1,5 @@
 # Member constraints
 
-<!-- toc -->
-
 A member constraint `'m member of ['c_1..'c_N]` expresses that the
 region `'m` must be *equal* to some **choice regions** `'c_i` (for
 some `i`). These constraints cannot be expressed by users, but they
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md
index 91c8c452611..11fd2a5fc7d 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/placeholders_and_universes.md
@@ -1,7 +1,5 @@
 # Placeholders and universes
 
-<!-- toc -->
-
 From time to time we have to reason about regions that we can't
 concretely know. For example, consider this program:
 
diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
index 55436261fde..6b13c97023f 100644
--- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
+++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
@@ -1,7 +1,5 @@
 # Procedures for breaking changes
 
-<!-- toc -->
-
 This page defines the best practices procedure for making bug fixes or soundness
 corrections in the compiler that can cause existing code to stop compiling. This
 text is based on
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
index c9c0d64a604..9c5ebbd36c4 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
@@ -123,6 +123,12 @@ if [#96176][cleanup-compiler-for] is resolved.
 
 [cleanup-compiler-for]: https://github.com/rust-lang/rust/issues/96176
 
+### Rendering step graph
+
+When you run bootstrap with the `BOOTSTRAP_TRACING` environment variable configured, bootstrap will automatically output a DOT file that shows all executed steps and their dependencies. The files will have a prefix `bootstrap-steps`. You can use e.g. `xdot` to visualize the file or e.g. `dot -Tsvg` to convert the DOT file to a SVG file.
+
+A separate DOT file will be outputted for dry-run and non-dry-run execution.
+
 ### Using `tracing` in bootstrap
 
 Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. Examples:
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
index 2793ad43815..da425d8d39b 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
@@ -1,7 +1,5 @@
 # What Bootstrapping does
 
-<!-- toc -->
-
 [*Bootstrapping*][boot] is the process of using a compiler to compile itself.
 More accurately, it means using an older compiler to compile a newer version of
 the same compiler.
diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
index d29cd144810..b07d3533f59 100644
--- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
+++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
@@ -1,7 +1,5 @@
 # How to build and run the compiler
 
-<!-- toc -->
-
 <div class="warning">
 
 For `profile = "library"` users, or users who use `download-rustc = true | "if-unchanged"`, please be advised that
diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md
index e11a2cd8ee5..436aec8ee26 100644
--- a/src/doc/rustc-dev-guide/src/building/new-target.md
+++ b/src/doc/rustc-dev-guide/src/building/new-target.md
@@ -6,8 +6,6 @@ relevant to your desired goal.
 
 See also the associated documentation in the [target tier policy].
 
-<!-- toc -->
-
 [target tier policy]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
 
 ## Specifying a new LLVM
diff --git a/src/doc/rustc-dev-guide/src/building/optimized-build.md b/src/doc/rustc-dev-guide/src/building/optimized-build.md
index 62dfaca89d2..863ed9749fb 100644
--- a/src/doc/rustc-dev-guide/src/building/optimized-build.md
+++ b/src/doc/rustc-dev-guide/src/building/optimized-build.md
@@ -1,7 +1,5 @@
 # Optimized build of the compiler
 
-<!-- toc -->
-
 There are multiple additional build configuration options and techniques that can be used to compile a
 build of `rustc` that is as optimized as possible (for example when building `rustc` for a Linux
 distribution). The status of these configuration options for various Rust targets is tracked [here].
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index c046161e77f..35c7e935b56 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -3,8 +3,6 @@
 The full bootstrapping process takes quite a while. Here are some suggestions to
 make your life easier.
 
-<!-- toc -->
-
 ## Installing a pre-push hook
 
 CI will automatically fail your build if it doesn't pass `tidy`, our internal
diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md
index 102e2020779..edd2aa6c5f6 100644
--- a/src/doc/rustc-dev-guide/src/compiler-debugging.md
+++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md
@@ -1,7 +1,5 @@
 # Debugging the compiler
 
-<!-- toc -->
-
 This chapter contains a few tips to debug the compiler. These tips aim to be
 useful no matter what you are working on.  Some of the other chapters have
 advice about specific parts of the compiler (e.g. the [Queries Debugging and
diff --git a/src/doc/rustc-dev-guide/src/compiler-src.md b/src/doc/rustc-dev-guide/src/compiler-src.md
index 00aa9622684..d67bacb1b33 100644
--- a/src/doc/rustc-dev-guide/src/compiler-src.md
+++ b/src/doc/rustc-dev-guide/src/compiler-src.md
@@ -1,7 +1,5 @@
 # High-level overview of the compiler source
 
-<!-- toc -->
-
 Now that we have [seen what the compiler does][orgch],
 let's take a look at the structure of the [`rust-lang/rust`] repository,
 where the rustc source code lives.
diff --git a/src/doc/rustc-dev-guide/src/const-eval/interpret.md b/src/doc/rustc-dev-guide/src/const-eval/interpret.md
index 51a539de5cb..08382b12ff0 100644
--- a/src/doc/rustc-dev-guide/src/const-eval/interpret.md
+++ b/src/doc/rustc-dev-guide/src/const-eval/interpret.md
@@ -1,7 +1,5 @@
 # Interpreter
 
-<!-- toc -->
-
 The interpreter is a virtual machine for executing MIR without compiling to
 machine code. It is usually invoked via `tcx.const_eval_*` functions. The
 interpreter is shared between the compiler (for compile-time function
diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md
index b3fcd79ec81..963bef3af8d 100644
--- a/src/doc/rustc-dev-guide/src/contributing.md
+++ b/src/doc/rustc-dev-guide/src/contributing.md
@@ -1,7 +1,5 @@
 # Contribution procedures
 
-<!-- toc -->
-
 ## Bug reports
 
 While bugs are unfortunate, they're a reality in software. We can't fix what we
diff --git a/src/doc/rustc-dev-guide/src/coroutine-closures.md b/src/doc/rustc-dev-guide/src/coroutine-closures.md
index 48cdba44a9f..2617c824a39 100644
--- a/src/doc/rustc-dev-guide/src/coroutine-closures.md
+++ b/src/doc/rustc-dev-guide/src/coroutine-closures.md
@@ -1,7 +1,5 @@
 # Async closures/"coroutine-closures"
 
-<!-- toc -->
-
 Please read [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) to understand the general motivation of the feature. This is a very technical and somewhat "vertical" chapter; ideally we'd split this and sprinkle it across all the relevant chapters, but for the purposes of understanding async closures *holistically*, I've put this together all here in one chapter.
 
 ## Coroutine-closures -- a technical deep dive
diff --git a/src/doc/rustc-dev-guide/src/crates-io.md b/src/doc/rustc-dev-guide/src/crates-io.md
index 4431585a2f0..677b1fc0313 100644
--- a/src/doc/rustc-dev-guide/src/crates-io.md
+++ b/src/doc/rustc-dev-guide/src/crates-io.md
@@ -11,7 +11,7 @@ you should avoid adding dependencies to the compiler for several reasons:
 - The dependency may have transitive dependencies that have one of the above
   problems.
 
-<!-- date-check: Feb 2023 -->
+<!-- date-check: Aug 2025 -->
 Note that there is no official policy for vetting new dependencies to the compiler.
 Decisions are made on a case-by-case basis, during code review.
 
diff --git a/src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md b/src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md
index ac629934e0a..bd4f795ce03 100644
--- a/src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md
+++ b/src/doc/rustc-dev-guide/src/debugging-support-in-rustc.md
@@ -1,7 +1,5 @@
 # Debugging support in the Rust compiler
 
-<!-- toc -->
-
 This document explains the state of debugging tools support in the Rust compiler (rustc).
 It gives an overview of GDB, LLDB, WinDbg/CDB,
 as well as infrastructure around Rust compiler to debug Rust code.
diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md
index 33f5441d36e..82191e0a6ea 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics.md
@@ -1,7 +1,5 @@
 # Errors and lints
 
-<!-- toc -->
-
 A lot of effort has been put into making `rustc` have great error messages.
 This chapter is about how to emit compile errors and lints from the compiler.
 
diff --git a/src/doc/rustc-dev-guide/src/early_late_parameters.md b/src/doc/rustc-dev-guide/src/early_late_parameters.md
index 3f94b090566..c472bdc2c48 100644
--- a/src/doc/rustc-dev-guide/src/early_late_parameters.md
+++ b/src/doc/rustc-dev-guide/src/early_late_parameters.md
@@ -1,8 +1,6 @@
 
 # Early vs Late bound parameters
 
-<!-- toc -->
-
 > **NOTE**: This chapter largely talks about early/late bound as being solely relevant when discussing function item types/function definitions. This is potentially not completely true, async blocks and closures should likely be discussed somewhat in this chapter.
 
 ## What does it mean to be "early" bound or "late" bound
diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md
index d6c5c3ac852..04d2e37732f 100644
--- a/src/doc/rustc-dev-guide/src/getting-started.md
+++ b/src/doc/rustc-dev-guide/src/getting-started.md
@@ -3,8 +3,6 @@
 Thank you for your interest in contributing to Rust! There are many ways to
 contribute, and we appreciate all of them.
 
-<!-- toc -->
-
 If this is your first time contributing, the [walkthrough] chapter can give you a good example of
 how a typical contribution would go.
 
diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md
index 8726ddfce20..447c6fd4546 100644
--- a/src/doc/rustc-dev-guide/src/git.md
+++ b/src/doc/rustc-dev-guide/src/git.md
@@ -1,7 +1,5 @@
 # Using Git
 
-<!-- toc -->
-
 The Rust project uses [Git] to manage its source code. In order to
 contribute, you'll need some familiarity with its features so that your changes
 can be incorporated into the compiler.
diff --git a/src/doc/rustc-dev-guide/src/guides/editions.md b/src/doc/rustc-dev-guide/src/guides/editions.md
index 9a92d4ebcb5..b65fbb13cd1 100644
--- a/src/doc/rustc-dev-guide/src/guides/editions.md
+++ b/src/doc/rustc-dev-guide/src/guides/editions.md
@@ -1,7 +1,5 @@
 # Editions
 
-<!-- toc -->
-
 This chapter gives an overview of how Edition support works in rustc.
 This assumes that you are familiar with what Editions are (see the [Edition Guide]).
 
diff --git a/src/doc/rustc-dev-guide/src/hir.md b/src/doc/rustc-dev-guide/src/hir.md
index 72fb1070157..38ba33112f2 100644
--- a/src/doc/rustc-dev-guide/src/hir.md
+++ b/src/doc/rustc-dev-guide/src/hir.md
@@ -1,7 +1,5 @@
 # The HIR
 
-<!-- toc -->
-
 The HIR – "High-Level Intermediate Representation" – is the primary IR used
 in most of rustc. It is a compiler-friendly representation of the abstract
 syntax tree (AST) that is generated after parsing, macro expansion, and name
diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md
index 76cf2386c82..00bce8599e4 100644
--- a/src/doc/rustc-dev-guide/src/implementing_new_features.md
+++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md
@@ -1,7 +1,5 @@
 # Implementing new language features
 
-<!-- toc -->
-
 When you want to implement a new significant feature in the compiler, you need to go through this process to make sure everything goes smoothly.
 
 **NOTE: This section is for *language* features, not *library* features, which use [a different process].**
diff --git a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
index 880363b94bf..288b90f33c3 100644
--- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
+++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
@@ -1,7 +1,5 @@
 # LLVM source-based code coverage
 
-<!-- toc -->
-
 `rustc` supports detailed source-based code and test coverage analysis
 with a command line option (`-C instrument-coverage`) that instruments Rust
 libraries and binaries with additional instructions and data, at compile time.
diff --git a/src/doc/rustc-dev-guide/src/macro-expansion.md b/src/doc/rustc-dev-guide/src/macro-expansion.md
index a90f717004f..54d6d2b4e81 100644
--- a/src/doc/rustc-dev-guide/src/macro-expansion.md
+++ b/src/doc/rustc-dev-guide/src/macro-expansion.md
@@ -1,7 +1,5 @@
 # Macro expansion
 
-<!-- toc -->
-
 Rust has a very powerful macro system. In the previous chapter, we saw how
 the parser sets aside macros to be expanded (using temporary [placeholders]).
 This chapter is about the process of expanding those macros iteratively until
diff --git a/src/doc/rustc-dev-guide/src/mir/construction.md b/src/doc/rustc-dev-guide/src/mir/construction.md
index f2559a22b95..8360d9ff1a8 100644
--- a/src/doc/rustc-dev-guide/src/mir/construction.md
+++ b/src/doc/rustc-dev-guide/src/mir/construction.md
@@ -1,7 +1,5 @@
 # MIR construction
 
-<!-- toc -->
-
 The lowering of [HIR] to [MIR] occurs for the following (probably incomplete)
 list of items:
 
diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md
index 85e57dd839b..970e61196c1 100644
--- a/src/doc/rustc-dev-guide/src/mir/dataflow.md
+++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md
@@ -1,7 +1,5 @@
 # Dataflow Analysis
 
-<!-- toc -->
-
 If you work on the MIR, you will frequently come across various flavors of
 [dataflow analysis][wiki]. `rustc` uses dataflow to find uninitialized
 variables, determine what variables are live across a generator `yield`
diff --git a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
index 3b321fd44d1..4da612c83f0 100644
--- a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
+++ b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
@@ -1,7 +1,5 @@
 # Drop elaboration
 
-<!-- toc -->
-
 ## Dynamic drops
 
 According to the [reference][reference-drop]:
diff --git a/src/doc/rustc-dev-guide/src/mir/index.md b/src/doc/rustc-dev-guide/src/mir/index.md
index f355875aa15..8ba5f3ac8b7 100644
--- a/src/doc/rustc-dev-guide/src/mir/index.md
+++ b/src/doc/rustc-dev-guide/src/mir/index.md
@@ -1,7 +1,5 @@
 # The MIR (Mid-level IR)
 
-<!-- toc -->
-
 MIR is Rust's _Mid-level Intermediate Representation_. It is
 constructed from [HIR](../hir.html). MIR was introduced in
 [RFC 1211]. It is a radically simplified form of Rust that is used for
diff --git a/src/doc/rustc-dev-guide/src/name-resolution.md b/src/doc/rustc-dev-guide/src/name-resolution.md
index 719ebce8553..2e96382f779 100644
--- a/src/doc/rustc-dev-guide/src/name-resolution.md
+++ b/src/doc/rustc-dev-guide/src/name-resolution.md
@@ -1,7 +1,5 @@
 # Name resolution
 
-<!-- toc -->
-
 In the previous chapters, we saw how the [*Abstract Syntax Tree* (`AST`)][ast]
 is built with all macros expanded. We saw how doing that requires doing some
 name resolution to resolve imports and macro names. In this chapter, we show
diff --git a/src/doc/rustc-dev-guide/src/normalization.md b/src/doc/rustc-dev-guide/src/normalization.md
index eb0962a4122..53e20f1c0db 100644
--- a/src/doc/rustc-dev-guide/src/normalization.md
+++ b/src/doc/rustc-dev-guide/src/normalization.md
@@ -1,7 +1,5 @@
 # Aliases and Normalization
 
-<!-- toc -->
-
 ## Aliases
 
 In Rust there are a number of types that are considered equal to some "underlying" type, for example inherent associated types, trait associated types, free type aliases (`type Foo = u32`), and opaque types (`-> impl RPIT`). We consider such types to be "aliases", alias types are represented by the [`TyKind::Alias`][tykind_alias] variant, with the kind of alias tracked by the [`AliasTyKind`][aliaskind] enum.
diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md
index 8a1a22fad66..12b76828b5c 100644
--- a/src/doc/rustc-dev-guide/src/overview.md
+++ b/src/doc/rustc-dev-guide/src/overview.md
@@ -1,7 +1,5 @@
 # Overview of the compiler
 
-<!-- toc -->
-
 This chapter is about the overall process of compiling a program -- how
 everything fits together.
 
diff --git a/src/doc/rustc-dev-guide/src/panic-implementation.md b/src/doc/rustc-dev-guide/src/panic-implementation.md
index 468190ffccd..dba3f2146d2 100644
--- a/src/doc/rustc-dev-guide/src/panic-implementation.md
+++ b/src/doc/rustc-dev-guide/src/panic-implementation.md
@@ -1,7 +1,5 @@
 # Panicking in Rust
 
-<!-- toc -->
-
 ## Step 1: Invocation of the `panic!` macro.
 
 There are actually two panic macros - one defined in `core`, and one defined in `std`.
diff --git a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
index 2fa81021045..4e3dadd406e 100644
--- a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
+++ b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md
@@ -1,7 +1,5 @@
 # Profile-guided optimization
 
-<!-- toc -->
-
 `rustc` supports doing profile-guided optimization (PGO).
 This chapter describes what PGO is and how the support for it is
 implemented in `rustc`.
diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
index 18e0e25c531..46e38832e64 100644
--- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
+++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
@@ -1,7 +1,5 @@
 # Incremental compilation in detail
 
-<!-- toc -->
-
 The incremental compilation scheme is, in essence, a surprisingly
 simple extension to the overall query system. It relies on the fact that:
 
diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation.md
index 6e5b4e8cc49..731ff3287d9 100644
--- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation.md
+++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation.md
@@ -1,7 +1,5 @@
 # Incremental compilation
 
-<!-- toc -->
-
 The incremental compilation scheme is, in essence, a surprisingly
 simple extension to the overall query system. We'll start by describing
 a slightly simplified variant of the real thing – the "basic algorithm" –
diff --git a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
index 444e20bc580..c1a4373f7da 100644
--- a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
+++ b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
@@ -1,7 +1,5 @@
 # The Query Evaluation Model in detail
 
-<!-- toc -->
-
 This chapter provides a deeper dive into the abstract model queries are built on.
 It does not go into implementation details but tries to explain
 the underlying logic. The examples here, therefore, have been stripped down and
diff --git a/src/doc/rustc-dev-guide/src/queries/salsa.md b/src/doc/rustc-dev-guide/src/queries/salsa.md
index 1a7b7fa9a68..dc7160edc22 100644
--- a/src/doc/rustc-dev-guide/src/queries/salsa.md
+++ b/src/doc/rustc-dev-guide/src/queries/salsa.md
@@ -1,7 +1,5 @@
 # How Salsa works
 
-<!-- toc -->
-
 This chapter is based on the explanation given by Niko Matsakis in this
 [video](https://www.youtube.com/watch?v=_muY4HjSqVw) about
 [Salsa](https://github.com/salsa-rs/salsa). To find out more you may
diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md
index 0ca1b360a70..8377a7b2f31 100644
--- a/src/doc/rustc-dev-guide/src/query.md
+++ b/src/doc/rustc-dev-guide/src/query.md
@@ -1,7 +1,5 @@
 # Queries: demand-driven compilation
 
-<!-- toc -->
-
 As described in [Overview of the compiler], the Rust compiler
 is still (as of <!-- date-check --> July 2021) transitioning from a
 traditional "pass-based" setup to a "demand-driven" system. The compiler query
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
index 0234d4a920e..4affbafe477 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
@@ -1,7 +1,5 @@
 # Rustdoc Internals
 
-<!-- toc -->
-
 This page describes [`rustdoc`]'s passes and modes. For an overview of `rustdoc`,
 see the ["Rustdoc overview" chapter](./rustdoc.md).
 
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md
index 3506431118b..beff0a94c1e 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md
@@ -7,8 +7,6 @@ in the crates in the doc bundle, and the second reads
 it, turns it into some in-memory structures, and
 scans them linearly to search.
 
-<!-- toc -->
-
 ## Search index format
 
 `search.js` calls this Raw, because it turns it into
diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md
index 52ae48c3735..9290fcd3b41 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc.md
@@ -9,8 +9,6 @@ For more details about how rustdoc works, see the
 
 [Rustdoc internals]: ./rustdoc-internals.md
 
-<!-- toc -->
-
 `rustdoc` uses `rustc` internals (and, of course, the standard library), so you
 will have to build the compiler and `std` once before you can build `rustdoc`.
 
diff --git a/src/doc/rustc-dev-guide/src/solve/candidate-preference.md b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md
new file mode 100644
index 00000000000..89605294735
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md
@@ -0,0 +1,427 @@
+# Candidate preference
+
+There are multiple ways to prove `Trait` and `NormalizesTo` goals. Each such option is called a [`Candidate`]. If there are multiple applicable candidates, we prefer some candidates over others. We store the relevant information in their [`CandidateSource`].
+
+This preference may result in incorrect inference or region constraints and would therefore be unsound during coherence. Because of this, we simply try to merge all candidates in coherence.
+
+## `Trait` goals
+
+Trait goals merge their applicable candidates in [`fn merge_trait_candidates`]. This document provides additional details and references to explain *why* we've got the current preference rules.
+
+### `CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))`
+
+Trivial builtin impls are builtin impls which are known to be always applicable for well-formed types. This means that if one exists, using another candidate should never have fewer constraints. We currently only consider `Sized` - and `MetaSized` - impls to be trivial.
+
+This is necessary to prevent a lifetime error for the following pattern
+
+```rust
+trait Trait<T>: Sized {}
+impl<'a> Trait<u32> for &'a str {}
+impl<'a> Trait<i32> for &'a str {}
+fn is_sized<T: Sized>(_: T) {}
+fn foo<'a, 'b, T>(x: &'b str)
+where
+    &'a str: Trait<T>,
+{
+    // Elaborating the `&'a str: Trait<T>` where-bound results in a
+    // `&'a str: Sized` where-bound. We do not want to prefer this
+    // over the builtin impl. 
+    is_sized(x);
+}
+```
+
+This preference is incorrect in case the builtin impl has a nested goal which relies on a non-param where-clause
+```rust
+struct MyType<'a, T: ?Sized>(&'a (), T);
+fn is_sized<T>() {}
+fn foo<'a, T: ?Sized>()
+where
+    (MyType<'a, T>,): Sized,
+    MyType<'static, T>: Sized,
+{
+    // The where-bound is trivial while the builtin `Sized` impl for tuples
+    // requires proving `MyType<'a, T>: Sized` which can only be proven by
+    // using the where-clause, adding an unnecessary `'static` constraint.
+    is_sized::<(MyType<'a, T>,)>();
+    //~^ ERROR lifetime may not live long enough
+}
+```
+
+### `CandidateSource::ParamEnv`
+
+Once there's at least one *non-global* `ParamEnv` candidate, we prefer *all* `ParamEnv` candidates over other candidate kinds.
+A where-bound is global if it is not higher-ranked and doesn't contain any generic parameters. It may contain `'static`.
+
+We try to apply where-bounds over other candidates as users tends to have the most control over them, so they can most easily
+adjust them in case our candidate preference is incorrect.
+
+#### Preference over `Impl` candidates
+
+This is necessary to avoid region errors in the following example
+
+```rust
+trait Trait<'a> {}
+impl<T> Trait<'static> for T {}
+fn impls_trait<'a, T: Trait<'a>>() {}
+fn foo<'a, T: Trait<'a>>() {
+    impls_trait::<'a, T>();
+}
+```
+
+We also need this as shadowed impls can result in currently ambiguous solver cycles: [trait-system-refactor-initiative#76]. Without preference we'd be forced to fail with ambiguity
+errors if the where-bound results in region constraints to avoid incompleteness.
+```rust
+trait Super {
+    type SuperAssoc;
+}
+
+trait Trait: Super<SuperAssoc = Self::TraitAssoc> {
+    type TraitAssoc;
+}
+
+impl<T, U> Trait for T
+where
+    T: Super<SuperAssoc = U>,
+{
+    type TraitAssoc = U;
+}
+
+fn overflow<T: Trait>() {
+    // We can use the elaborated `Super<SuperAssoc = Self::TraitAssoc>` where-bound
+    // to prove the where-bound of the `T: Trait` implementation. This currently results in
+    // overflow. 
+    let x: <T as Trait>::TraitAssoc;
+}
+```
+
+This preference causes a lot of issues. See [#24066]. Most of the
+issues are caused by prefering where-bounds over impls even if the where-bound guides type inference:
+```rust
+trait Trait<T> {
+    fn call_me(&self, x: T) {}
+}
+impl<T> Trait<u32> for T {}
+impl<T> Trait<i32> for T {}
+fn bug<T: Trait<U>, U>(x: T) {
+    x.call_me(1u32);
+    //~^ ERROR mismatched types
+}
+```
+However, even if we only apply this preference if the where-bound doesn't guide inference, it may still result
+in incorrect lifetime constraints:
+```rust
+trait Trait<'a> {}
+impl<'a> Trait<'a> for &'a str {}
+fn impls_trait<'a, T: Trait<'a>>(_: T) {}
+fn foo<'a, 'b>(x: &'b str)
+where
+    &'a str: Trait<'b>
+{
+    // Need to prove `&'x str: Trait<'b>` with `'b: 'x`.
+    impls_trait::<'b, _>(x);
+    //~^ ERROR lifetime may not live long enough
+}
+```
+
+#### Preference over `AliasBound` candidates
+
+This is necessary to avoid region errors in the following example
+```rust
+trait Bound<'a> {}
+trait Trait<'a> {
+    type Assoc: Bound<'a>;
+}
+
+fn impls_bound<'b, T: Bound<'b>>() {}
+fn foo<'a, 'b, 'c, T>()
+where
+    T: Trait<'a>,
+    for<'hr> T::Assoc: Bound<'hr>,
+{
+    impls_bound::<'b, T::Assoc>();
+    impls_bound::<'c, T::Assoc>();
+}
+```
+It can also result in unnecessary constraints
+```rust
+trait Bound<'a> {}
+trait Trait<'a> {
+    type Assoc: Bound<'a>;
+}
+
+fn impls_bound<'b, T: Bound<'b>>() {}
+fn foo<'a, 'b, T>()
+where
+    T: for<'hr> Trait<'hr>,
+    <T as Trait<'b>>::Assoc: Bound<'a>,
+{
+    // Using the where-bound for `<T as Trait<'a>>::Assoc: Bound<'a>`
+    // unnecessarily equates `<T as Trait<'a>>::Assoc` with the
+    // `<T as Trait<'b>>::Assoc` from the env.
+    impls_bound::<'a, <T as Trait<'a>>::Assoc>();
+    // For a `<T as Trait<'b>>::Assoc: Bound<'b>` the self type of the
+    // where-bound matches, but the arguments of the trait bound don't.
+    impls_bound::<'b, <T as Trait<'b>>::Assoc>();
+}
+```
+
+#### Why no preference for global where-bounds
+
+Global where-bounds are either fully implied by an impl or unsatisfiable. If they are unsatisfiable, we don't really care what happens. If a where-bound is fully implied then using the impl to prove the trait goal cannot result in additional constraints. For trait goals this is only useful for where-bounds which use `'static`:
+
+```rust
+trait A {
+    fn test(&self);
+}
+
+fn foo(x: &dyn A)
+where
+    dyn A + 'static: A, // Using this bound would lead to a lifetime error.
+{
+    x.test();
+}
+```
+More importantly, by using impls here we prevent global where-bounds from shadowing impls when normalizing associated types. There are no known issues from preferring impls over global where-bounds.
+
+#### Why still consider global where-bounds
+
+Given that we just use impls even if there exists a global where-bounds, you may ask why we don't just ignore these global where-bounds entirely: we use them to weaken the inference guidance from non-global where-bounds.
+
+Without a global where-bound, we currently prefer non-global where bounds even though there would be an applicable impl as well. By adding a non-global where-bound, this unnecessary inference guidance is disabled, allowing the following to compile:
+```rust
+fn check<Color>(color: Color)
+where
+    Vec: Into<Color> + Into<f32>,
+{
+    let _: f32 = Vec.into();
+    // Without the global `Vec: Into<f32>`  bound we'd
+    // eagerly use the non-global `Vec: Into<Color>` bound
+    // here, causing this to fail.
+}
+
+struct Vec;
+impl From<Vec> for f32 {
+    fn from(_: Vec) -> Self {
+        loop {}
+    }
+}
+```
+
+### `CandidateSource::AliasBound`
+
+We prefer alias-bound candidates over impls. We currently use this preference to guide type inference, causing the following to compile. I personally don't think this preference is desirable 🤷
+```rust
+pub trait Dyn {
+    type Word: Into<u64>;
+    fn d_tag(&self) -> Self::Word;
+    fn tag32(&self) -> Option<u32> {
+        self.d_tag().into().try_into().ok()
+        // prove `Self::Word: Into<?0>` and then select a method
+        // on `?0`, needs eager inference.
+    }
+}
+```
+```rust
+fn impl_trait() -> impl Into<u32> {
+    0u16
+}
+
+fn main() {
+    // There are two possible types for `x`:
+    // - `u32` by using the "alias bound" of `impl Into<u32>`
+    // - `impl Into<u32>`, i.e. `u16`, by using `impl<T> From<T> for T`
+    //
+    // We infer the type of `x` to be `u32` even though this is not
+    // strictly necessary and can even lead to surprising errors.
+    let x = impl_trait().into();
+    println!("{}", std::mem::size_of_val(&x));
+}
+```
+This preference also avoids ambiguity due to region constraints, I don't know whether people rely on this in practice.
+```rust
+trait Bound<'a> {}
+impl<T> Bound<'static> for T {}
+trait Trait<'a> {
+    type Assoc: Bound<'a>;
+}
+
+fn impls_bound<'b, T: Bound<'b>>() {}
+fn foo<'a, T: Trait<'a>>() {
+    // Should we infer this to `'a` or `'static`.
+    impls_bound::<'_, T::Assoc>();
+}
+```
+
+### `CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_))`
+
+We prefer builtin trait object impls over user-written impls. This is **unsound** and should be remoed in the future. See [#57893](https://github.com/rust-lang/rust/issues/57893) and [#141347](https://github.com/rust-lang/rust/pull/141347) for more details.
+
+## `NormalizesTo` goals
+
+The candidate preference behavior during normalization is implemented in [`fn assemble_and_merge_candidates`].
+
+### Where-bounds shadow impls
+
+Normalization of associated items does not consider impls if the corresponding trait goal has been proven via a `ParamEnv` or `AliasBound` candidate.
+This means that for where-bounds which do not constrain associated types, the associated types remain *rigid*.
+
+This is necessary to avoid unnecessary region constraints from applying impls.
+```rust
+trait Trait<'a> {
+    type Assoc;
+}
+impl Trait<'static> for u32 {
+    type Assoc = u32;
+}
+
+fn bar<'b, T: Trait<'b>>() -> T::Assoc { todo!() }
+fn foo<'a>()
+where
+    u32: Trait<'a>,
+{
+    // Normalizing the return type would use the impl, proving
+    // the `T: Trait` where-bound would use the where-bound, resulting
+    // in different region constraints.
+    bar::<'_, u32>();
+}
+```
+
+### We always consider `AliasBound` candidates
+
+In case the where-bound does not specify the associated item, we consider `AliasBound` candidates instead of treating the alias as rigid, even though the trait goal was proven via a `ParamEnv` candidate.
+
+```rust
+trait Super {
+    type Assoc;
+}
+trait Bound {
+    type Assoc: Super<Assoc = u32>;
+}
+trait Trait: Super {}
+
+// Elaborating the environment results in a `T::Assoc: Super` where-bound.
+// This where-bound must not prevent normalization via the `Super<Assoc = u32>`
+// item bound.
+fn heck<T: Bound<Assoc: Trait>>(x: <T::Assoc as Super>::Assoc) -> u32 {
+    x
+}
+```
+Using such an alias can result in additional region constraints, cc [#133044].
+```rust
+trait Bound<'a> {
+    type Assoc;
+}
+trait Trait {
+    type Assoc: Bound<'static, Assoc = u32>;
+}
+
+fn heck<'a, T: Trait<Assoc: Bound<'a>>>(x: <T::Assoc as Bound<'a>>::Assoc) {
+    // Normalizing the associated type requires `T::Assoc: Bound<'static>` as it
+    // uses the `Bound<'static>` alias-bound instead of keeping the alias rigid.
+    drop(x);
+}
+```
+
+### We prefer `ParamEnv` candidates over `AliasBound`
+
+While we use `AliasBound` candidates if the where-bound does not specify the associated type, in case it does, we prefer the where-bound.
+This is necessary for the following example:
+```rust
+// Make sure we prefer the `I::IntoIterator: Iterator<Item = ()>`
+// where-bound over the `I::Intoiterator: Iterator<Item = I::Item>`
+// alias-bound.
+
+trait Iterator {
+    type Item;
+}
+
+trait IntoIterator {
+    type Item;
+    type IntoIter: Iterator<Item = Self::Item>;
+}
+
+fn normalize<I: Iterator<Item = ()>>() {}
+
+fn foo<I>()
+where
+    I: IntoIterator,
+    I::IntoIter: Iterator<Item = ()>,
+{
+    // We need to prefer the `I::IntoIterator: Iterator<Item = ()>`
+    // where-bound over the `I::Intoiterator: Iterator<Item = I::Item>`
+    // alias-bound.
+    normalize::<I::IntoIter>();
+}
+```
+
+### We always consider where-bounds
+
+Even if the trait goal was proven via an impl, we still prefer `ParamEnv` candidates, if any exist.
+
+#### We prefer "orphaned" where-bounds
+
+We add "orphaned" `Projection` clauses into the `ParamEnv` when normalizing item bounds of GATs and RPITIT in `fn check_type_bounds`.
+We need to prefer these `ParamEnv` candidates over impls and other where-bounds. 
+```rust
+#![feature(associated_type_defaults)]
+trait Foo {
+    // We should be able to prove that `i32: Baz<Self>` because of
+    // the impl below, which requires that `Self::Bar<()>: Eq<i32>`
+    // which is true, because we assume `for<T> Self::Bar<T> = i32`.
+    type Bar<T>: Baz<Self> = i32;
+}
+trait Baz<T: ?Sized> {}
+impl<T: Foo + ?Sized> Baz<T> for i32 where T::Bar<()>: Eq<i32> {}
+trait Eq<T> {}
+impl<T> Eq<T> for T {}
+```
+
+I don't fully understand the cases where this preference is actually necessary and haven't been able to exploit this in fun ways yet, but 🤷
+
+#### We prefer global where-bounds over impls
+
+This is necessary for the following to compile. I don't know whether anything relies on it in practice 🤷
+```rust
+trait Id {
+    type This;
+}
+impl<T> Id for T {
+    type This = T;
+}
+
+fn foo<T>(x: T) -> <u32 as Id>::This
+where
+    u32: Id<This = T>,
+{
+    x
+}
+```
+This means normalization can result in additional region constraints, cc [#133044].
+```rust
+trait Trait {
+    type Assoc;
+}
+
+impl Trait for &u32 {
+    type Assoc = u32;
+}
+
+fn trait_bound<T: Trait>() {}
+fn normalize<T: Trait<Assoc = u32>>() {}
+
+fn foo<'a>()
+where
+    &'static u32: Trait<Assoc = u32>,
+{
+    trait_bound::<&'a u32>(); // ok, proven via impl
+    normalize::<&'a u32>(); // error, proven via where-bound
+}
+```
+
+[`Candidate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/struct.Candidate.html
+[`CandidateSource`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/enum.CandidateSource.html
+[`fn merge_trait_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs#L1342-L1424
+[`fn assemble_and_merge_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs#L920-L1003
+[trait-system-refactor-initiative#76]: https://github.com/rust-lang/trait-system-refactor-initiative/issues/76
+[#24066]: https://github.com/rust-lang/rust/issues/24066
+[#133044]: https://github.com/rust-lang/rust/issues/133044
\ No newline at end of file
diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md
index 230925252ba..d0cee54adb6 100644
--- a/src/doc/rustc-dev-guide/src/stability.md
+++ b/src/doc/rustc-dev-guide/src/stability.md
@@ -6,8 +6,6 @@ APIs to use unstable APIs internally in the rustc standard library.
 **NOTE**: this section is for *library* features, not *language* features. For instructions on
 stabilizing a language feature see [Stabilizing Features](./stabilization_guide.md).
 
-<!-- toc -->
-
 ## unstable
 
 The `#[unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]`
diff --git a/src/doc/rustc-dev-guide/src/stabilization_guide.md b/src/doc/rustc-dev-guide/src/stabilization_guide.md
index f155272e5a2..e399930fc52 100644
--- a/src/doc/rustc-dev-guide/src/stabilization_guide.md
+++ b/src/doc/rustc-dev-guide/src/stabilization_guide.md
@@ -6,8 +6,6 @@
 
 Once an unstable feature has been well-tested with no outstanding concerns, anyone may push for its stabilization, though involving the people who have worked on it is prudent. Follow these steps:
 
-<!-- toc -->
-
 ## Write an RFC, if needed
 
 If the feature was part of a [lang experiment], the lang team generally will want to first accept an RFC before stabilization.
diff --git a/src/doc/rustc-dev-guide/src/test-implementation.md b/src/doc/rustc-dev-guide/src/test-implementation.md
index e906dd29f25..f09d7363199 100644
--- a/src/doc/rustc-dev-guide/src/test-implementation.md
+++ b/src/doc/rustc-dev-guide/src/test-implementation.md
@@ -1,7 +1,5 @@
 # The `#[test]` attribute
 
-<!-- toc -->
-
 
 
 Many Rust programmers rely on a built-in attribute called `#[test]`. All
diff --git a/src/doc/rustc-dev-guide/src/tests/adding.md b/src/doc/rustc-dev-guide/src/tests/adding.md
index 895eabfbd56..e5c26bef11d 100644
--- a/src/doc/rustc-dev-guide/src/tests/adding.md
+++ b/src/doc/rustc-dev-guide/src/tests/adding.md
@@ -1,7 +1,5 @@
 # Adding new tests
 
-<!-- toc -->
-
 **In general, we expect every PR that fixes a bug in rustc to come accompanied
 by a regression test of some kind.** This test should fail in master but pass
 after the PR. These tests are really useful for preventing us from repeating the
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index a108dfdef9b..4980ed845d6 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -1,7 +1,5 @@
 # Compiletest
 
-<!-- toc -->
-
 ## Introduction
 
 `compiletest` is the main test harness of the Rust test suite. It allows test
diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
index 89e4d3e9b58..f4ba9a044e6 100644
--- a/src/doc/rustc-dev-guide/src/tests/directives.md
+++ b/src/doc/rustc-dev-guide/src/tests/directives.md
@@ -1,7 +1,5 @@
 # Compiletest directives
 
-<!-- toc -->
-
 <!--
 FIXME(jieyouxu) completely revise this chapter.
 -->
@@ -52,6 +50,8 @@ not be exhaustive. Directives can generally be found by browsing the
 
 ### Auxiliary builds
 
+See [Building auxiliary crates](compiletest.html#building-auxiliary-crates)
+
 | Directive             | Explanation                                                                                           | Supported test suites | Possible values                               |
 |-----------------------|-------------------------------------------------------------------------------------------------------|-----------------------|-----------------------------------------------|
 | `aux-bin`             | Build a aux binary, made available in `auxiliary/bin` relative to test directory                      | All except `run-make` | Path to auxiliary `.rs` file                  |
@@ -61,8 +61,7 @@ not be exhaustive. Directives can generally be found by browsing the
 | `proc-macro`          | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm].                | All except `run-make` | Path to auxiliary proc-macro `.rs` file       |
 | `build-aux-docs`      | Build docs for auxiliaries as well.  Note that this only works with `aux-build`, not `aux-crate`.     | All except `run-make` | N/A                                           |
 
-[^pm]: please see the Auxiliary proc-macro section in the
-    [compiletest](./compiletest.md) chapter for specifics.
+[^pm]: please see the [Auxiliary proc-macro section](compiletest.html#auxiliary-proc-macro) in the compiletest chapter for specifics.
 
 ### Controlling outcome expectations
 
@@ -298,6 +297,7 @@ See [Pretty-printer](compiletest.md#pretty-printer-tests).
 - [`should-ice`](compiletest.md#incremental-tests) — incremental cfail should
       ICE
 - [`reference`] — an annotation linking to a rule in the reference
+- `disable-gdb-pretty-printers` — disable gdb pretty printers for debuginfo tests
 
 [`reference`]: https://github.com/rust-lang/reference/blob/master/docs/authoring.md#test-rule-annotations
 
@@ -358,7 +358,7 @@ described below:
   - Example: `x86_64-unknown-linux-gnu`
 
 See
-[`tests/ui/commandline-argfile.rs`](https://github.com/rust-lang/rust/blob/master/tests/ui/argfile/commandline-argfile.rs)
+[`tests/ui/argfile/commandline-argfile.rs`](https://github.com/rust-lang/rust/blob/master/tests/ui/argfile/commandline-argfile.rs)
 for an example of a test that uses this substitution.
 
 [output normalization]: ui.md#normalization
diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md
index 032da1ca1e8..ae093984223 100644
--- a/src/doc/rustc-dev-guide/src/tests/docker.md
+++ b/src/doc/rustc-dev-guide/src/tests/docker.md
@@ -6,12 +6,12 @@ need to install Docker on a Linux, Windows, or macOS system (typically Linux
 will be much faster than Windows or macOS because the latter use virtual
 machines to emulate a Linux environment).
 
-Jobs running in CI are configured through a set of bash scripts, and it is not always trivial to reproduce their behavior locally. If you want to run a CI job locally in the simplest way possible, you can use a provided helper Python script that tries to replicate what happens on CI as closely as possible:
+Jobs running in CI are configured through a set of bash scripts, and it is not always trivial to reproduce their behavior locally. If you want to run a CI job locally in the simplest way possible, you can use a provided helper `citool` that tries to replicate what happens on CI as closely as possible:
 
 ```bash
-python3 src/ci/github-actions/ci.py run-local <job-name>
+cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
 # For example:
-python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux-alt
+cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux-alt
 ```
 
 If the above script does not work for you, you would like to have more control of the Docker image execution, or you want to understand what exactly happens during Docker job execution, then continue reading below.
@@ -53,15 +53,6 @@ Some additional notes about using the interactive mode:
   containers. With the container name, run `docker exec -it <CONTAINER>
   /bin/bash` where `<CONTAINER>` is the container name like `4ba195e95cef`.
 
-The approach described above is a relatively low-level interface for running the Docker images
-directly. If you want to run a full CI Linux job locally with Docker, in a way that is as close to CI as possible, you can use the following command:
-
-```bash
-cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
-# For example:
-cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux-alt
-```
-
 [Docker]: https://www.docker.com/
 [`src/ci/docker`]: https://github.com/rust-lang/rust/tree/master/src/ci/docker
 [`src/ci/docker/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/run.sh
diff --git a/src/doc/rustc-dev-guide/src/tests/intro.md b/src/doc/rustc-dev-guide/src/tests/intro.md
index 79b96c450a8..b90c16d602c 100644
--- a/src/doc/rustc-dev-guide/src/tests/intro.md
+++ b/src/doc/rustc-dev-guide/src/tests/intro.md
@@ -1,7 +1,5 @@
 # Testing the compiler
 
-<!-- toc -->
-
 The Rust project runs a wide variety of different tests, orchestrated by the
 build system (`./x test`). This section gives a brief overview of the different
 testing tools. Subsequent chapters dive into [running tests](running.md) and
diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md
index 6526fe9c235..f6e313062cd 100644
--- a/src/doc/rustc-dev-guide/src/tests/running.md
+++ b/src/doc/rustc-dev-guide/src/tests/running.md
@@ -1,7 +1,5 @@
 # Running tests
 
-<!-- toc -->
-
 You can run the entire test collection using `x`. But note that running the
 *entire* test collection is almost never what you want to do during local
 development because it takes a really long time. For local development, see the
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 782f78d7614..25dd5814cf6 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -1,7 +1,5 @@
 # UI tests
 
-<!-- toc -->
-
 UI tests are a particular [test suite](compiletest.md#test-suites) of
 compiletest.
 
@@ -25,9 +23,9 @@ If you need to work with `#![no_std]` cross-compiling tests, consult the
 
 ## General structure of a test
 
-A test consists of a Rust source file located anywhere in the `tests/ui`
-directory, but they should be placed in a suitable sub-directory. For example,
-[`tests/ui/hello.rs`] is a basic hello-world test.
+A test consists of a Rust source file located in the `tests/ui` directory.
+**Tests must be placed in the appropriate subdirectory** based on their purpose
+and testing category - placing tests directly in `tests/ui` is not permitted.
 
 Compiletest will use `rustc` to compile the test, and compare the output against
 the expected output which is stored in a `.stdout` or `.stderr` file located
@@ -46,8 +44,6 @@ pass/fail expectations](#controlling-passfail-expectations).
 By default, a test is built as an executable binary. If you need a different
 crate type, you can use the `#![crate_type]` attribute to set it as needed.
 
-[`tests/ui/hello.rs`]: https://github.com/rust-lang/rust/blob/master/tests/ui/hello.rs
-
 ## Output comparison
 
 UI tests store the expected output from the compiler in `.stderr` and `.stdout`
diff --git a/src/doc/rustc-dev-guide/src/thir.md b/src/doc/rustc-dev-guide/src/thir.md
index 73d09ad80bf..3d3dafaef49 100644
--- a/src/doc/rustc-dev-guide/src/thir.md
+++ b/src/doc/rustc-dev-guide/src/thir.md
@@ -1,7 +1,5 @@
 # The THIR
 
-<!-- toc -->
-
 The THIR ("Typed High-Level Intermediate Representation"), previously called HAIR for
 "High-Level Abstract IR", is another IR used by rustc that is generated after
 [type checking]. It is (as of <!-- date-check --> January 2024) used for
diff --git a/src/doc/rustc-dev-guide/src/tracing.md b/src/doc/rustc-dev-guide/src/tracing.md
index 0cfdf306e92..5e5b81fc65b 100644
--- a/src/doc/rustc-dev-guide/src/tracing.md
+++ b/src/doc/rustc-dev-guide/src/tracing.md
@@ -1,7 +1,5 @@
 # Using tracing to debug the compiler
 
-<!-- toc -->
-
 The compiler has a lot of [`debug!`] (or `trace!`) calls, which print out logging information
 at many points. These are very useful to at least narrow down the location of
 a bug if not to find it entirely, or just to orient yourself as to why the
diff --git a/src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md b/src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md
index 40fd4581bf3..2884ca5a05a 100644
--- a/src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md
+++ b/src/doc/rustc-dev-guide/src/traits/goals-and-clauses.md
@@ -1,7 +1,5 @@
 # Goals and clauses
 
-<!-- toc -->
-
 In logic programming terms, a **goal** is something that you must
 prove and a **clause** is something that you know is true. As
 described in the [lowering to logic](./lowering-to-logic.html)
diff --git a/src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md b/src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md
index 1248d434610..cc8b3bf800c 100644
--- a/src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md
+++ b/src/doc/rustc-dev-guide/src/traits/lowering-to-logic.md
@@ -1,7 +1,5 @@
 # Lowering to logic
 
-<!-- toc -->
-
 The key observation here is that the Rust trait system is basically a
 kind of logic, and it can be mapped onto standard logical inference
 rules. We can then look for solutions to those inference rules in a
diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md
index c62b0593694..ccb2b04268e 100644
--- a/src/doc/rustc-dev-guide/src/traits/resolution.md
+++ b/src/doc/rustc-dev-guide/src/traits/resolution.md
@@ -1,7 +1,5 @@
 # Trait resolution (old-style)
 
-<!-- toc -->
-
 This chapter describes the general process of _trait resolution_ and points out
 some non-obvious things.
 
diff --git a/src/doc/rustc-dev-guide/src/ty.md b/src/doc/rustc-dev-guide/src/ty.md
index 767ac3fdba2..4055f475e99 100644
--- a/src/doc/rustc-dev-guide/src/ty.md
+++ b/src/doc/rustc-dev-guide/src/ty.md
@@ -1,7 +1,5 @@
 # The `ty` module: representing types
 
-<!-- toc -->
-
 The `ty` module defines how the Rust compiler represents types internally. It also defines the
 *typing context* (`tcx` or `TyCtxt`), which is the central data structure in the compiler.
 
diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md
index 888eb2439c5..2243205f129 100644
--- a/src/doc/rustc-dev-guide/src/type-inference.md
+++ b/src/doc/rustc-dev-guide/src/type-inference.md
@@ -1,7 +1,5 @@
 # Type inference
 
-<!-- toc -->
-
 Type inference is the process of automatic detection of the type of an
 expression.
 
diff --git a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md
index e21bc5155da..db15467a47a 100644
--- a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md
+++ b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md
@@ -1,7 +1,5 @@
 # Typing/Parameter Environments
 
-<!-- toc -->
-
 ## Typing Environments
 
 When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The set of in-scope where clauses, and what phase of the compiler type system operations are being performed in (the [`ParamEnv`][penv] and [`TypingMode`][tmode] structs respectively).
diff --git a/src/doc/rustc-dev-guide/src/variance.md b/src/doc/rustc-dev-guide/src/variance.md
index ad4fa4adfdd..7aa01407155 100644
--- a/src/doc/rustc-dev-guide/src/variance.md
+++ b/src/doc/rustc-dev-guide/src/variance.md
@@ -1,7 +1,5 @@
 # Variance of type and lifetime parameters
 
-<!-- toc -->
-
 For a more general background on variance, see the [background] appendix.
 
 [background]: ./appendix/background.html
diff --git a/src/doc/rustc-dev-guide/src/walkthrough.md b/src/doc/rustc-dev-guide/src/walkthrough.md
index 48b3f8bb15d..b4c3379347e 100644
--- a/src/doc/rustc-dev-guide/src/walkthrough.md
+++ b/src/doc/rustc-dev-guide/src/walkthrough.md
@@ -1,7 +1,5 @@
 # Walkthrough: a typical contribution
 
-<!-- toc -->
-
 There are _a lot_ of ways to contribute to the Rust compiler, including fixing
 bugs, improving performance, helping design features, providing feedback on
 existing features, etc. This chapter does not claim to scratch the surface.
diff --git a/src/doc/rustc-dev-guide/triagebot.toml b/src/doc/rustc-dev-guide/triagebot.toml
index b3f4c2d281c..3ac5d57a52b 100644
--- a/src/doc/rustc-dev-guide/triagebot.toml
+++ b/src/doc/rustc-dev-guide/triagebot.toml
@@ -62,9 +62,6 @@ allow-unauthenticated = [
 # Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html
 [issue-links]
 
-# Automatically close and reopen PRs made by bots to run CI on them
-[bot-pull-requests]
-
 [behind-upstream]
 days-threshold = 7
 
diff --git a/src/doc/rustc/src/platform-support/lynxos178.md b/src/doc/rustc/src/platform-support/lynxos178.md
index 6463f95a0b8..121e11fb653 100644
--- a/src/doc/rustc/src/platform-support/lynxos178.md
+++ b/src/doc/rustc/src/platform-support/lynxos178.md
@@ -15,7 +15,7 @@ Target triples available:
 
 ## Target maintainers
 
-- Renat Fatykhov, https://github.com/rfatykhov-lynx
+[@rfatykhov-lynx](https://github.com/rfatykhov-lynx)
 
 ## Requirements
 
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index b6ce8551060..e204e1788ba 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -486,6 +486,7 @@ impl fmt::Display for Display<'_> {
                     (sym::debug_assertions, None) => "debug-assertions enabled",
                     (sym::target_os, Some(os)) => match os.as_str() {
                         "android" => "Android",
+                        "cygwin" => "Cygwin",
                         "dragonfly" => "DragonFly BSD",
                         "emscripten" => "Emscripten",
                         "freebsd" => "FreeBSD",
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 89d5acb985b..782311e593b 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -763,13 +763,13 @@ impl Item {
             .iter()
             .filter_map(|attr| match attr {
                 hir::Attribute::Parsed(AttributeKind::LinkSection { name, .. }) => {
-                    Some(format!("#[link_section = \"{name}\"]"))
+                    Some(format!("#[unsafe(link_section = \"{name}\")]"))
                 }
                 hir::Attribute::Parsed(AttributeKind::NoMangle(..)) => {
-                    Some("#[no_mangle]".to_string())
+                    Some("#[unsafe(no_mangle)]".to_string())
                 }
                 hir::Attribute::Parsed(AttributeKind::ExportName { name, .. }) => {
-                    Some(format!("#[export_name = \"{name}\"]"))
+                    Some(format!("#[unsafe(export_name = \"{name}\")]"))
                 }
                 hir::Attribute::Parsed(AttributeKind::NonExhaustive(..)) => {
                     Some("#[non_exhaustive]".to_string())
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 0f23413074f..493fdc6fb1b 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -368,6 +368,8 @@ pub(crate) enum HrefError {
     Private,
     // Not in external cache, href link should be in same page
     NotInExternalCache,
+    /// Refers to an unnamable item, such as one defined within a function or const block.
+    UnnamableItem,
 }
 
 /// This function is to get the external macro path because they are not in the cache used in
@@ -479,6 +481,26 @@ fn generate_item_def_id_path(
     Ok((url_parts, shortty, fqp))
 }
 
+/// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block.
+fn is_unnamable(tcx: TyCtxt<'_>, did: DefId) -> bool {
+    let mut cur_did = did;
+    while let Some(parent) = tcx.opt_parent(cur_did) {
+        match tcx.def_kind(parent) {
+            // items defined in these can be linked to, as long as they are visible
+            DefKind::Mod | DefKind::ForeignMod => cur_did = parent,
+            // items in impls can be linked to,
+            // as long as we can link to the item the impl is on.
+            // since associated traits are not a thing,
+            // it should not be possible to refer to an impl item if
+            // the base type is not namable.
+            DefKind::Impl { .. } => return false,
+            // everything else does not have docs generated for it
+            _ => return true,
+        }
+    }
+    return false;
+}
+
 fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
     if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
 }
@@ -552,6 +574,9 @@ pub(crate) fn href_with_root_path(
         }
         _ => original_did,
     };
+    if is_unnamable(cx.tcx(), did) {
+        return Err(HrefError::UnnamableItem);
+    }
     let cache = cx.cache();
     let relative_to = &cx.current;
 
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 1f92c521d46..2782e8e0058 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -8,6 +8,9 @@ use super::static_files::{STATIC_FILES, StaticFiles};
 use crate::externalfiles::ExternalHtml;
 use crate::html::render::{StylePath, ensure_trailing_slash};
 
+#[cfg(test)]
+mod tests;
+
 pub(crate) struct Layout {
     pub(crate) logo: String,
     pub(crate) favicon: String,
@@ -68,6 +71,13 @@ struct PageLayout<'a> {
     display_krate_version_extra: &'a str,
 }
 
+impl PageLayout<'_> {
+    /// See [`may_remove_crossorigin`].
+    fn static_root_path_may_remove_crossorigin(&self) -> bool {
+        may_remove_crossorigin(&self.static_root_path)
+    }
+}
+
 pub(crate) use crate::html::render::sidebar::filters;
 
 pub(crate) fn render<T: Display, S: Display>(
@@ -134,3 +144,22 @@ pub(crate) fn redirect(url: &str) -> String {
 </html>"##,
     )
 }
+
+/// Conservatively determines if `href` is relative to the current origin,
+/// so that `crossorigin` may be safely removed from `<link>` elements.
+pub(crate) fn may_remove_crossorigin(href: &str) -> bool {
+    // Reject scheme-relative URLs (`//example.com/`).
+    if href.starts_with("//") {
+        return false;
+    }
+    // URL is interpreted as having a scheme iff: it starts with an ascii alpha, and only
+    // contains ascii alphanumeric or `+` `-` `.` up to the `:`.
+    // https://url.spec.whatwg.org/#url-parsing
+    let has_scheme = href.split_once(':').is_some_and(|(scheme, _rest)| {
+        let mut chars = scheme.chars();
+        chars.next().is_some_and(|c| c.is_ascii_alphabetic())
+            && chars.all(|c| c.is_ascii_alphanumeric() || c == '+' || c == '-' || c == '.')
+    });
+    // Reject anything with a scheme (`http:`, etc.).
+    !has_scheme
+}
diff --git a/src/librustdoc/html/layout/tests.rs b/src/librustdoc/html/layout/tests.rs
new file mode 100644
index 00000000000..d4a19ee9abf
--- /dev/null
+++ b/src/librustdoc/html/layout/tests.rs
@@ -0,0 +1,24 @@
+#[test]
+fn test_may_remove_crossorigin() {
+    use super::may_remove_crossorigin;
+
+    assert!(may_remove_crossorigin("font.woff2"));
+    assert!(may_remove_crossorigin("/font.woff2"));
+    assert!(may_remove_crossorigin("./font.woff2"));
+    assert!(may_remove_crossorigin(":D/font.woff2"));
+    assert!(may_remove_crossorigin("../font.woff2"));
+
+    assert!(!may_remove_crossorigin("//example.com/static.files"));
+    assert!(!may_remove_crossorigin("http://example.com/static.files"));
+    assert!(!may_remove_crossorigin("https://example.com/static.files"));
+    assert!(!may_remove_crossorigin("https://example.com:8080/static.files"));
+
+    assert!(!may_remove_crossorigin("ftp://example.com/static.files"));
+    assert!(!may_remove_crossorigin("blob:http://example.com/static.files"));
+    assert!(!may_remove_crossorigin("javascript:alert('Hello, world!')"));
+    assert!(!may_remove_crossorigin("//./C:"));
+    assert!(!may_remove_crossorigin("file:////C:"));
+    assert!(!may_remove_crossorigin("file:///./C:"));
+    assert!(!may_remove_crossorigin("data:,Hello%2C%20World%21"));
+    assert!(!may_remove_crossorigin("hi...:hello"));
+}
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 7af99e7097c..398436e3fe1 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -7,7 +7,7 @@
     <meta name="description" content="{{page.description}}"> {# #}
     <title>{{page.title}}</title> {# #}
     <script>if(window.location.protocol!=="file:") {# Hack to skip preloading fonts locally - see #98769 #}
-    document.head.insertAdjacentHTML("beforeend","{{files.source_serif_4_regular}},{{files.fira_sans_italic}},{{files.fira_sans_regular}},{{files.fira_sans_medium_italic}},{{files.fira_sans_medium}},{{files.source_code_pro_regular}},{{files.source_code_pro_semibold}}".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}${f}">`).join("")) {# #}
+    document.head.insertAdjacentHTML("beforeend","{{files.source_serif_4_regular}},{{files.fira_sans_italic}},{{files.fira_sans_regular}},{{files.fira_sans_medium_italic}},{{files.fira_sans_medium}},{{files.source_code_pro_regular}},{{files.source_code_pro_semibold}}".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"{% if !static_root_path_may_remove_crossorigin() %} crossorigin{% endif %} href="{{static_root_path|safe}}${f}">`).join("")) {# #}
     </script> {# #}
     <link rel="stylesheet" {#+ #}
           href="{{static_root_path|safe}}{{files.normalize_css}}"> {# #}
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 031d018c8b3..f966d926562 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -908,8 +908,12 @@ fn maybe_from_hir_attr(
         hir::Attribute::Parsed(kind) => kind,
 
         hir::Attribute::Unparsed(_) => {
-            // FIXME: We should handle `#[doc(hidden)]`.
-            return Some(other_attr(tcx, attr));
+            return Some(if attr.has_name(sym::macro_export) {
+                Attribute::MacroExport
+                // FIXME: We should handle `#[doc(hidden)]`.
+            } else {
+                other_attr(tcx, attr)
+            });
         }
     };
 
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 5a9aa2a94c8..c9fa3a4837f 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -941,13 +941,21 @@ fn preprocess_link(
     ori_link: &MarkdownLink,
     dox: &str,
 ) -> Option<Result<PreprocessingInfo, PreprocessingError>> {
+    // certain link kinds cannot have their path be urls,
+    // so they should not be ignored, no matter how much they look like urls.
+    // e.g. [https://example.com/] is not a link to example.com.
+    let can_be_url = !matches!(
+        ori_link.kind,
+        LinkType::ShortcutUnknown | LinkType::CollapsedUnknown | LinkType::ReferenceUnknown
+    );
+
     // [] is mostly likely not supposed to be a link
     if ori_link.link.is_empty() {
         return None;
     }
 
     // Bail early for real links.
-    if ori_link.link.contains('/') {
+    if can_be_url && ori_link.link.contains('/') {
         return None;
     }
 
@@ -972,7 +980,7 @@ fn preprocess_link(
         Ok(None) => (None, link, link),
         Err((err_msg, relative_range)) => {
             // Only report error if we would not have ignored this link. See issue #83859.
-            if !should_ignore_link_with_disambiguators(link) {
+            if !(can_be_url && should_ignore_link_with_disambiguators(link)) {
                 let disambiguator_range = match range_between_backticks(&ori_link.range, dox) {
                     MarkdownLinkRange::Destination(no_backticks_range) => {
                         MarkdownLinkRange::Destination(
@@ -989,7 +997,25 @@ fn preprocess_link(
         }
     };
 
-    if should_ignore_link(path_str) {
+    // If there's no backticks, be lenient and revert to the old behavior.
+    // This is to prevent churn by linting on stuff that isn't meant to be a link.
+    // only shortcut links have simple enough syntax that they
+    // are likely to be written accidentally, collapsed and reference links
+    // need 4 metachars, and reference links will not usually use
+    // backticks in the reference name.
+    // therefore, only shortcut syntax gets the lenient behavior.
+    //
+    // here's a truth table for how link kinds that cannot be urls are handled:
+    //
+    // |-------------------------------------------------------|
+    // |              |  is shortcut link  | not shortcut link |
+    // |--------------|--------------------|-------------------|
+    // | has backtick |    never ignore    |    never ignore   |
+    // | no backtick  | ignore if url-like |    never ignore   |
+    // |-------------------------------------------------------|
+    let ignore_urllike =
+        can_be_url || (ori_link.kind == LinkType::ShortcutUnknown && !ori_link.link.contains('`'));
+    if ignore_urllike && should_ignore_link(path_str) {
         return None;
     }
 
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 6235b0e8576..40f89009a43 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -37,8 +37,8 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
 // will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line
 // are deliberately not in a doc comment, because they need not be in public docs.)
 //
-// Latest feature: Structured Attributes
-pub const FORMAT_VERSION: u32 = 54;
+// Latest feature: Add Attribute::MacroUse
+pub const FORMAT_VERSION: u32 = 55;
 
 /// The root of the emitted JSON blob.
 ///
@@ -216,6 +216,9 @@ pub enum Attribute {
     /// `#[must_use]`
     MustUse { reason: Option<String> },
 
+    /// `#[macro_export]`
+    MacroExport,
+
     /// `#[export_name = "name"]`
     ExportName(String),
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 9b296973b425ffb159e12cf3cd56580fd5c8538
+Subproject 840b83a10fb0e039a83f4d70ad032892c287570
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
index 17d251a7bbb..120a4b98a65 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -417,7 +417,7 @@ fn replace_types<'tcx>(
                 {
                     let projection = projection_predicate
                         .projection_term
-                        .with_self_ty(cx.tcx, new_ty)
+                        .with_replaced_self_ty(cx.tcx, new_ty)
                         .expect_ty(cx.tcx)
                         .to_ty(cx.tcx);
 
diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
index 8068edfff94..c2b58b952aa 100644
--- a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
+++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
@@ -18,7 +18,7 @@ error: this `match` arm has a differing case than its expression
 LL |         "~!@#$%^&*()-_=+Foo" => {},
    |         ^^^^^^^^^^^^^^^^^^^^
    |
-help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization difference)
+help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization)
    |
 LL -         "~!@#$%^&*()-_=+Foo" => {},
 LL +         "~!@#$%^&*()-_=+foo" => {},
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index aceae3e3a3b..2d49b1a7097 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -279,6 +279,15 @@ pub struct Config {
     /// [`Self::rustc_path`].
     pub stage0_rustc_path: Option<Utf8PathBuf>,
 
+    /// Path to the stage 1 or higher `rustc` used to obtain target information via
+    /// `--print=all-target-specs-json` and similar queries.
+    ///
+    /// Normally this is unset, because [`Self::rustc_path`] can be used instead.
+    /// But when running "stage 1" ui-fulldeps tests, `rustc_path` is a stage 0
+    /// compiler, whereas target specs must be obtained from a stage 1+ compiler
+    /// (in case the JSON format has changed since the last bootstrap bump).
+    pub query_rustc_path: Option<Utf8PathBuf>,
+
     /// Path to the `rustdoc`-under-test. Like [`Self::rustc_path`], this `rustdoc` is *staged*.
     pub rustdoc_path: Option<Utf8PathBuf>,
 
@@ -712,6 +721,7 @@ impl Config {
             rustc_path: Utf8PathBuf::default(),
             cargo_path: Default::default(),
             stage0_rustc_path: Default::default(),
+            query_rustc_path: Default::default(),
             rustdoc_path: Default::default(),
             coverage_dump_path: Default::default(),
             python: Default::default(),
@@ -917,7 +927,7 @@ pub struct TargetCfgs {
 
 impl TargetCfgs {
     fn new(config: &Config) -> TargetCfgs {
-        let mut targets: HashMap<String, TargetCfg> = serde_json::from_str(&rustc_output(
+        let mut targets: HashMap<String, TargetCfg> = serde_json::from_str(&query_rustc_output(
             config,
             &["--print=all-target-specs-json", "-Zunstable-options"],
             Default::default(),
@@ -950,7 +960,7 @@ impl TargetCfgs {
             if config.target.ends_with(".json") || !envs.is_empty() {
                 targets.insert(
                     config.target.clone(),
-                    serde_json::from_str(&rustc_output(
+                    serde_json::from_str(&query_rustc_output(
                         config,
                         &[
                             "--print=target-spec-json",
@@ -1009,10 +1019,13 @@ impl TargetCfgs {
         // which are respected for `--print=cfg` but not for `--print=all-target-specs-json`. The
         // code below extracts them from `--print=cfg`: make sure to only override fields that can
         // actually be changed with `-C` flags.
-        for config in
-            rustc_output(config, &["--print=cfg", "--target", &config.target], Default::default())
-                .trim()
-                .lines()
+        for config in query_rustc_output(
+            config,
+            &["--print=cfg", "--target", &config.target],
+            Default::default(),
+        )
+        .trim()
+        .lines()
         {
             let (name, value) = config
                 .split_once("=\"")
@@ -1113,7 +1126,7 @@ pub enum Endian {
 }
 
 fn builtin_cfg_names(config: &Config) -> HashSet<String> {
-    rustc_output(
+    query_rustc_output(
         config,
         &["--print=check-cfg", "-Zunstable-options", "--check-cfg=cfg()"],
         Default::default(),
@@ -1128,7 +1141,7 @@ pub const KNOWN_CRATE_TYPES: &[&str] =
     &["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
 
 fn supported_crate_types(config: &Config) -> HashSet<String> {
-    let crate_types: HashSet<_> = rustc_output(
+    let crate_types: HashSet<_> = query_rustc_output(
         config,
         &["--target", &config.target, "--print=supported-crate-types", "-Zunstable-options"],
         Default::default(),
@@ -1149,8 +1162,10 @@ fn supported_crate_types(config: &Config) -> HashSet<String> {
     crate_types
 }
 
-fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
-    let mut command = Command::new(&config.rustc_path);
+fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
+    let query_rustc_path = config.query_rustc_path.as_deref().unwrap_or(&config.rustc_path);
+
+    let mut command = Command::new(query_rustc_path);
     add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
     command.args(&config.target_rustcflags).args(args);
     command.env("RUSTC_BOOTSTRAP", "1");
diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs
index 54511f4fd08..13e694b7f03 100644
--- a/src/tools/compiletest/src/directives.rs
+++ b/src/tools/compiletest/src/directives.rs
@@ -203,6 +203,8 @@ pub struct TestProps {
     pub add_core_stubs: bool,
     /// Whether line annotatins are required for the given error kind.
     pub dont_require_annotations: HashSet<ErrorKind>,
+    /// Whether pretty printers should be disabled in gdb.
+    pub disable_gdb_pretty_printers: bool,
 }
 
 mod directives {
@@ -251,6 +253,7 @@ mod directives {
     pub const ADD_CORE_STUBS: &'static str = "add-core-stubs";
     // This isn't a real directive, just one that is probably mistyped often
     pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
+    pub const DISABLE_GDB_PRETTY_PRINTERS: &'static str = "disable-gdb-pretty-printers";
 }
 
 impl TestProps {
@@ -306,6 +309,7 @@ impl TestProps {
             has_enzyme: false,
             add_core_stubs: false,
             dont_require_annotations: Default::default(),
+            disable_gdb_pretty_printers: false,
         }
     }
 
@@ -654,6 +658,12 @@ impl TestProps {
                         self.dont_require_annotations
                             .insert(ErrorKind::expect_from_user_str(err_kind.trim()));
                     }
+
+                    config.set_name_directive(
+                        ln,
+                        DISABLE_GDB_PRETTY_PRINTERS,
+                        &mut self.disable_gdb_pretty_printers,
+                    );
                 },
             );
 
diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs
index 7fc76a42e0c..f7955429d83 100644
--- a/src/tools/compiletest/src/directives/directive_names.rs
+++ b/src/tools/compiletest/src/directives/directive_names.rs
@@ -18,6 +18,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "check-stdout",
     "check-test-line-numbers-match",
     "compile-flags",
+    "disable-gdb-pretty-printers",
     "doc-flags",
     "dont-check-compiler-stderr",
     "dont-check-compiler-stdout",
diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs
index 5682cc57b6f..30d8537b51a 100644
--- a/src/tools/compiletest/src/directives/tests.rs
+++ b/src/tools/compiletest/src/directives/tests.rs
@@ -203,22 +203,8 @@ impl ConfigBuilder {
         }
 
         args.push("--rustc-path".to_string());
-        // This is a subtle/fragile thing. On rust-lang CI, there is no global
-        // `rustc`, and Cargo doesn't offer a convenient way to get the path to
-        // `rustc`. Fortunately bootstrap sets `RUSTC` for us, which is pointing
-        // to the stage0 compiler.
-        //
-        // Otherwise, if you are running compiletests's tests manually, you
-        // probably don't have `RUSTC` set, in which case this falls back to the
-        // global rustc. If your global rustc is too far out of sync with stage0,
-        // then this may cause confusing errors. Or if for some reason you don't
-        // have rustc in PATH, that would also fail.
-        args.push(std::env::var("RUSTC").unwrap_or_else(|_| {
-            eprintln!(
-                "warning: RUSTC not set, using global rustc (are you not running via bootstrap?)"
-            );
-            "rustc".to_string()
-        }));
+        args.push(std::env::var("TEST_RUSTC").expect("must be configured by bootstrap"));
+
         crate::parse_config(args)
     }
 }
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index c712185733c..f5409e78341 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -63,6 +63,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "path to rustc to use for compiling run-make recipes",
             "PATH",
         )
+        .optopt(
+            "",
+            "query-rustc-path",
+            "path to rustc to use for querying target information (defaults to `--rustc-path`)",
+            "PATH",
+        )
         .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH")
         .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH")
         .reqopt("", "python", "path to python to use for doc tests", "PATH")
@@ -354,6 +360,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         rustc_path: opt_path(matches, "rustc-path"),
         cargo_path: matches.opt_str("cargo-path").map(Utf8PathBuf::from),
         stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(Utf8PathBuf::from),
+        query_rustc_path: matches.opt_str("query-rustc-path").map(Utf8PathBuf::from),
         rustdoc_path: matches.opt_str("rustdoc-path").map(Utf8PathBuf::from),
         coverage_dump_path: matches.opt_str("coverage-dump-path").map(Utf8PathBuf::from),
         python: matches.opt_str("python").unwrap(),
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index f66d4f98f1f..35670ba89e9 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -354,13 +354,10 @@ impl<'test> TestCx<'test> {
             }
         } else {
             if proc_res.status.success() {
-                {
-                    self.error(&format!("{} test did not emit an error", self.config.mode));
-                    if self.config.mode == crate::common::TestMode::Ui {
-                        println!("note: by default, ui tests are expected not to compile");
-                    }
-                    proc_res.fatal(None, || ());
-                };
+                let err = &format!("{} test did not emit an error", self.config.mode);
+                let extra_note = (self.config.mode == crate::common::TestMode::Ui)
+                    .then_some("note: by default, ui tests are expected not to compile");
+                self.fatal_proc_rec_general(err, extra_note, proc_res, || ());
             }
 
             if !self.props.dont_check_failure_status {
@@ -606,7 +603,10 @@ impl<'test> TestCx<'test> {
             );
         } else {
             for pattern in missing_patterns {
-                self.error(&format!("error pattern '{}' not found!", pattern));
+                println!(
+                    "\n{prefix}: error pattern '{pattern}' not found!",
+                    prefix = self.error_prefix()
+                );
             }
             self.fatal_proc_rec("multiple error patterns not found", proc_res);
         }
@@ -765,12 +765,6 @@ impl<'test> TestCx<'test> {
         }
 
         if !unexpected.is_empty() || !not_found.is_empty() {
-            self.error(&format!(
-                "{} unexpected diagnostics reported, {} expected diagnostics not reported",
-                unexpected.len(),
-                not_found.len()
-            ));
-
             // Emit locations in a format that is short (relative paths) but "clickable" in editors.
             // Also normalize path separators to `/`.
             let file_name = self
@@ -794,19 +788,20 @@ impl<'test> TestCx<'test> {
                 |suggestions: &mut Vec<_>, e: &Error, kind, line, msg, color, rank| {
                     let mut ret = String::new();
                     if kind {
-                        ret += &format!("{} {}", "with kind".color(color), e.kind);
+                        ret += &format!("{} {}", "with different kind:".color(color), e.kind);
                     }
                     if line {
                         if !ret.is_empty() {
                             ret.push(' ');
                         }
-                        ret += &format!("{} {}", "on line".color(color), line_str(e));
+                        ret += &format!("{} {}", "on different line:".color(color), line_str(e));
                     }
                     if msg {
                         if !ret.is_empty() {
                             ret.push(' ');
                         }
-                        ret += &format!("{} {}", "with message".color(color), e.msg.cyan());
+                        ret +=
+                            &format!("{} {}", "with different message:".color(color), e.msg.cyan());
                     }
                     suggestions.push((ret, rank));
                 };
@@ -829,17 +824,21 @@ impl<'test> TestCx<'test> {
             // - only known line - meh, but suggested
             // - others are not worth suggesting
             if !unexpected.is_empty() {
-                let header = "--- reported in JSON output but not expected in test file ---";
-                println!("{}", header.green());
+                println!(
+                    "\n{prefix}: {n} diagnostics reported in JSON output but not expected in test file",
+                    prefix = self.error_prefix(),
+                    n = unexpected.len(),
+                );
                 for error in &unexpected {
                     print_error(error);
                     let mut suggestions = Vec::new();
                     for candidate in &not_found {
+                        let kind_mismatch = candidate.kind != error.kind;
                         let mut push_red_suggestion = |line, msg, rank| {
                             push_suggestion(
                                 &mut suggestions,
                                 candidate,
-                                candidate.kind != error.kind,
+                                kind_mismatch,
                                 line,
                                 msg,
                                 Color::Red,
@@ -851,26 +850,29 @@ impl<'test> TestCx<'test> {
                         } else if candidate.line_num.is_some()
                             && candidate.line_num == error.line_num
                         {
-                            push_red_suggestion(false, true, 1);
+                            push_red_suggestion(false, true, if kind_mismatch { 2 } else { 1 });
                         }
                     }
 
                     show_suggestions(suggestions, "expected", Color::Red);
                 }
-                println!("{}", "---".green());
             }
             if !not_found.is_empty() {
-                let header = "--- expected in test file but not reported in JSON output ---";
-                println!("{}", header.red());
+                println!(
+                    "\n{prefix}: {n} diagnostics expected in test file but not reported in JSON output",
+                    prefix = self.error_prefix(),
+                    n = not_found.len(),
+                );
                 for error in &not_found {
                     print_error(error);
                     let mut suggestions = Vec::new();
                     for candidate in unexpected.iter().chain(&unimportant) {
+                        let kind_mismatch = candidate.kind != error.kind;
                         let mut push_green_suggestion = |line, msg, rank| {
                             push_suggestion(
                                 &mut suggestions,
                                 candidate,
-                                candidate.kind != error.kind,
+                                kind_mismatch,
                                 line,
                                 msg,
                                 Color::Green,
@@ -882,13 +884,12 @@ impl<'test> TestCx<'test> {
                         } else if candidate.line_num.is_some()
                             && candidate.line_num == error.line_num
                         {
-                            push_green_suggestion(false, true, 1);
+                            push_green_suggestion(false, true, if kind_mismatch { 2 } else { 1 });
                         }
                     }
 
                     show_suggestions(suggestions, "reported", Color::Green);
                 }
-                println!("{}", "---".red());
             }
             panic!(
                 "errors differ from expected\nstatus: {}\ncommand: {}\n",
@@ -1996,33 +1997,52 @@ impl<'test> TestCx<'test> {
         output_base_name(self.config, self.testpaths, self.safe_revision())
     }
 
-    fn error(&self, err: &str) {
+    /// Prefix to print before error messages. Normally just `error`, but also
+    /// includes the revision name for tests that use revisions.
+    #[must_use]
+    fn error_prefix(&self) -> String {
         match self.revision {
-            Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
-            None => println!("\nerror: {}", err),
+            Some(rev) => format!("error in revision `{rev}`"),
+            None => format!("error"),
         }
     }
 
     #[track_caller]
     fn fatal(&self, err: &str) -> ! {
-        self.error(err);
+        println!("\n{prefix}: {err}", prefix = self.error_prefix());
         error!("fatal error, panic: {:?}", err);
         panic!("fatal error");
     }
 
     fn fatal_proc_rec(&self, err: &str, proc_res: &ProcRes) -> ! {
-        self.error(err);
-        proc_res.fatal(None, || ());
+        self.fatal_proc_rec_general(err, None, proc_res, || ());
     }
 
-    fn fatal_proc_rec_with_ctx(
+    /// Underlying implementation of [`Self::fatal_proc_rec`], providing some
+    /// extra capabilities not needed by most callers.
+    fn fatal_proc_rec_general(
         &self,
         err: &str,
+        extra_note: Option<&str>,
         proc_res: &ProcRes,
-        on_failure: impl FnOnce(Self),
+        callback_before_unwind: impl FnOnce(),
     ) -> ! {
-        self.error(err);
-        proc_res.fatal(None, || on_failure(*self));
+        println!("\n{prefix}: {err}", prefix = self.error_prefix());
+
+        // Some callers want to print additional notes after the main error message.
+        if let Some(note) = extra_note {
+            println!("{note}");
+        }
+
+        // Print the details and output of the subprocess that caused this test to fail.
+        println!("{}", proc_res.format_info());
+
+        // Some callers want print more context or show a custom diff before the unwind occurs.
+        callback_before_unwind();
+
+        // Use resume_unwind instead of panic!() to prevent a panic message + backtrace from
+        // compiletest, which is unnecessary noise.
+        std::panic::resume_unwind(Box::new(()));
     }
 
     // codegen tests (using FileCheck)
@@ -2081,7 +2101,7 @@ impl<'test> TestCx<'test> {
         if cfg!(target_os = "freebsd") { "ISO-8859-1" } else { "UTF-8" }
     }
 
-    fn compare_to_default_rustdoc(&mut self, out_dir: &Utf8Path) {
+    fn compare_to_default_rustdoc(&self, out_dir: &Utf8Path) {
         if !self.config.has_html_tidy {
             return;
         }
@@ -2958,7 +2978,8 @@ pub struct ProcRes {
 }
 
 impl ProcRes {
-    pub fn print_info(&self) {
+    #[must_use]
+    pub fn format_info(&self) -> String {
         fn render(name: &str, contents: &str) -> String {
             let contents = json::extract_rendered(contents);
             let contents = contents.trim_end();
@@ -2974,24 +2995,13 @@ impl ProcRes {
             }
         }
 
-        println!(
+        format!(
             "status: {}\ncommand: {}\n{}\n{}\n",
             self.status,
             self.cmdline,
             render("stdout", &self.stdout),
             render("stderr", &self.stderr),
-        );
-    }
-
-    pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
-        if let Some(e) = err {
-            println!("\nerror: {}", e);
-        }
-        self.print_info();
-        on_failure();
-        // Use resume_unwind instead of panic!() to prevent a panic message + backtrace from
-        // compiletest, which is unnecessary noise.
-        std::panic::resume_unwind(Box::new(()));
+        )
     }
 }
 
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
index 471e4a4c819..6114afdc9df 100644
--- a/src/tools/compiletest/src/runtest/debuginfo.rs
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -259,7 +259,9 @@ impl TestCx<'_> {
                 Some(version) => {
                     println!("NOTE: compiletest thinks it is using GDB version {}", version);
 
-                    if version > extract_gdb_version("7.4").unwrap() {
+                    if !self.props.disable_gdb_pretty_printers
+                        && version > extract_gdb_version("7.4").unwrap()
+                    {
                         // Add the directory containing the pretty printers to
                         // GDB's script auto loading safe path
                         script_str.push_str(&format!(
diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs
index 236f021ce82..4a143aa5824 100644
--- a/src/tools/compiletest/src/runtest/rustdoc.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc.rs
@@ -28,8 +28,8 @@ impl TestCx<'_> {
             }
             let res = self.run_command_to_procres(&mut cmd);
             if !res.status.success() {
-                self.fatal_proc_rec_with_ctx("htmldocck failed!", &res, |mut this| {
-                    this.compare_to_default_rustdoc(&out_dir)
+                self.fatal_proc_rec_general("htmldocck failed!", None, &res, || {
+                    self.compare_to_default_rustdoc(&out_dir);
                 });
             }
         }
diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs
index 4f35efedfde..083398f9274 100644
--- a/src/tools/compiletest/src/runtest/rustdoc_json.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs
@@ -29,9 +29,9 @@ impl TestCx<'_> {
         );
 
         if !res.status.success() {
-            self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
+            self.fatal_proc_rec_general("jsondocck failed!", None, &res, || {
                 println!("Rustdoc Output:");
-                proc_res.print_info();
+                println!("{}", proc_res.format_info());
             })
         }
 
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
index deec81f7e51..14b3be02a79 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
@@ -16,7 +16,7 @@ LL | ABORT()
    |
    = note: BACKTRACE:
    = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
index deec81f7e51..14b3be02a79 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
@@ -16,7 +16,7 @@ LL | ABORT()
    |
    = note: BACKTRACE:
    = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/panic/abort_unwind.stderr b/src/tools/miri/tests/fail/panic/abort_unwind.stderr
index 81d560c27ec..35052f37dfc 100644
--- a/src/tools/miri/tests/fail/panic/abort_unwind.stderr
+++ b/src/tools/miri/tests/fail/panic/abort_unwind.stderr
@@ -16,7 +16,7 @@ LL | ABORT()
    |
    = note: BACKTRACE:
    = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr
index bc6cce93d41..3f1fbfef721 100644
--- a/src/tools/miri/tests/fail/panic/double_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/double_panic.stderr
@@ -19,7 +19,7 @@ LL | ABORT()
    |
    = note: BACKTRACE:
    = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr
index 61bc9a7a495..9aca2ed654f 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr
@@ -15,7 +15,7 @@ LL | ABORT()
    = note: inside `std::rt::__rust_abort` at RUSTLIB/std/src/rt.rs:LL:CC
    = note: inside `panic_abort::__rust_start_panic` at RUSTLIB/panic_abort/src/lib.rs:LL:CC
    = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr
index a7a42f8174e..425817d5f86 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr
@@ -15,7 +15,7 @@ LL | ABORT()
    = note: inside `std::rt::__rust_abort` at RUSTLIB/std/src/rt.rs:LL:CC
    = note: inside `panic_abort::__rust_start_panic` at RUSTLIB/panic_abort/src/lib.rs:LL:CC
    = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr
index ba1f11065ea..a21e185219e 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr
@@ -15,7 +15,7 @@ LL | ABORT()
    = note: inside `std::rt::__rust_abort` at RUSTLIB/std/src/rt.rs:LL:CC
    = note: inside `panic_abort::__rust_start_panic` at RUSTLIB/panic_abort/src/lib.rs:LL:CC
    = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr
index 1464c1fcc7c..a3cf5d72198 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr
@@ -15,7 +15,7 @@ LL | ABORT()
    = note: inside `std::rt::__rust_abort` at RUSTLIB/std/src/rt.rs:LL:CC
    = note: inside `panic_abort::__rust_start_panic` at RUSTLIB/panic_abort/src/lib.rs:LL:CC
    = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr
index b893220426c..8295a581060 100644
--- a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr
+++ b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr
@@ -14,7 +14,7 @@ LL | ABORT()
    |
    = note: BACKTRACE:
    = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/terminate-terminator.stderr b/src/tools/miri/tests/fail/terminate-terminator.stderr
index a0ee75e5dd2..f0f305d76bc 100644
--- a/src/tools/miri/tests/fail/terminate-terminator.stderr
+++ b/src/tools/miri/tests/fail/terminate-terminator.stderr
@@ -18,7 +18,7 @@ LL | ABORT()
    |
    = note: BACKTRACE:
    = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/unwind-action-terminate.stderr b/src/tools/miri/tests/fail/unwind-action-terminate.stderr
index 5fa485752a4..216ae84512a 100644
--- a/src/tools/miri/tests/fail/unwind-action-terminate.stderr
+++ b/src/tools/miri/tests/fail/unwind-action-terminate.stderr
@@ -16,7 +16,7 @@ LL | ABORT()
    |
    = note: BACKTRACE:
    = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
-   = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/validity/dangling_ref3.rs b/src/tools/miri/tests/fail/validity/dangling_ref3.rs
index 8e8a75bd7ec..0fecd8f1c28 100644
--- a/src/tools/miri/tests/fail/validity/dangling_ref3.rs
+++ b/src/tools/miri/tests/fail/validity/dangling_ref3.rs
@@ -1,5 +1,8 @@
 // Make sure we catch this even without Stacked Borrows
 //@compile-flags: -Zmiri-disable-stacked-borrows
+
+#![allow(dangling_pointers_from_locals)]
+
 use std::mem;
 
 fn dangling() -> *const u8 {
diff --git a/src/tools/miri/tests/pass/fn_align.rs b/src/tools/miri/tests/pass/fn_align.rs
deleted file mode 100644
index 9752d033458..00000000000
--- a/src/tools/miri/tests/pass/fn_align.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-//@compile-flags: -Zmin-function-alignment=8
-
-// FIXME(rust-lang/rust#82232, rust-lang/rust#143834): temporarily renamed to mitigate `#[align]`
-// nameres ambiguity
-#![feature(rustc_attrs)]
-#![feature(fn_align)]
-
-// When a function uses `align(N)`, the function address should be a multiple of `N`.
-
-#[rustc_align(256)]
-fn foo() {}
-
-#[rustc_align(16)]
-fn bar() {}
-
-#[rustc_align(4)]
-fn baz() {}
-
-fn main() {
-    assert!((foo as usize).is_multiple_of(256));
-    assert!((bar as usize).is_multiple_of(16));
-
-    // The maximum of `align(N)` and `-Zmin-function-alignment=N` is used.
-    assert!((baz as usize).is_multiple_of(8));
-}
diff --git a/src/tools/run-make-support/src/artifact_names.rs b/src/tools/run-make-support/src/artifact_names.rs
index a889b30e145..a2bb1186944 100644
--- a/src/tools/run-make-support/src/artifact_names.rs
+++ b/src/tools/run-make-support/src/artifact_names.rs
@@ -35,6 +35,8 @@ pub fn dynamic_lib_extension() -> &'static str {
         "dylib"
     } else if target.contains("windows") {
         "dll"
+    } else if target.contains("aix") {
+        "a"
     } else {
         "so"
     }
diff --git a/src/tools/rust-analyzer/.github/workflows/rustc-pull.yml b/src/tools/rust-analyzer/.github/workflows/rustc-pull.yml
index 2a842f3b311..37cf5f3726b 100644
--- a/src/tools/rust-analyzer/.github/workflows/rustc-pull.yml
+++ b/src/tools/rust-analyzer/.github/workflows/rustc-pull.yml
@@ -11,10 +11,11 @@ jobs:
     if: github.repository == 'rust-lang/rust-analyzer'
     uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
     with:
+      github-app-id: ${{ vars.APP_CLIENT_ID }}
       zulip-stream-id: 185405
       zulip-bot-email:  "rust-analyzer-ci-bot@rust-lang.zulipchat.com"
       pr-base-branch: master
       branch-name: rustc-pull
     secrets:
       zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }}
-      token: ${{ secrets.GITHUB_TOKEN }}
+      github-app-secret: ${{ secrets.APP_PRIVATE_KEY }}
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 7d03300c221..5a29379ba48 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -24,6 +24,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
 
 [[package]]
+name = "anstyle"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
+
+[[package]]
 name = "anyhow"
 version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -45,6 +51,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
 
 [[package]]
+name = "atomic-polyfill"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
+dependencies = [
+ "critical-section",
+]
+
+[[package]]
 name = "autocfg"
 version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -120,6 +135,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "26c4925bc979b677330a8c7fe7a8c94af2dbb4a2d37b4a20a80d884400f46baa"
 
 [[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
 name = "camino"
 version = "1.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -288,6 +309,40 @@ dependencies = [
 ]
 
 [[package]]
+name = "clap"
+version = "4.5.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
+dependencies = [
+ "clap_builder",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
+dependencies = [
+ "anstyle",
+ "clap_lex",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
+
+[[package]]
+name = "cobs"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
+dependencies = [
+ "thiserror 2.0.12",
+]
+
+[[package]]
 name = "countme"
 version = "3.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -309,6 +364,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "critical-section"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+
+[[package]]
 name = "crossbeam-channel"
 version = "0.5.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -566,6 +627,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
 
 [[package]]
+name = "hash32"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
 name = "hashbrown"
 version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -592,6 +662,20 @@ dependencies = [
 ]
 
 [[package]]
+name = "heapless"
+version = "0.7.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
+dependencies = [
+ "atomic-polyfill",
+ "hash32",
+ "rustc_version",
+ "serde",
+ "spin",
+ "stable_deref_trait",
+]
+
+[[package]]
 name = "hermit-abi"
 version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1562,6 +1646,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
 
 [[package]]
+name = "postcard"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
+dependencies = [
+ "cobs",
+ "heapless",
+ "serde",
+]
+
+[[package]]
 name = "potential_utf"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1608,6 +1703,7 @@ dependencies = [
  "ra-ap-rustc_lexer 0.123.0",
  "span",
  "syntax-bridge",
+ "temp-dir",
  "tt",
 ]
 
@@ -1615,6 +1711,8 @@ dependencies = [
 name = "proc-macro-srv-cli"
 version = "0.0.0"
 dependencies = [
+ "clap",
+ "postcard",
  "proc-macro-api",
  "proc-macro-srv",
  "tt",
@@ -1992,6 +2090,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver",
+]
+
+[[package]]
 name = "ryu"
 version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2209,6 +2316,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
 name = "stable_deref_trait"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
index ad17f1730be..b8eadb608fe 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
@@ -206,6 +206,7 @@ impl EditionedFileId {
 
 #[salsa_macros::input(debug)]
 pub struct FileText {
+    #[returns(ref)]
     pub text: Arc<str>,
     pub file_id: vfs::FileId,
 }
@@ -357,7 +358,7 @@ fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse<ast::SourceFil
     let _p = tracing::info_span!("parse", ?file_id).entered();
     let (file_id, edition) = file_id.unpack(db.as_dyn_database());
     let text = db.file_text(file_id).text(db);
-    ast::SourceFile::parse(&text, edition)
+    ast::SourceFile::parse(text, edition)
 }
 
 fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option<&[SyntaxError]> {
diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
index aed00aa9fc4..f83c21eb8d6 100644
--- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
+++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
@@ -134,10 +134,10 @@ fn next_cfg_expr<S: Copy>(it: &mut tt::iter::TtIter<'_, S>) -> Option<CfgExpr> {
     };
 
     // Eat comma separator
-    if let Some(TtElement::Leaf(tt::Leaf::Punct(punct))) = it.peek() {
-        if punct.char == ',' {
-            it.next();
-        }
+    if let Some(TtElement::Leaf(tt::Leaf::Punct(punct))) = it.peek()
+        && punct.char == ','
+    {
+        it.next();
     }
     Some(ret)
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
index b509e69b0d3..53250510f87 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
@@ -377,10 +377,10 @@ fn parse_repr_tt(tt: &crate::tt::TopSubtree) -> Option<ReprOptions> {
                 let mut align = None;
                 if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
                     tts.next();
-                    if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() {
-                        if let Ok(a) = lit.symbol.as_str().parse() {
-                            align = Align::from_bytes(a).ok();
-                        }
+                    if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next()
+                        && let Ok(a) = lit.symbol.as_str().parse()
+                    {
+                        align = Align::from_bytes(a).ok();
                     }
                 }
                 ReprOptions { align, ..Default::default() }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
index abd1382801d..3b9281ffb9c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
@@ -1487,13 +1487,13 @@ impl ExprCollector<'_> {
             ast::Expr::UnderscoreExpr(_) => self.alloc_pat_from_expr(Pat::Wild, syntax_ptr),
             ast::Expr::ParenExpr(e) => {
                 // We special-case `(..)` for consistency with patterns.
-                if let Some(ast::Expr::RangeExpr(range)) = e.expr() {
-                    if range.is_range_full() {
-                        return Some(self.alloc_pat_from_expr(
-                            Pat::Tuple { args: Box::default(), ellipsis: Some(0) },
-                            syntax_ptr,
-                        ));
-                    }
+                if let Some(ast::Expr::RangeExpr(range)) = e.expr()
+                    && range.is_range_full()
+                {
+                    return Some(self.alloc_pat_from_expr(
+                        Pat::Tuple { args: Box::default(), ellipsis: Some(0) },
+                        syntax_ptr,
+                    ));
                 }
                 return e.expr().and_then(|expr| self.maybe_collect_expr_as_pat(&expr));
             }
@@ -2569,19 +2569,18 @@ impl ExprCollector<'_> {
                     }
                 }
                 RibKind::MacroDef(macro_id) => {
-                    if let Some((parent_ctx, label_macro_id)) = hygiene_info {
-                        if label_macro_id == **macro_id {
-                            // A macro is allowed to refer to labels from before its declaration.
-                            // Therefore, if we got to the rib of its declaration, give up its hygiene
-                            // and use its parent expansion.
-
-                            hygiene_id =
-                                HygieneId::new(parent_ctx.opaque_and_semitransparent(self.db));
-                            hygiene_info = parent_ctx.outer_expn(self.db).map(|expansion| {
-                                let expansion = self.db.lookup_intern_macro_call(expansion.into());
-                                (parent_ctx.parent(self.db), expansion.def)
-                            });
-                        }
+                    if let Some((parent_ctx, label_macro_id)) = hygiene_info
+                        && label_macro_id == **macro_id
+                    {
+                        // A macro is allowed to refer to labels from before its declaration.
+                        // Therefore, if we got to the rib of its declaration, give up its hygiene
+                        // and use its parent expansion.
+
+                        hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(self.db));
+                        hygiene_info = parent_ctx.outer_expn(self.db).map(|expansion| {
+                            let expansion = self.db.lookup_intern_macro_call(expansion.into());
+                            (parent_ctx.parent(self.db), expansion.def)
+                        });
                     }
                 }
                 _ => {}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
index 3bc4afb5c8a..230d1c93463 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
@@ -259,10 +259,10 @@ impl ExprCollector<'_> {
                                     }
                                 };
 
-                                if let Some(operand_idx) = operand_idx {
-                                    if let Some(position_span) = to_span(arg.position_span) {
-                                        mappings.push((position_span, operand_idx));
-                                    }
+                                if let Some(operand_idx) = operand_idx
+                                    && let Some(position_span) = to_span(arg.position_span)
+                                {
+                                    mappings.push((position_span, operand_idx));
                                 }
                             }
                         }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path.rs
index be006c98a58..579465e10f9 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path.rs
@@ -211,16 +211,17 @@ pub(super) fn lower_path(
     // Basically, even in rustc it is quite hacky:
     // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456
     // We follow what it did anyway :)
-    if segments.len() == 1 && kind == PathKind::Plain {
-        if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) {
-            let syn_ctxt = collector.expander.ctx_for_range(path.segment()?.syntax().text_range());
-            if let Some(macro_call_id) = syn_ctxt.outer_expn(collector.db) {
-                if collector.db.lookup_intern_macro_call(macro_call_id.into()).def.local_inner {
-                    kind = match resolve_crate_root(collector.db, syn_ctxt) {
-                        Some(crate_root) => PathKind::DollarCrate(crate_root),
-                        None => PathKind::Crate,
-                    }
-                }
+    if segments.len() == 1
+        && kind == PathKind::Plain
+        && let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast)
+    {
+        let syn_ctxt = collector.expander.ctx_for_range(path.segment()?.syntax().text_range());
+        if let Some(macro_call_id) = syn_ctxt.outer_expn(collector.db)
+            && collector.db.lookup_intern_macro_call(macro_call_id.into()).def.local_inner
+        {
+            kind = match resolve_crate_root(collector.db, syn_ctxt) {
+                Some(crate_root) => PathKind::DollarCrate(crate_root),
+                None => PathKind::Crate,
             }
         }
     }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
index f1b011333d9..b81dcc1fe96 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
@@ -900,14 +900,12 @@ impl Printer<'_> {
                         let field_name = arg.name.display(self.db, edition).to_string();
 
                         let mut same_name = false;
-                        if let Pat::Bind { id, subpat: None } = &self.store[arg.pat] {
-                            if let Binding { name, mode: BindingAnnotation::Unannotated, .. } =
+                        if let Pat::Bind { id, subpat: None } = &self.store[arg.pat]
+                            && let Binding { name, mode: BindingAnnotation::Unannotated, .. } =
                                 &self.store.assert_expr_only().bindings[*id]
-                            {
-                                if name.as_str() == field_name {
-                                    same_name = true;
-                                }
-                            }
+                            && name.as_str() == field_name
+                        {
+                            same_name = true;
                         }
 
                         w!(p, "{}", field_name);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
index dccfff002f2..faa0ef8ceec 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
@@ -107,11 +107,11 @@ struct FindPathCtx<'db> {
 /// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId
 fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Option<ModPath> {
     // - if the item is a module, jump straight to module search
-    if !ctx.is_std_item {
-        if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
-            return find_path_for_module(ctx, &mut FxHashSet::default(), module_id, true, max_len)
-                .map(|choice| choice.path);
-        }
+    if !ctx.is_std_item
+        && let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item
+    {
+        return find_path_for_module(ctx, &mut FxHashSet::default(), module_id, true, max_len)
+            .map(|choice| choice.path);
     }
 
     let may_be_in_scope = match ctx.prefix {
@@ -226,15 +226,15 @@ fn find_path_for_module(
     }
 
     // - if the module can be referenced as self, super or crate, do that
-    if let Some(kind) = is_kw_kind_relative_to_from(ctx.from_def_map, module_id, ctx.from) {
-        if ctx.prefix != PrefixKind::ByCrate || kind == PathKind::Crate {
-            return Some(Choice {
-                path: ModPath::from_segments(kind, None),
-                path_text_len: path_kind_len(kind),
-                stability: Stable,
-                prefer_due_to_prelude: false,
-            });
-        }
+    if let Some(kind) = is_kw_kind_relative_to_from(ctx.from_def_map, module_id, ctx.from)
+        && (ctx.prefix != PrefixKind::ByCrate || kind == PathKind::Crate)
+    {
+        return Some(Choice {
+            path: ModPath::from_segments(kind, None),
+            path_text_len: path_kind_len(kind),
+            stability: Stable,
+            prefer_due_to_prelude: false,
+        });
     }
 
     // - if the module is in the prelude, return it by that path
@@ -604,29 +604,29 @@ fn find_local_import_locations(
             &def_map[module.local_id]
         };
 
-        if let Some((name, vis, declared)) = data.scope.name_of(item) {
-            if vis.is_visible_from(db, from) {
-                let is_pub_or_explicit = match vis {
-                    Visibility::Module(_, VisibilityExplicitness::Explicit) => {
-                        cov_mark::hit!(explicit_private_imports);
-                        true
-                    }
-                    Visibility::Module(_, VisibilityExplicitness::Implicit) => {
-                        cov_mark::hit!(discount_private_imports);
-                        false
-                    }
-                    Visibility::PubCrate(_) => true,
-                    Visibility::Public => true,
-                };
-
-                // Ignore private imports unless they are explicit. these could be used if we are
-                // in a submodule of this module, but that's usually not
-                // what the user wants; and if this module can import
-                // the item and we're a submodule of it, so can we.
-                // Also this keeps the cached data smaller.
-                if declared || is_pub_or_explicit {
-                    cb(visited_modules, name, module);
+        if let Some((name, vis, declared)) = data.scope.name_of(item)
+            && vis.is_visible_from(db, from)
+        {
+            let is_pub_or_explicit = match vis {
+                Visibility::Module(_, VisibilityExplicitness::Explicit) => {
+                    cov_mark::hit!(explicit_private_imports);
+                    true
                 }
+                Visibility::Module(_, VisibilityExplicitness::Implicit) => {
+                    cov_mark::hit!(discount_private_imports);
+                    false
+                }
+                Visibility::PubCrate(_) => true,
+                Visibility::Public => true,
+            };
+
+            // Ignore private imports unless they are explicit. these could be used if we are
+            // in a submodule of this module, but that's usually not
+            // what the user wants; and if this module can import
+            // the item and we're a submodule of it, so can we.
+            // Also this keeps the cached data smaller.
+            if declared || is_pub_or_explicit {
+                cb(visited_modules, name, module);
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
index efa43994685..8f526d1a236 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
@@ -510,12 +510,11 @@ impl ItemScope {
         id: AttrId,
         idx: usize,
     ) {
-        if let Some(derives) = self.derive_macros.get_mut(&adt) {
-            if let Some(DeriveMacroInvocation { derive_call_ids, .. }) =
+        if let Some(derives) = self.derive_macros.get_mut(&adt)
+            && let Some(DeriveMacroInvocation { derive_call_ids, .. }) =
                 derives.iter_mut().find(|&&mut DeriveMacroInvocation { attr_id, .. }| id == attr_id)
-            {
-                derive_call_ids[idx] = Some(call);
-            }
+        {
+            derive_call_ids[idx] = Some(call);
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
index 5ab61c89394..032b287cd6a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
@@ -83,12 +83,12 @@ impl<'a> Ctx<'a> {
             .flat_map(|item| self.lower_mod_item(&item))
             .collect();
 
-        if let Some(ast::Expr::MacroExpr(tail_macro)) = stmts.expr() {
-            if let Some(call) = tail_macro.macro_call() {
-                cov_mark::hit!(macro_stmt_with_trailing_macro_expr);
-                if let Some(mod_item) = self.lower_mod_item(&call.into()) {
-                    self.top_level.push(mod_item);
-                }
+        if let Some(ast::Expr::MacroExpr(tail_macro)) = stmts.expr()
+            && let Some(call) = tail_macro.macro_call()
+        {
+            cov_mark::hit!(macro_stmt_with_trailing_macro_expr);
+            if let Some(mod_item) = self.lower_mod_item(&call.into()) {
+                self.top_level.push(mod_item);
             }
         }
 
@@ -112,12 +112,11 @@ impl<'a> Ctx<'a> {
                 _ => None,
             })
             .collect();
-        if let Some(ast::Expr::MacroExpr(expr)) = block.tail_expr() {
-            if let Some(call) = expr.macro_call() {
-                if let Some(mod_item) = self.lower_mod_item(&call.into()) {
-                    self.top_level.push(mod_item);
-                }
-            }
+        if let Some(ast::Expr::MacroExpr(expr)) = block.tail_expr()
+            && let Some(call) = expr.macro_call()
+            && let Some(mod_item) = self.lower_mod_item(&call.into())
+        {
+            self.top_level.push(mod_item);
         }
         self.tree.vis.arena = self.visibilities.into_iter().collect();
         self.tree.top_level = self.top_level.into_boxed_slice();
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 750308026ee..d431f214016 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
@@ -218,10 +218,10 @@ pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option
 
     for (_, module_data) in crate_def_map.modules() {
         for def in module_data.scope.declarations() {
-            if let ModuleDefId::TraitId(trait_) = def {
-                if db.attrs(trait_.into()).has_doc_notable_trait() {
-                    traits.push(trait_);
-                }
+            if let ModuleDefId::TraitId(trait_) = def
+                && db.attrs(trait_.into()).has_doc_notable_trait()
+            {
+                traits.push(trait_);
             }
         }
     }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
index 5e95b061399..e8ae499d27b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -221,46 +221,42 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
             _ => None,
         };
 
-        if let Some(src) = src {
-            if let Some(file_id) = src.file_id.macro_file() {
-                if let MacroKind::Derive
-                | MacroKind::DeriveBuiltIn
-                | MacroKind::Attr
-                | MacroKind::AttrBuiltIn = file_id.kind(&db)
-                {
-                    let call = file_id.call_node(&db);
-                    let mut show_spans = false;
-                    let mut show_ctxt = false;
-                    for comment in
-                        call.value.children_with_tokens().filter(|it| it.kind() == COMMENT)
-                    {
-                        show_spans |= comment.to_string().contains("+spans");
-                        show_ctxt |= comment.to_string().contains("+syntaxctxt");
-                    }
-                    let pp = pretty_print_macro_expansion(
-                        src.value,
-                        db.span_map(src.file_id).as_ref(),
-                        show_spans,
-                        show_ctxt,
-                    );
-                    format_to!(expanded_text, "\n{}", pp)
-                }
+        if let Some(src) = src
+            && let Some(file_id) = src.file_id.macro_file()
+            && let MacroKind::Derive
+            | MacroKind::DeriveBuiltIn
+            | MacroKind::Attr
+            | MacroKind::AttrBuiltIn = file_id.kind(&db)
+        {
+            let call = file_id.call_node(&db);
+            let mut show_spans = false;
+            let mut show_ctxt = false;
+            for comment in call.value.children_with_tokens().filter(|it| it.kind() == COMMENT) {
+                show_spans |= comment.to_string().contains("+spans");
+                show_ctxt |= comment.to_string().contains("+syntaxctxt");
             }
+            let pp = pretty_print_macro_expansion(
+                src.value,
+                db.span_map(src.file_id).as_ref(),
+                show_spans,
+                show_ctxt,
+            );
+            format_to!(expanded_text, "\n{}", pp)
         }
     }
 
     for impl_id in def_map[local_id].scope.impls() {
         let src = impl_id.lookup(&db).source(&db);
-        if let Some(macro_file) = src.file_id.macro_file() {
-            if let MacroKind::DeriveBuiltIn | MacroKind::Derive = macro_file.kind(&db) {
-                let pp = pretty_print_macro_expansion(
-                    src.value.syntax().clone(),
-                    db.span_map(macro_file.into()).as_ref(),
-                    false,
-                    false,
-                );
-                format_to!(expanded_text, "\n{}", pp)
-            }
+        if let Some(macro_file) = src.file_id.macro_file()
+            && let MacroKind::DeriveBuiltIn | MacroKind::Derive = macro_file.kind(&db)
+        {
+            let pp = pretty_print_macro_expansion(
+                src.value.syntax().clone(),
+                db.span_map(macro_file.into()).as_ref(),
+                false,
+                false,
+            );
+            format_to!(expanded_text, "\n{}", pp)
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index 0c3274d849a..267c4451b9d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -261,20 +261,20 @@ impl<'db> DefCollector<'db> {
 
         // Process other crate-level attributes.
         for attr in &*attrs {
-            if let Some(cfg) = attr.cfg() {
-                if self.cfg_options.check(&cfg) == Some(false) {
-                    process = false;
-                    break;
-                }
+            if let Some(cfg) = attr.cfg()
+                && self.cfg_options.check(&cfg) == Some(false)
+            {
+                process = false;
+                break;
             }
             let Some(attr_name) = attr.path.as_ident() else { continue };
 
             match () {
                 () if *attr_name == sym::recursion_limit => {
-                    if let Some(limit) = attr.string_value() {
-                        if let Ok(limit) = limit.as_str().parse() {
-                            crate_data.recursion_limit = Some(limit);
-                        }
+                    if let Some(limit) = attr.string_value()
+                        && let Ok(limit) = limit.as_str().parse()
+                    {
+                        crate_data.recursion_limit = Some(limit);
                     }
                 }
                 () if *attr_name == sym::crate_type => {
@@ -1188,56 +1188,44 @@ impl<'db> DefCollector<'db> {
             // Multiple globs may import the same item and they may override visibility from
             // previously resolved globs. Handle overrides here and leave the rest to
             // `ItemScope::push_res_with_import()`.
-            if let Some(def) = defs.types {
-                if let Some(prev_def) = prev_defs.types {
-                    if def.def == prev_def.def
-                        && self.from_glob_import.contains_type(module_id, name.clone())
-                        && def.vis != prev_def.vis
-                        && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
-                    {
-                        changed = true;
-                        // This import is being handled here, don't pass it down to
-                        // `ItemScope::push_res_with_import()`.
-                        defs.types = None;
-                        self.def_map.modules[module_id]
-                            .scope
-                            .update_visibility_types(name, def.vis);
-                    }
-                }
+            if let Some(def) = defs.types
+                && let Some(prev_def) = prev_defs.types
+                && def.def == prev_def.def
+                && self.from_glob_import.contains_type(module_id, name.clone())
+                && def.vis != prev_def.vis
+                && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
+            {
+                changed = true;
+                // This import is being handled here, don't pass it down to
+                // `ItemScope::push_res_with_import()`.
+                defs.types = None;
+                self.def_map.modules[module_id].scope.update_visibility_types(name, def.vis);
             }
 
-            if let Some(def) = defs.values {
-                if let Some(prev_def) = prev_defs.values {
-                    if def.def == prev_def.def
-                        && self.from_glob_import.contains_value(module_id, name.clone())
-                        && def.vis != prev_def.vis
-                        && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
-                    {
-                        changed = true;
-                        // See comment above.
-                        defs.values = None;
-                        self.def_map.modules[module_id]
-                            .scope
-                            .update_visibility_values(name, def.vis);
-                    }
-                }
+            if let Some(def) = defs.values
+                && let Some(prev_def) = prev_defs.values
+                && def.def == prev_def.def
+                && self.from_glob_import.contains_value(module_id, name.clone())
+                && def.vis != prev_def.vis
+                && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
+            {
+                changed = true;
+                // See comment above.
+                defs.values = None;
+                self.def_map.modules[module_id].scope.update_visibility_values(name, def.vis);
             }
 
-            if let Some(def) = defs.macros {
-                if let Some(prev_def) = prev_defs.macros {
-                    if def.def == prev_def.def
-                        && self.from_glob_import.contains_macro(module_id, name.clone())
-                        && def.vis != prev_def.vis
-                        && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
-                    {
-                        changed = true;
-                        // See comment above.
-                        defs.macros = None;
-                        self.def_map.modules[module_id]
-                            .scope
-                            .update_visibility_macros(name, def.vis);
-                    }
-                }
+            if let Some(def) = defs.macros
+                && let Some(prev_def) = prev_defs.macros
+                && def.def == prev_def.def
+                && self.from_glob_import.contains_macro(module_id, name.clone())
+                && def.vis != prev_def.vis
+                && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
+            {
+                changed = true;
+                // See comment above.
+                defs.macros = None;
+                self.def_map.modules[module_id].scope.update_visibility_macros(name, def.vis);
             }
         }
 
@@ -1392,15 +1380,14 @@ impl<'db> DefCollector<'db> {
                         Resolved::Yes
                     };
 
-                    if let Some(ident) = path.as_ident() {
-                        if let Some(helpers) = self.def_map.derive_helpers_in_scope.get(&ast_id) {
-                            if helpers.iter().any(|(it, ..)| it == ident) {
-                                cov_mark::hit!(resolved_derive_helper);
-                                // Resolved to derive helper. Collect the item's attributes again,
-                                // starting after the derive helper.
-                                return recollect_without(self);
-                            }
-                        }
+                    if let Some(ident) = path.as_ident()
+                        && let Some(helpers) = self.def_map.derive_helpers_in_scope.get(&ast_id)
+                        && helpers.iter().any(|(it, ..)| it == ident)
+                    {
+                        cov_mark::hit!(resolved_derive_helper);
+                        // Resolved to derive helper. Collect the item's attributes again,
+                        // starting after the derive helper.
+                        return recollect_without(self);
                     }
 
                     let def = match resolver_def_id(path) {
@@ -1729,12 +1716,12 @@ impl ModCollector<'_, '_> {
 
         let mut process_mod_item = |item: ModItemId| {
             let attrs = self.item_tree.attrs(db, krate, item.ast_id());
-            if let Some(cfg) = attrs.cfg() {
-                if !self.is_cfg_enabled(&cfg) {
-                    let ast_id = item.ast_id().erase();
-                    self.emit_unconfigured_diagnostic(InFile::new(self.file_id(), ast_id), &cfg);
-                    return;
-                }
+            if let Some(cfg) = attrs.cfg()
+                && !self.is_cfg_enabled(&cfg)
+            {
+                let ast_id = item.ast_id().erase();
+                self.emit_unconfigured_diagnostic(InFile::new(self.file_id(), ast_id), &cfg);
+                return;
             }
 
             if let Err(()) = self.resolve_attributes(&attrs, item, container) {
@@ -1871,14 +1858,13 @@ impl ModCollector<'_, '_> {
                     if self.def_collector.def_map.block.is_none()
                         && self.def_collector.is_proc_macro
                         && self.module_id == DefMap::ROOT
+                        && let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name)
                     {
-                        if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) {
-                            self.def_collector.export_proc_macro(
-                                proc_macro,
-                                InFile::new(self.file_id(), id),
-                                fn_id,
-                            );
-                        }
+                        self.def_collector.export_proc_macro(
+                            proc_macro,
+                            InFile::new(self.file_id(), id),
+                            fn_id,
+                        );
                     }
 
                     update_def(self.def_collector, fn_id.into(), &it.name, vis, false);
@@ -2419,13 +2405,13 @@ impl ModCollector<'_, '_> {
             macro_id,
             &self.item_tree[mac.visibility],
         );
-        if let Some(helpers) = helpers_opt {
-            if self.def_collector.def_map.block.is_none() {
-                Arc::get_mut(&mut self.def_collector.def_map.data)
-                    .unwrap()
-                    .exported_derives
-                    .insert(macro_id.into(), helpers);
-            }
+        if let Some(helpers) = helpers_opt
+            && self.def_collector.def_map.block.is_none()
+        {
+            Arc::get_mut(&mut self.def_collector.def_map.data)
+                .unwrap()
+                .exported_derives
+                .insert(macro_id.into(), helpers);
         }
     }
 
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 316ad5dae69..a10990e6a8f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -228,15 +228,15 @@ impl<'db> Resolver<'db> {
                                 ResolvePathResultPrefixInfo::default(),
                             ));
                         }
-                    } else if let &GenericDefId::AdtId(adt) = def {
-                        if *first_name == sym::Self_ {
-                            return Some((
-                                TypeNs::AdtSelfType(adt),
-                                remaining_idx(),
-                                None,
-                                ResolvePathResultPrefixInfo::default(),
-                            ));
-                        }
+                    } else if let &GenericDefId::AdtId(adt) = def
+                        && *first_name == sym::Self_
+                    {
+                        return Some((
+                            TypeNs::AdtSelfType(adt),
+                            remaining_idx(),
+                            None,
+                            ResolvePathResultPrefixInfo::default(),
+                        ));
                     }
                     if let Some(id) = params.find_type_by_name(first_name, *def) {
                         return Some((
@@ -401,13 +401,13 @@ impl<'db> Resolver<'db> {
                         handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id)
                     }
                     Scope::GenericParams { params, def } => {
-                        if let &GenericDefId::ImplId(impl_) = def {
-                            if *first_name == sym::Self_ {
-                                return Some((
-                                    ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_), None),
-                                    ResolvePathResultPrefixInfo::default(),
-                                ));
-                            }
+                        if let &GenericDefId::ImplId(impl_) = def
+                            && *first_name == sym::Self_
+                        {
+                            return Some((
+                                ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_), None),
+                                ResolvePathResultPrefixInfo::default(),
+                            ));
                         }
                         if let Some(id) = params.find_const_by_name(first_name, *def) {
                             let val = ValueNs::GenericParam(id);
@@ -436,14 +436,14 @@ impl<'db> Resolver<'db> {
                                     ResolvePathResultPrefixInfo::default(),
                                 ));
                             }
-                        } else if let &GenericDefId::AdtId(adt) = def {
-                            if *first_name == sym::Self_ {
-                                let ty = TypeNs::AdtSelfType(adt);
-                                return Some((
-                                    ResolveValueResult::Partial(ty, 1, None),
-                                    ResolvePathResultPrefixInfo::default(),
-                                ));
-                            }
+                        } else if let &GenericDefId::AdtId(adt) = def
+                            && *first_name == sym::Self_
+                        {
+                            let ty = TypeNs::AdtSelfType(adt);
+                            return Some((
+                                ResolveValueResult::Partial(ty, 1, None),
+                                ResolvePathResultPrefixInfo::default(),
+                            ));
                         }
                         if let Some(id) = params.find_type_by_name(first_name, *def) {
                             let ty = TypeNs::GenericParam(id);
@@ -469,13 +469,14 @@ impl<'db> Resolver<'db> {
         // If a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back
         // to resolving to the primitive type, to allow this to still work in the presence of
         // `use core::u16;`.
-        if path.kind == PathKind::Plain && n_segments > 1 {
-            if let Some(builtin) = BuiltinType::by_name(first_name) {
-                return Some((
-                    ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None),
-                    ResolvePathResultPrefixInfo::default(),
-                ));
-            }
+        if path.kind == PathKind::Plain
+            && n_segments > 1
+            && let Some(builtin) = BuiltinType::by_name(first_name)
+        {
+            return Some((
+                ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None),
+                ResolvePathResultPrefixInfo::default(),
+            ));
         }
 
         None
@@ -660,12 +661,11 @@ impl<'db> Resolver<'db> {
                 Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()),
                 &Scope::GenericParams { def: GenericDefId::ImplId(impl_), .. } => {
                     let impl_data = db.impl_signature(impl_);
-                    if let Some(target_trait) = impl_data.target_trait {
-                        if let Some(TypeNs::TraitId(trait_)) = self
+                    if let Some(target_trait) = impl_data.target_trait
+                        && let Some(TypeNs::TraitId(trait_)) = self
                             .resolve_path_in_type_ns_fully(db, &impl_data.store[target_trait.path])
-                        {
-                            traits.insert(trait_);
-                        }
+                    {
+                        traits.insert(trait_);
                     }
                 }
                 _ => (),
@@ -918,17 +918,17 @@ fn handle_macro_def_scope(
     hygiene_info: &mut Option<(SyntaxContext, MacroDefId)>,
     macro_id: &MacroDefId,
 ) {
-    if let Some((parent_ctx, label_macro_id)) = hygiene_info {
-        if label_macro_id == macro_id {
-            // A macro is allowed to refer to variables from before its declaration.
-            // Therefore, if we got to the rib of its declaration, give up its hygiene
-            // and use its parent expansion.
-            *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(db));
-            *hygiene_info = parent_ctx.outer_expn(db).map(|expansion| {
-                let expansion = db.lookup_intern_macro_call(expansion.into());
-                (parent_ctx.parent(db), expansion.def)
-            });
-        }
+    if let Some((parent_ctx, label_macro_id)) = hygiene_info
+        && label_macro_id == macro_id
+    {
+        // A macro is allowed to refer to variables from before its declaration.
+        // Therefore, if we got to the rib of its declaration, give up its hygiene
+        // and use its parent expansion.
+        *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(db));
+        *hygiene_info = parent_ctx.outer_expn(db).map(|expansion| {
+            let expansion = db.lookup_intern_macro_call(expansion.into());
+            (parent_ctx.parent(db), expansion.def)
+        });
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
index 4a9af01091f..ec344613761 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
@@ -555,12 +555,11 @@ fn concat_expand(
         // FIXME: hack on top of a hack: `$e:expr` captures get surrounded in parentheses
         // to ensure the right parsing order, so skip the parentheses here. Ideally we'd
         // implement rustc's model. cc https://github.com/rust-lang/rust-analyzer/pull/10623
-        if let TtElement::Subtree(subtree, subtree_iter) = &t {
-            if let [tt::TokenTree::Leaf(tt)] = subtree_iter.remaining().flat_tokens() {
-                if subtree.delimiter.kind == tt::DelimiterKind::Parenthesis {
-                    t = TtElement::Leaf(tt);
-                }
-            }
+        if let TtElement::Subtree(subtree, subtree_iter) = &t
+            && let [tt::TokenTree::Leaf(tt)] = subtree_iter.remaining().flat_tokens()
+            && subtree.delimiter.kind == tt::DelimiterKind::Parenthesis
+        {
+            t = TtElement::Leaf(tt);
         }
         match t {
             TtElement::Leaf(tt::Leaf::Literal(it)) if i % 2 == 0 => {
@@ -891,7 +890,7 @@ fn include_str_expand(
     };
 
     let text = db.file_text(file_id.file_id(db));
-    let text = &*text.text(db);
+    let text = &**text.text(db);
 
     ExpandResult::ok(quote!(call_site =>#text))
 }
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs
index c6ea4a3a33d..d5ebd6ee19f 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs
@@ -334,10 +334,10 @@ where
             _ => Some(CfgExpr::Atom(CfgAtom::Flag(name))),
         },
     };
-    if let Some(NodeOrToken::Token(element)) = iter.peek() {
-        if element.kind() == syntax::T![,] {
-            iter.next();
-        }
+    if let Some(NodeOrToken::Token(element)) = iter.peek()
+        && element.kind() == syntax::T![,]
+    {
+        iter.next();
     }
     result
 }
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs
index 6730b337d35..a7f3e27a455 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs
@@ -99,6 +99,16 @@ impl FileRange {
     pub fn into_file_id(self, db: &dyn ExpandDatabase) -> FileRangeWrapper<FileId> {
         FileRangeWrapper { file_id: self.file_id.file_id(db), range: self.range }
     }
+
+    #[inline]
+    pub fn file_text(self, db: &dyn ExpandDatabase) -> &triomphe::Arc<str> {
+        db.file_text(self.file_id.file_id(db)).text(db)
+    }
+
+    #[inline]
+    pub fn text(self, db: &dyn ExpandDatabase) -> &str {
+        &self.file_text(db)[self.range]
+    }
 }
 
 /// `AstId` points to an AST node in any file.
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
index 4a4a3e52aea..fe77e156598 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
@@ -280,8 +280,8 @@ pub(crate) fn fixup_syntax(
                     }
                 },
                 ast::RecordExprField(it) => {
-                    if let Some(colon) = it.colon_token() {
-                        if it.name_ref().is_some() && it.expr().is_none() {
+                    if let Some(colon) = it.colon_token()
+                        && it.name_ref().is_some() && it.expr().is_none() {
                             append.insert(colon.into(), vec![
                                 Leaf::Ident(Ident {
                                     sym: sym::__ra_fixup,
@@ -290,11 +290,10 @@ pub(crate) fn fixup_syntax(
                                 })
                             ]);
                         }
-                    }
                 },
                 ast::Path(it) => {
-                    if let Some(colon) = it.coloncolon_token() {
-                        if it.segment().is_none() {
+                    if let Some(colon) = it.coloncolon_token()
+                        && it.segment().is_none() {
                             append.insert(colon.into(), vec![
                                 Leaf::Ident(Ident {
                                     sym: sym::__ra_fixup,
@@ -303,7 +302,6 @@ pub(crate) fn fixup_syntax(
                                 })
                             ]);
                         }
-                    }
                 },
                 ast::ClosureExpr(it) => {
                     if it.body().is_none() {
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
index ac61b220097..472ec83ffef 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -365,12 +365,11 @@ impl HirFileId {
                 HirFileId::FileId(id) => break id,
                 HirFileId::MacroFile(file) => {
                     let loc = db.lookup_intern_macro_call(file);
-                    if loc.def.is_include() {
-                        if let MacroCallKind::FnLike { eager: Some(eager), .. } = &loc.kind {
-                            if let Ok(it) = include_input_to_file_id(db, file, &eager.arg) {
-                                break it;
-                            }
-                        }
+                    if loc.def.is_include()
+                        && let MacroCallKind::FnLike { eager: Some(eager), .. } = &loc.kind
+                        && let Ok(it) = include_input_to_file_id(db, file, &eager.arg)
+                    {
+                        break it;
                     }
                     self = loc.kind.file_id();
                 }
@@ -648,12 +647,11 @@ impl MacroCallLoc {
         db: &dyn ExpandDatabase,
         macro_call_id: MacroCallId,
     ) -> Option<EditionedFileId> {
-        if self.def.is_include() {
-            if let MacroCallKind::FnLike { eager: Some(eager), .. } = &self.kind {
-                if let Ok(it) = include_input_to_file_id(db, macro_call_id, &eager.arg) {
-                    return Some(it);
-                }
-            }
+        if self.def.is_include()
+            && let MacroCallKind::FnLike { eager: Some(eager), .. } = &self.kind
+            && let Ok(it) = include_input_to_file_id(db, macro_call_id, &eager.arg)
+        {
+            return Some(it);
         }
 
         None
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
index 9f1e3879e1e..d84d978cdb7 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
@@ -273,16 +273,17 @@ fn convert_path(
     // Basically, even in rustc it is quite hacky:
     // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456
     // We follow what it did anyway :)
-    if mod_path.segments.len() == 1 && mod_path.kind == PathKind::Plain {
-        if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) {
-            let syn_ctx = span_for_range(segment.syntax().text_range());
-            if let Some(macro_call_id) = syn_ctx.outer_expn(db) {
-                if db.lookup_intern_macro_call(macro_call_id.into()).def.local_inner {
-                    mod_path.kind = match resolve_crate_root(db, syn_ctx) {
-                        Some(crate_root) => PathKind::DollarCrate(crate_root),
-                        None => PathKind::Crate,
-                    }
-                }
+    if mod_path.segments.len() == 1
+        && mod_path.kind == PathKind::Plain
+        && let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast)
+    {
+        let syn_ctx = span_for_range(segment.syntax().text_range());
+        if let Some(macro_call_id) = syn_ctx.outer_expn(db)
+            && db.lookup_intern_macro_call(macro_call_id.into()).def.local_inner
+        {
+            mod_path.kind = match resolve_crate_root(db, syn_ctx) {
+                Some(crate_root) => PathKind::DollarCrate(crate_root),
+                None => PathKind::Crate,
             }
         }
     }
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 cc8f7bf04a5..26ca7fb9a15 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
@@ -197,10 +197,11 @@ pub(crate) fn deref_by_trait(
         // 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) = LangItem::Receiver.resolve_trait(db, table.trait_env.krate) {
-                return Some(receiver);
-            }
+        if use_receiver_trait
+            && false
+            && let Some(receiver) = LangItem::Receiver.resolve_trait(db, table.trait_env.krate)
+        {
+            return Some(receiver);
         }
         // Old rustc versions might not have `Receiver` trait.
         // Fallback to `Deref` if they don't
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
index 77d15a73af6..8af8fb73f34 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
@@ -309,11 +309,11 @@ impl TyBuilder<hir_def::AdtId> {
         if let Some(defaults) = defaults.get(self.vec.len()..) {
             for default_ty in defaults {
                 // NOTE(skip_binders): we only check if the arg type is error type.
-                if let Some(x) = default_ty.skip_binders().ty(Interner) {
-                    if x.is_unknown() {
-                        self.vec.push(fallback().cast(Interner));
-                        continue;
-                    }
+                if let Some(x) = default_ty.skip_binders().ty(Interner)
+                    && x.is_unknown()
+                {
+                    self.vec.push(fallback().cast(Interner));
+                    continue;
                 }
                 // Each default can only depend on the previous parameters.
                 self.vec.push(default_ty.clone().substitute(Interner, &*self.vec).cast(Interner));
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
index 26b635298a6..3ba7c93d4fb 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
@@ -83,34 +83,34 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
         Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
     }
     fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
-        if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) {
-            if let hir_def::AdtId::EnumId(e) = id.0 {
-                let enum_data = self.db.enum_signature(e);
-                let ty = enum_data.repr.unwrap_or_default().discr_type();
-                return chalk_ir::TyKind::Scalar(match ty {
-                    hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed {
-                        true => chalk_ir::Scalar::Int(chalk_ir::IntTy::Isize),
-                        false => chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize),
-                    },
-                    hir_def::layout::IntegerType::Fixed(size, is_signed) => match is_signed {
-                        true => chalk_ir::Scalar::Int(match size {
-                            hir_def::layout::Integer::I8 => chalk_ir::IntTy::I8,
-                            hir_def::layout::Integer::I16 => chalk_ir::IntTy::I16,
-                            hir_def::layout::Integer::I32 => chalk_ir::IntTy::I32,
-                            hir_def::layout::Integer::I64 => chalk_ir::IntTy::I64,
-                            hir_def::layout::Integer::I128 => chalk_ir::IntTy::I128,
-                        }),
-                        false => chalk_ir::Scalar::Uint(match size {
-                            hir_def::layout::Integer::I8 => chalk_ir::UintTy::U8,
-                            hir_def::layout::Integer::I16 => chalk_ir::UintTy::U16,
-                            hir_def::layout::Integer::I32 => chalk_ir::UintTy::U32,
-                            hir_def::layout::Integer::I64 => chalk_ir::UintTy::U64,
-                            hir_def::layout::Integer::I128 => chalk_ir::UintTy::U128,
-                        }),
-                    },
-                })
-                .intern(Interner);
-            }
+        if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner)
+            && let hir_def::AdtId::EnumId(e) = id.0
+        {
+            let enum_data = self.db.enum_signature(e);
+            let ty = enum_data.repr.unwrap_or_default().discr_type();
+            return chalk_ir::TyKind::Scalar(match ty {
+                hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed {
+                    true => chalk_ir::Scalar::Int(chalk_ir::IntTy::Isize),
+                    false => chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize),
+                },
+                hir_def::layout::IntegerType::Fixed(size, is_signed) => match is_signed {
+                    true => chalk_ir::Scalar::Int(match size {
+                        hir_def::layout::Integer::I8 => chalk_ir::IntTy::I8,
+                        hir_def::layout::Integer::I16 => chalk_ir::IntTy::I16,
+                        hir_def::layout::Integer::I32 => chalk_ir::IntTy::I32,
+                        hir_def::layout::Integer::I64 => chalk_ir::IntTy::I64,
+                        hir_def::layout::Integer::I128 => chalk_ir::IntTy::I128,
+                    }),
+                    false => chalk_ir::Scalar::Uint(match size {
+                        hir_def::layout::Integer::I8 => chalk_ir::UintTy::U8,
+                        hir_def::layout::Integer::I16 => chalk_ir::UintTy::U16,
+                        hir_def::layout::Integer::I32 => chalk_ir::UintTy::U32,
+                        hir_def::layout::Integer::I64 => chalk_ir::UintTy::U64,
+                        hir_def::layout::Integer::I128 => chalk_ir::UintTy::U128,
+                    }),
+                },
+            })
+            .intern(Interner);
         }
         chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U8)).intern(Interner)
     }
@@ -142,10 +142,10 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
         ) -> Option<chalk_ir::TyVariableKind> {
             if let TyKind::BoundVar(bv) = ty.kind(Interner) {
                 let binders = binders.as_slice(Interner);
-                if bv.debruijn == DebruijnIndex::INNERMOST {
-                    if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
-                        return Some(tk);
-                    }
+                if bv.debruijn == DebruijnIndex::INNERMOST
+                    && let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind
+                {
+                    return Some(tk);
                 }
             }
             None
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 14b9cd203f6..f30ec839a00 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
@@ -342,10 +342,10 @@ pub(crate) fn eval_to_const(
             return c;
         }
     }
-    if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr) {
-        if let Ok((Ok(result), _)) = interpret_mir(db, Arc::new(mir_body), true, None) {
-            return result;
-        }
+    if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr)
+        && let Ok((Ok(result), _)) = interpret_mir(db, Arc::new(mir_body), true, None)
+    {
+        return result;
     }
     unknown_const(infer[expr].clone())
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
index 40fe3073cf2..0815e62f87e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -657,10 +657,10 @@ impl<'a> DeclValidator<'a> {
     }
 
     fn is_trait_impl_container(&self, container_id: ItemContainerId) -> bool {
-        if let ItemContainerId::ImplId(impl_id) = container_id {
-            if self.db.impl_trait(impl_id).is_some() {
-                return true;
-            }
+        if let ItemContainerId::ImplId(impl_id) = container_id
+            && self.db.impl_trait(impl_id).is_some()
+        {
+            return true;
         }
         false
     }
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 cc531f076dd..b26bd2b8fa9 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
@@ -528,15 +528,15 @@ impl FilterMapNextChecker {
             return None;
         }
 
-        if *function_id == self.next_function_id? {
-            if let Some(prev_filter_map_expr_id) = self.prev_filter_map_expr_id {
-                let is_dyn_trait = self
-                    .prev_receiver_ty
-                    .as_ref()
-                    .is_some_and(|it| it.strip_references().dyn_trait().is_some());
-                if *receiver_expr_id == prev_filter_map_expr_id && !is_dyn_trait {
-                    return Some(());
-                }
+        if *function_id == self.next_function_id?
+            && let Some(prev_filter_map_expr_id) = self.prev_filter_map_expr_id
+        {
+            let is_dyn_trait = self
+                .prev_receiver_ty
+                .as_ref()
+                .is_some_and(|it| it.strip_references().dyn_trait().is_some());
+            if *receiver_expr_id == prev_filter_map_expr_id && !is_dyn_trait {
+                return Some(());
             }
         }
 
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 ca132fbdc45..e803b56a1ed 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
@@ -382,10 +382,10 @@ impl HirDisplay for Pat {
                     let subpats = (0..num_fields).map(|i| {
                         WriteWith(move |f| {
                             let fid = LocalFieldId::from_raw((i as u32).into());
-                            if let Some(p) = subpatterns.get(i) {
-                                if p.field == fid {
-                                    return p.pattern.hir_fmt(f);
-                                }
+                            if let Some(p) = subpatterns.get(i)
+                                && p.field == fid
+                            {
+                                return p.pattern.hir_fmt(f);
                             }
                             if let Some(p) = subpatterns.iter().find(|p| p.field == fid) {
                                 p.pattern.hir_fmt(f)
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 f6ad3c7aae2..827585e5069 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
@@ -272,10 +272,10 @@ impl<'db> UnsafeVisitor<'db> {
                 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);
-                    }
+                if let TyKind::Function(fn_ptr) = callee.kind(Interner)
+                    && fn_ptr.sig.safety == chalk_ir::Safety::Unsafe
+                {
+                    self.on_unsafe_op(current.into(), UnsafetyReason::UnsafeFnCall);
                 }
             }
             Expr::Path(path) => {
@@ -346,12 +346,11 @@ impl<'db> UnsafeVisitor<'db> {
             Expr::Cast { .. } => self.inside_assignment = inside_assignment,
             Expr::Field { .. } => {
                 self.inside_assignment = inside_assignment;
-                if !inside_assignment {
-                    if let Some(Either::Left(FieldId { parent: VariantId::UnionId(_), .. })) =
+                if !inside_assignment
+                    && let Some(Either::Left(FieldId { parent: VariantId::UnionId(_), .. })) =
                         self.infer.field_resolution(current)
-                    {
-                        self.on_unsafe_op(current.into(), UnsafetyReason::UnionField);
-                    }
+                {
+                    self.on_unsafe_op(current.into(), UnsafetyReason::UnionField);
                 }
             }
             Expr::Unsafe { statements, .. } => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index b3760e3a382..8f35a3c2145 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -608,48 +608,46 @@ impl HirDisplay for ProjectionTy {
         // if we are projection on a type parameter, check if the projection target has bounds
         // itself, if so, we render them directly as `impl Bound` instead of the less useful
         // `<Param as Trait>::Assoc`
-        if !f.display_kind.is_source_code() {
-            if let TyKind::Placeholder(idx) = self_ty.kind(Interner) {
-                if !f.bounds_formatting_ctx.contains(self) {
-                    let db = f.db;
-                    let id = from_placeholder_idx(db, *idx);
-                    let generics = generics(db, id.parent);
-
-                    let substs = generics.placeholder_subst(db);
-                    let bounds = db
-                        .generic_predicates(id.parent)
-                        .iter()
-                        .map(|pred| pred.clone().substitute(Interner, &substs))
-                        .filter(|wc| match wc.skip_binders() {
-                            WhereClause::Implemented(tr) => {
-                                matches!(
-                                    tr.self_type_parameter(Interner).kind(Interner),
-                                    TyKind::Alias(_)
-                                )
-                            }
-                            WhereClause::TypeOutlives(t) => {
-                                matches!(t.ty.kind(Interner), TyKind::Alias(_))
-                            }
-                            // We shouldn't be here if these exist
-                            WhereClause::AliasEq(_) => false,
-                            WhereClause::LifetimeOutlives(_) => false,
-                        })
-                        .collect::<Vec<_>>();
-                    if !bounds.is_empty() {
-                        return f.format_bounds_with(self.clone(), |f| {
-                            write_bounds_like_dyn_trait_with_prefix(
-                                f,
-                                "impl",
-                                Either::Left(
-                                    &TyKind::Alias(AliasTy::Projection(self.clone()))
-                                        .intern(Interner),
-                                ),
-                                &bounds,
-                                SizedByDefault::NotSized,
-                            )
-                        });
-                    }
-                }
+        if !f.display_kind.is_source_code()
+            && let TyKind::Placeholder(idx) = self_ty.kind(Interner)
+            && !f.bounds_formatting_ctx.contains(self)
+        {
+            let db = f.db;
+            let id = from_placeholder_idx(db, *idx);
+            let generics = generics(db, id.parent);
+
+            let substs = generics.placeholder_subst(db);
+            let bounds = db
+                .generic_predicates(id.parent)
+                .iter()
+                .map(|pred| pred.clone().substitute(Interner, &substs))
+                .filter(|wc| {
+                    let ty = match wc.skip_binders() {
+                        WhereClause::Implemented(tr) => tr.self_type_parameter(Interner),
+                        WhereClause::TypeOutlives(t) => t.ty.clone(),
+                        // We shouldn't be here if these exist
+                        WhereClause::AliasEq(_) | WhereClause::LifetimeOutlives(_) => {
+                            return false;
+                        }
+                    };
+                    let TyKind::Alias(AliasTy::Projection(proj)) = ty.kind(Interner) else {
+                        return false;
+                    };
+                    proj == self
+                })
+                .collect::<Vec<_>>();
+            if !bounds.is_empty() {
+                return f.format_bounds_with(self.clone(), |f| {
+                    write_bounds_like_dyn_trait_with_prefix(
+                        f,
+                        "impl",
+                        Either::Left(
+                            &TyKind::Alias(AliasTy::Projection(self.clone())).intern(Interner),
+                        ),
+                        &bounds,
+                        SizedByDefault::NotSized,
+                    )
+                });
             }
         }
 
@@ -1860,18 +1858,13 @@ fn write_bounds_like_dyn_trait(
                 write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?;
                 f.end_location_link();
                 if is_fn_trait {
-                    if let [self_, params @ ..] = trait_ref.substitution.as_slice(Interner) {
-                        if let Some(args) =
+                    if let [self_, params @ ..] = trait_ref.substitution.as_slice(Interner)
+                        && let Some(args) =
                             params.first().and_then(|it| it.assert_ty_ref(Interner).as_tuple())
-                        {
-                            write!(f, "(")?;
-                            hir_fmt_generic_arguments(
-                                f,
-                                args.as_slice(Interner),
-                                self_.ty(Interner),
-                            )?;
-                            write!(f, ")")?;
-                        }
+                    {
+                        write!(f, "(")?;
+                        hir_fmt_generic_arguments(f, args.as_slice(Interner), self_.ty(Interner))?;
+                        write!(f, ")")?;
                     }
                 } else {
                     let params = generic_args_sans_defaults(
@@ -1879,13 +1872,13 @@ fn write_bounds_like_dyn_trait(
                         Some(trait_.into()),
                         trait_ref.substitution.as_slice(Interner),
                     );
-                    if let [self_, params @ ..] = params {
-                        if !params.is_empty() {
-                            write!(f, "<")?;
-                            hir_fmt_generic_arguments(f, params, self_.ty(Interner))?;
-                            // there might be assoc type bindings, so we leave the angle brackets open
-                            angle_open = true;
-                        }
+                    if let [self_, params @ ..] = params
+                        && !params.is_empty()
+                    {
+                        write!(f, "<")?;
+                        hir_fmt_generic_arguments(f, params, self_.ty(Interner))?;
+                        // there might be assoc type bindings, so we leave the angle brackets open
+                        angle_open = true;
                     }
                 }
             }
@@ -2443,11 +2436,11 @@ impl HirDisplayWithExpressionStore for Path {
                                 generic_args.args[0].hir_fmt(f, store)?;
                             }
                         }
-                        if let Some(ret) = generic_args.bindings[0].type_ref {
-                            if !matches!(&store[ret], TypeRef::Tuple(v) if v.is_empty()) {
-                                write!(f, " -> ")?;
-                                ret.hir_fmt(f, store)?;
-                            }
+                        if let Some(ret) = generic_args.bindings[0].type_ref
+                            && !matches!(&store[ret], TypeRef::Tuple(v) if v.is_empty())
+                        {
+                            write!(f, " -> ")?;
+                            ret.hir_fmt(f, store)?;
                         }
                     }
                     hir_def::expr_store::path::GenericArgsParentheses::No => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs
index 30949c83bfa..6294d683e6c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs
@@ -136,16 +136,15 @@ pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> b
     let predicates = predicates.iter().map(|p| p.skip_binders().skip_binders().clone());
     elaborate_clause_supertraits(db, predicates).any(|pred| match pred {
         WhereClause::Implemented(trait_ref) => {
-            if from_chalk_trait_id(trait_ref.trait_id) == sized {
-                if let TyKind::BoundVar(it) =
+            if from_chalk_trait_id(trait_ref.trait_id) == sized
+                && let TyKind::BoundVar(it) =
                     *trait_ref.self_type_parameter(Interner).kind(Interner)
-                {
-                    // Since `generic_predicates` is `Binder<Binder<..>>`, the `DebrujinIndex` of
-                    // self-parameter is `1`
-                    return it
-                        .index_if_bound_at(DebruijnIndex::ONE)
-                        .is_some_and(|idx| idx == trait_self_param_idx);
-                }
+            {
+                // Since `generic_predicates` is `Binder<Binder<..>>`, the `DebrujinIndex` of
+                // self-parameter is `1`
+                return it
+                    .index_if_bound_at(DebruijnIndex::ONE)
+                    .is_some_and(|idx| idx == trait_self_param_idx);
             }
             false
         }
@@ -401,10 +400,10 @@ where
         cb(MethodViolationCode::ReferencesSelfOutput)?;
     }
 
-    if !func_data.is_async() {
-        if let Some(mvc) = contains_illegal_impl_trait_in_trait(db, &sig) {
-            cb(mvc)?;
-        }
+    if !func_data.is_async()
+        && let Some(mvc) = contains_illegal_impl_trait_in_trait(db, &sig)
+    {
+        cb(mvc)?;
     }
 
     let generic_params = db.generic_params(func.into());
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 7c39afa0ef8..86345b23364 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -902,12 +902,12 @@ impl<'db> InferenceContext<'db> {
                         return false;
                     }
 
-                    if let UnresolvedMethodCall { field_with_same_name, .. } = diagnostic {
-                        if let Some(ty) = field_with_same_name {
-                            *ty = table.resolve_completely(ty.clone());
-                            if ty.contains_unknown() {
-                                *field_with_same_name = None;
-                            }
+                    if let UnresolvedMethodCall { field_with_same_name, .. } = diagnostic
+                        && let Some(ty) = field_with_same_name
+                    {
+                        *ty = table.resolve_completely(ty.clone());
+                        if ty.contains_unknown() {
+                            *field_with_same_name = None;
                         }
                     }
                 }
@@ -1010,12 +1010,12 @@ impl<'db> InferenceContext<'db> {
             param_tys.push(va_list_ty);
         }
         let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
-        if let Some(self_param) = self.body.self_param {
-            if let Some(ty) = param_tys.next() {
-                let ty = self.insert_type_vars(ty);
-                let ty = self.normalize_associated_types_in(ty);
-                self.write_binding_ty(self_param, ty);
-            }
+        if let Some(self_param) = self.body.self_param
+            && let Some(ty) = param_tys.next()
+        {
+            let ty = self.insert_type_vars(ty);
+            let ty = self.normalize_associated_types_in(ty);
+            self.write_binding_ty(self_param, ty);
         }
         let mut tait_candidates = FxHashSet::default();
         for (ty, pat) in param_tys.zip(&*self.body.params) {
@@ -1199,20 +1199,19 @@ impl<'db> InferenceContext<'db> {
             ) -> std::ops::ControlFlow<Self::BreakTy> {
                 let ty = self.table.resolve_ty_shallow(ty);
 
-                if let TyKind::OpaqueType(id, _) = ty.kind(Interner) {
-                    if let ImplTraitId::TypeAliasImplTrait(alias_id, _) =
+                if let TyKind::OpaqueType(id, _) = ty.kind(Interner)
+                    && let ImplTraitId::TypeAliasImplTrait(alias_id, _) =
                         self.db.lookup_intern_impl_trait_id((*id).into())
-                    {
-                        let loc = self.db.lookup_intern_type_alias(alias_id);
-                        match loc.container {
-                            ItemContainerId::ImplId(impl_id) => {
-                                self.assocs.insert(*id, (impl_id, ty.clone()));
-                            }
-                            ItemContainerId::ModuleId(..) | ItemContainerId::ExternBlockId(..) => {
-                                self.non_assocs.insert(*id, ty.clone());
-                            }
-                            _ => {}
+                {
+                    let loc = self.db.lookup_intern_type_alias(alias_id);
+                    match loc.container {
+                        ItemContainerId::ImplId(impl_id) => {
+                            self.assocs.insert(*id, (impl_id, ty.clone()));
+                        }
+                        ItemContainerId::ModuleId(..) | ItemContainerId::ExternBlockId(..) => {
+                            self.non_assocs.insert(*id, ty.clone());
                         }
+                        _ => {}
                     }
                 }
 
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 4e95eca3f94..f0a4167f8e2 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
@@ -233,26 +233,25 @@ impl CastCheck {
         F: FnMut(ExprId, Vec<Adjustment>),
     {
         // Mutability order is opposite to rustc. `Mut < Not`
-        if m_expr <= m_cast {
-            if let TyKind::Array(ety, _) = t_expr.kind(Interner) {
-                // Coerce to a raw pointer so that we generate RawPtr in MIR.
-                let array_ptr_type = TyKind::Raw(m_expr, t_expr.clone()).intern(Interner);
-                if let Ok((adj, _)) = table.coerce(&self.expr_ty, &array_ptr_type, CoerceNever::Yes)
-                {
-                    apply_adjustments(self.source_expr, adj);
-                } else {
-                    never!(
-                        "could not cast from reference to array to pointer to array ({:?} to {:?})",
-                        self.expr_ty,
-                        array_ptr_type
-                    );
-                }
+        if m_expr <= m_cast
+            && let TyKind::Array(ety, _) = t_expr.kind(Interner)
+        {
+            // Coerce to a raw pointer so that we generate RawPtr in MIR.
+            let array_ptr_type = TyKind::Raw(m_expr, t_expr.clone()).intern(Interner);
+            if let Ok((adj, _)) = table.coerce(&self.expr_ty, &array_ptr_type, CoerceNever::Yes) {
+                apply_adjustments(self.source_expr, adj);
+            } else {
+                never!(
+                    "could not cast from reference to array to pointer to array ({:?} to {:?})",
+                    self.expr_ty,
+                    array_ptr_type
+                );
+            }
 
-                // This is a less strict condition than rustc's `demand_eqtype`,
-                // but false negative is better than false positive
-                if table.coerce(ety, t_cast, CoerceNever::Yes).is_ok() {
-                    return Ok(());
-                }
+            // This is a less strict condition than rustc's `demand_eqtype`,
+            // but false negative is better than false positive
+            if table.coerce(ety, t_cast, CoerceNever::Yes).is_ok() {
+                return Ok(());
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
index c3029bf2b59..8024c1a9a4e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
@@ -176,12 +176,12 @@ impl InferenceContext<'_> {
         }
 
         // Deduction based on the expected `dyn Fn` is done separately.
-        if let TyKind::Dyn(dyn_ty) = expected_ty.kind(Interner) {
-            if let Some(sig) = self.deduce_sig_from_dyn_ty(dyn_ty) {
-                let expected_sig_ty = TyKind::Function(sig).intern(Interner);
+        if let TyKind::Dyn(dyn_ty) = expected_ty.kind(Interner)
+            && let Some(sig) = self.deduce_sig_from_dyn_ty(dyn_ty)
+        {
+            let expected_sig_ty = TyKind::Function(sig).intern(Interner);
 
-                self.unify(sig_ty, &expected_sig_ty);
-            }
+            self.unify(sig_ty, &expected_sig_ty);
         }
     }
 
@@ -208,14 +208,13 @@ impl InferenceContext<'_> {
                             alias: AliasTy::Projection(projection_ty),
                             ty: projected_ty,
                         }) = bound.skip_binders()
-                        {
-                            if let Some(sig) = self.deduce_sig_from_projection(
+                            && let Some(sig) = self.deduce_sig_from_projection(
                                 closure_kind,
                                 projection_ty,
                                 projected_ty,
-                            ) {
-                                return Some(sig);
-                            }
+                            )
+                        {
+                            return Some(sig);
                         }
                         None
                     });
@@ -254,55 +253,44 @@ impl InferenceContext<'_> {
         let mut expected_kind = None;
 
         for clause in elaborate_clause_supertraits(self.db, clauses.rev()) {
-            if expected_sig.is_none() {
-                if let WhereClause::AliasEq(AliasEq {
-                    alias: AliasTy::Projection(projection),
-                    ty,
-                }) = &clause
-                {
-                    let inferred_sig =
-                        self.deduce_sig_from_projection(closure_kind, projection, ty);
-                    // Make sure that we didn't infer a signature that mentions itself.
-                    // This can happen when we elaborate certain supertrait bounds that
-                    // mention projections containing the `Self` type. See rust-lang/rust#105401.
-                    struct MentionsTy<'a> {
-                        expected_ty: &'a Ty,
-                    }
-                    impl TypeVisitor<Interner> for MentionsTy<'_> {
-                        type BreakTy = ();
+            if expected_sig.is_none()
+                && let WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection), ty }) =
+                    &clause
+            {
+                let inferred_sig = self.deduce_sig_from_projection(closure_kind, projection, ty);
+                // Make sure that we didn't infer a signature that mentions itself.
+                // This can happen when we elaborate certain supertrait bounds that
+                // mention projections containing the `Self` type. See rust-lang/rust#105401.
+                struct MentionsTy<'a> {
+                    expected_ty: &'a Ty,
+                }
+                impl TypeVisitor<Interner> for MentionsTy<'_> {
+                    type BreakTy = ();
 
-                        fn interner(&self) -> Interner {
-                            Interner
-                        }
+                    fn interner(&self) -> Interner {
+                        Interner
+                    }
 
-                        fn as_dyn(
-                            &mut self,
-                        ) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy>
-                        {
-                            self
-                        }
+                    fn as_dyn(
+                        &mut self,
+                    ) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy>
+                    {
+                        self
+                    }
 
-                        fn visit_ty(
-                            &mut self,
-                            t: &Ty,
-                            db: chalk_ir::DebruijnIndex,
-                        ) -> ControlFlow<()> {
-                            if t == self.expected_ty {
-                                ControlFlow::Break(())
-                            } else {
-                                t.super_visit_with(self, db)
-                            }
+                    fn visit_ty(&mut self, t: &Ty, db: chalk_ir::DebruijnIndex) -> ControlFlow<()> {
+                        if t == self.expected_ty {
+                            ControlFlow::Break(())
+                        } else {
+                            t.super_visit_with(self, db)
                         }
                     }
-                    if inferred_sig
-                        .visit_with(
-                            &mut MentionsTy { expected_ty },
-                            chalk_ir::DebruijnIndex::INNERMOST,
-                        )
-                        .is_continue()
-                    {
-                        expected_sig = inferred_sig;
-                    }
+                }
+                if inferred_sig
+                    .visit_with(&mut MentionsTy { expected_ty }, chalk_ir::DebruijnIndex::INNERMOST)
+                    .is_continue()
+                {
+                    expected_sig = inferred_sig;
                 }
             }
 
@@ -617,11 +605,10 @@ impl HirPlace {
         if let CaptureKind::ByRef(BorrowKind::Mut {
             kind: MutBorrowKind::Default | MutBorrowKind::TwoPhasedBorrow,
         }) = current_capture
+            && self.projections[len..].contains(&ProjectionElem::Deref)
         {
-            if self.projections[len..].contains(&ProjectionElem::Deref) {
-                current_capture =
-                    CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture });
-            }
+            current_capture =
+                CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture });
         }
         current_capture
     }
@@ -1076,12 +1063,11 @@ impl InferenceContext<'_> {
             Mutability::Mut => CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::Default }),
             Mutability::Not => CaptureKind::ByRef(BorrowKind::Shared),
         };
-        if let Some(place) = self.place_of_expr_without_adjust(tgt_expr) {
-            if let Some(place) =
+        if let Some(place) = self.place_of_expr_without_adjust(tgt_expr)
+            && let Some(place) =
                 apply_adjusts_to_place(&mut self.current_capture_span_stack, place, rest)
-            {
-                self.add_capture(place, capture_kind);
-            }
+        {
+            self.add_capture(place, capture_kind);
         }
         self.walk_expr_with_adjust(tgt_expr, rest);
     }
@@ -1169,15 +1155,15 @@ impl InferenceContext<'_> {
                     }
                 }
                 self.walk_expr(*expr);
-                if let Some(discr_place) = self.place_of_expr(*expr) {
-                    if self.is_upvar(&discr_place) {
-                        let mut capture_mode = None;
-                        for arm in arms.iter() {
-                            self.walk_pat(&mut capture_mode, arm.pat);
-                        }
-                        if let Some(c) = capture_mode {
-                            self.push_capture(discr_place, c);
-                        }
+                if let Some(discr_place) = self.place_of_expr(*expr)
+                    && self.is_upvar(&discr_place)
+                {
+                    let mut capture_mode = None;
+                    for arm in arms.iter() {
+                        self.walk_pat(&mut capture_mode, arm.pat);
+                    }
+                    if let Some(c) = capture_mode {
+                        self.push_capture(discr_place, c);
                     }
                 }
             }
@@ -1209,13 +1195,11 @@ impl InferenceContext<'_> {
                     let mutability = 'b: {
                         if let Some(deref_trait) =
                             self.resolve_lang_item(LangItem::DerefMut).and_then(|it| it.as_trait())
-                        {
-                            if let Some(deref_fn) = deref_trait
+                            && let Some(deref_fn) = deref_trait
                                 .trait_items(self.db)
                                 .method_by_name(&Name::new_symbol_root(sym::deref_mut))
-                            {
-                                break 'b deref_fn == f;
-                            }
+                        {
+                            break 'b deref_fn == f;
                         }
                         false
                     };
@@ -1405,10 +1389,10 @@ impl InferenceContext<'_> {
 
     fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty {
         let mut ty = None;
-        if let Some(it) = self.result.expr_adjustments.get(&e) {
-            if let Some(it) = it.last() {
-                ty = Some(it.target.clone());
-            }
+        if let Some(it) = self.result.expr_adjustments.get(&e)
+            && let Some(it) = it.last()
+        {
+            ty = Some(it.target.clone());
         }
         ty.unwrap_or_else(|| self.expr_ty(e))
     }
@@ -1793,10 +1777,10 @@ impl InferenceContext<'_> {
     }
 
     pub(super) fn add_current_closure_dependency(&mut self, dep: ClosureId) {
-        if let Some(c) = self.current_closure {
-            if !dep_creates_cycle(&self.closure_dependencies, &mut FxHashSet::default(), c, dep) {
-                self.closure_dependencies.entry(c).or_default().push(dep);
-            }
+        if let Some(c) = self.current_closure
+            && !dep_creates_cycle(&self.closure_dependencies, &mut FxHashSet::default(), c, dep)
+        {
+            self.closure_dependencies.entry(c).or_default().push(dep);
         }
 
         fn dep_creates_cycle(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs
index 39bd90849fe..761a2564aa7 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs
@@ -164,14 +164,14 @@ impl CoerceMany {
         // - [Comment from rustc](https://github.com/rust-lang/rust/blob/5ff18d0eaefd1bd9ab8ec33dab2404a44e7631ed/compiler/rustc_hir_typeck/src/coercion.rs#L1334-L1335)
         // First try to coerce the new expression to the type of the previous ones,
         // but only if the new expression has no coercion already applied to it.
-        if expr.is_none_or(|expr| !ctx.result.expr_adjustments.contains_key(&expr)) {
-            if let Ok(res) = ctx.coerce(expr, &expr_ty, &self.merged_ty(), CoerceNever::Yes) {
-                self.final_ty = Some(res);
-                if let Some(expr) = expr {
-                    self.expressions.push(expr);
-                }
-                return;
+        if expr.is_none_or(|expr| !ctx.result.expr_adjustments.contains_key(&expr))
+            && let Ok(res) = ctx.coerce(expr, &expr_ty, &self.merged_ty(), CoerceNever::Yes)
+        {
+            self.final_ty = Some(res);
+            if let Some(expr) = expr {
+                self.expressions.push(expr);
             }
+            return;
         }
 
         if let Ok((adjustments, res)) =
@@ -322,18 +322,13 @@ impl InferenceTable<'_> {
         // If we are coercing into a TAIT, coerce into its proxy inference var, instead.
         let mut to_ty = to_ty;
         let _to;
-        if let Some(tait_table) = &self.tait_coercion_table {
-            if let TyKind::OpaqueType(opaque_ty_id, _) = to_ty.kind(Interner) {
-                if !matches!(
-                    from_ty.kind(Interner),
-                    TyKind::InferenceVar(..) | TyKind::OpaqueType(..)
-                ) {
-                    if let Some(ty) = tait_table.get(opaque_ty_id) {
-                        _to = ty.clone();
-                        to_ty = &_to;
-                    }
-                }
-            }
+        if let Some(tait_table) = &self.tait_coercion_table
+            && let TyKind::OpaqueType(opaque_ty_id, _) = to_ty.kind(Interner)
+            && !matches!(from_ty.kind(Interner), TyKind::InferenceVar(..) | TyKind::OpaqueType(..))
+            && let Some(ty) = tait_table.get(opaque_ty_id)
+        {
+            _to = ty.clone();
+            to_ty = &_to;
         }
 
         // Consider coercing the subtype to a DST
@@ -594,14 +589,13 @@ impl InferenceTable<'_> {
         F: FnOnce(Ty) -> Vec<Adjustment>,
         G: FnOnce(Ty) -> Vec<Adjustment>,
     {
-        if let TyKind::Function(to_fn_ptr) = to_ty.kind(Interner) {
-            if let (chalk_ir::Safety::Safe, chalk_ir::Safety::Unsafe) =
+        if let TyKind::Function(to_fn_ptr) = to_ty.kind(Interner)
+            && let (chalk_ir::Safety::Safe, chalk_ir::Safety::Unsafe) =
                 (from_fn_ptr.sig.safety, to_fn_ptr.sig.safety)
-            {
-                let from_unsafe =
-                    TyKind::Function(safe_to_unsafe_fn_ty(from_fn_ptr.clone())).intern(Interner);
-                return self.unify_and(&from_unsafe, to_ty, to_unsafe);
-            }
+        {
+            let from_unsafe =
+                TyKind::Function(safe_to_unsafe_fn_ty(from_fn_ptr.clone())).intern(Interner);
+            return self.unify_and(&from_unsafe, to_ty, to_unsafe);
         }
         self.unify_and(&from_ty, to_ty, normal)
     }
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 d43c99fc282..16fc2bfc063 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
@@ -653,19 +653,18 @@ impl InferenceContext<'_> {
                 // FIXME: Note down method resolution her
                 match op {
                     UnaryOp::Deref => {
-                        if let Some(deref_trait) = self.resolve_lang_trait(LangItem::Deref) {
-                            if let Some(deref_fn) = deref_trait
+                        if let Some(deref_trait) = self.resolve_lang_trait(LangItem::Deref)
+                            && let Some(deref_fn) = deref_trait
                                 .trait_items(self.db)
                                 .method_by_name(&Name::new_symbol_root(sym::deref))
-                            {
-                                // FIXME: this is wrong in multiple ways, subst is empty, and we emit it even for builtin deref (note that
-                                // the mutability is not wrong, and will be fixed in `self.infer_mut`).
-                                self.write_method_resolution(
-                                    tgt_expr,
-                                    deref_fn,
-                                    Substitution::empty(Interner),
-                                );
-                            }
+                        {
+                            // FIXME: this is wrong in multiple ways, subst is empty, and we emit it even for builtin deref (note that
+                            // the mutability is not wrong, and will be fixed in `self.infer_mut`).
+                            self.write_method_resolution(
+                                tgt_expr,
+                                deref_fn,
+                                Substitution::empty(Interner),
+                            );
                         }
                         if let Some(derefed) = builtin_deref(self.table.db, &inner_ty, true) {
                             self.resolve_ty_shallow(derefed)
@@ -1387,28 +1386,28 @@ impl InferenceContext<'_> {
         let ret_ty = match method_ty.callable_sig(self.db) {
             Some(sig) => {
                 let p_left = &sig.params()[0];
-                if matches!(op, BinaryOp::CmpOp(..) | BinaryOp::Assignment { .. }) {
-                    if let TyKind::Ref(mtbl, lt, _) = p_left.kind(Interner) {
-                        self.write_expr_adj(
-                            lhs,
-                            Box::new([Adjustment {
-                                kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
-                                target: p_left.clone(),
-                            }]),
-                        );
-                    }
+                if matches!(op, BinaryOp::CmpOp(..) | BinaryOp::Assignment { .. })
+                    && let TyKind::Ref(mtbl, lt, _) = p_left.kind(Interner)
+                {
+                    self.write_expr_adj(
+                        lhs,
+                        Box::new([Adjustment {
+                            kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
+                            target: p_left.clone(),
+                        }]),
+                    );
                 }
                 let p_right = &sig.params()[1];
-                if matches!(op, BinaryOp::CmpOp(..)) {
-                    if let TyKind::Ref(mtbl, lt, _) = p_right.kind(Interner) {
-                        self.write_expr_adj(
-                            rhs,
-                            Box::new([Adjustment {
-                                kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
-                                target: p_right.clone(),
-                            }]),
-                        );
-                    }
+                if matches!(op, BinaryOp::CmpOp(..))
+                    && let TyKind::Ref(mtbl, lt, _) = p_right.kind(Interner)
+                {
+                    self.write_expr_adj(
+                        rhs,
+                        Box::new([Adjustment {
+                            kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
+                            target: p_right.clone(),
+                        }]),
+                    );
                 }
                 sig.ret().clone()
             }
@@ -1664,14 +1663,12 @@ impl InferenceContext<'_> {
             Some((ty, field_id, adjustments, is_public)) => {
                 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
                 self.result.field_resolutions.insert(tgt_expr, field_id);
-                if !is_public {
-                    if let Either::Left(field) = field_id {
-                        // FIXME: Merge this diagnostic into UnresolvedField?
-                        self.push_diagnostic(InferenceDiagnostic::PrivateField {
-                            expr: tgt_expr,
-                            field,
-                        });
-                    }
+                if !is_public && let Either::Left(field) = field_id {
+                    // FIXME: Merge this diagnostic into UnresolvedField?
+                    self.push_diagnostic(InferenceDiagnostic::PrivateField {
+                        expr: tgt_expr,
+                        field,
+                    });
                 }
                 ty
             }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
index 3f7eba9dd18..c798e9e050a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
@@ -124,53 +124,41 @@ impl InferenceContext<'_> {
                 self.infer_mut_not_expr_iter(fields.iter().map(|it| it.expr).chain(*spread))
             }
             &Expr::Index { base, index } => {
-                if mutability == Mutability::Mut {
-                    if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
-                        if let Some(index_trait) =
-                            LangItem::IndexMut.resolve_trait(self.db, self.table.trait_env.krate)
-                        {
-                            if let Some(index_fn) = index_trait
-                                .trait_items(self.db)
-                                .method_by_name(&Name::new_symbol_root(sym::index_mut))
-                            {
-                                *f = index_fn;
-                                let mut base_ty = None;
-                                let base_adjustments = self
-                                    .result
-                                    .expr_adjustments
-                                    .get_mut(&base)
-                                    .and_then(|it| it.last_mut());
-                                if let Some(Adjustment {
-                                    kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)),
-                                    target,
-                                }) = base_adjustments
-                                {
-                                    if let TyKind::Ref(_, _, ty) = target.kind(Interner) {
-                                        base_ty = Some(ty.clone());
-                                    }
-                                    *mutability = Mutability::Mut;
-                                }
-
-                                // Apply `IndexMut` obligation for non-assignee expr
-                                if let Some(base_ty) = base_ty {
-                                    let index_ty =
-                                        if let Some(ty) = self.result.type_of_expr.get(index) {
-                                            ty.clone()
-                                        } else {
-                                            self.infer_expr(
-                                                index,
-                                                &Expectation::none(),
-                                                ExprIsRead::Yes,
-                                            )
-                                        };
-                                    let trait_ref = TyBuilder::trait_ref(self.db, index_trait)
-                                        .push(base_ty)
-                                        .fill(|_| index_ty.clone().cast(Interner))
-                                        .build();
-                                    self.push_obligation(trait_ref.cast(Interner));
-                                }
-                            }
+                if mutability == Mutability::Mut
+                    && let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr)
+                    && let Some(index_trait) =
+                        LangItem::IndexMut.resolve_trait(self.db, self.table.trait_env.krate)
+                    && let Some(index_fn) = index_trait
+                        .trait_items(self.db)
+                        .method_by_name(&Name::new_symbol_root(sym::index_mut))
+                {
+                    *f = index_fn;
+                    let mut base_ty = None;
+                    let base_adjustments =
+                        self.result.expr_adjustments.get_mut(&base).and_then(|it| it.last_mut());
+                    if let Some(Adjustment {
+                        kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)),
+                        target,
+                    }) = base_adjustments
+                    {
+                        if let TyKind::Ref(_, _, ty) = target.kind(Interner) {
+                            base_ty = Some(ty.clone());
                         }
+                        *mutability = Mutability::Mut;
+                    }
+
+                    // Apply `IndexMut` obligation for non-assignee expr
+                    if let Some(base_ty) = base_ty {
+                        let index_ty = if let Some(ty) = self.result.type_of_expr.get(index) {
+                            ty.clone()
+                        } else {
+                            self.infer_expr(index, &Expectation::none(), ExprIsRead::Yes)
+                        };
+                        let trait_ref = TyBuilder::trait_ref(self.db, index_trait)
+                            .push(base_ty)
+                            .fill(|_| index_ty.clone().cast(Interner))
+                            .build();
+                        self.push_obligation(trait_ref.cast(Interner));
                     }
                 }
                 self.infer_mut_expr(base, mutability);
@@ -178,28 +166,23 @@ impl InferenceContext<'_> {
             }
             Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
                 let mut mutability = mutability;
-                if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
-                    if mutability == Mutability::Mut {
-                        if let Some(deref_trait) =
-                            LangItem::DerefMut.resolve_trait(self.db, self.table.trait_env.krate)
-                        {
-                            let ty = self.result.type_of_expr.get(*expr);
-                            let is_mut_ptr = ty.is_some_and(|ty| {
-                                let ty = self.table.resolve_ty_shallow(ty);
-                                matches!(
-                                    ty.kind(Interner),
-                                    chalk_ir::TyKind::Raw(Mutability::Mut, _)
-                                )
-                            });
-                            if is_mut_ptr {
-                                mutability = Mutability::Not;
-                            } else if let Some(deref_fn) = deref_trait
-                                .trait_items(self.db)
-                                .method_by_name(&Name::new_symbol_root(sym::deref_mut))
-                            {
-                                *f = deref_fn;
-                            }
-                        }
+                if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr)
+                    && mutability == Mutability::Mut
+                    && let Some(deref_trait) =
+                        LangItem::DerefMut.resolve_trait(self.db, self.table.trait_env.krate)
+                {
+                    let ty = self.result.type_of_expr.get(*expr);
+                    let is_mut_ptr = ty.is_some_and(|ty| {
+                        let ty = self.table.resolve_ty_shallow(ty);
+                        matches!(ty.kind(Interner), chalk_ir::TyKind::Raw(Mutability::Mut, _))
+                    });
+                    if is_mut_ptr {
+                        mutability = Mutability::Not;
+                    } else if let Some(deref_fn) = deref_trait
+                        .trait_items(self.db)
+                        .method_by_name(&Name::new_symbol_root(sym::deref_mut))
+                    {
+                        *f = deref_fn;
                     }
                 }
                 self.infer_mut_expr(*expr, mutability);
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 18288b718f7..707bec0fce4 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
@@ -498,12 +498,12 @@ impl InferenceContext<'_> {
 
         // 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) =
+        if self.pat_is_irrefutable(decl)
+            && expected.is_ty_var()
+            && let Some(resolved_array_ty) =
                 self.try_resolve_slice_ty_to_array_ty(prefix, suffix, slice)
-            {
-                self.unify(&expected, &resolved_array_ty);
-            }
+        {
+            self.unify(&expected, &resolved_array_ty);
         }
 
         let expected = self.resolve_ty_shallow(&expected);
@@ -539,17 +539,16 @@ impl InferenceContext<'_> {
 
     fn infer_lit_pat(&mut self, expr: ExprId, expected: &Ty) -> Ty {
         // Like slice patterns, byte string patterns can denote both `&[u8; N]` and `&[u8]`.
-        if let Expr::Literal(Literal::ByteString(_)) = self.body[expr] {
-            if let Some((inner, ..)) = expected.as_reference() {
-                let inner = self.resolve_ty_shallow(inner);
-                if matches!(inner.kind(Interner), TyKind::Slice(_)) {
-                    let elem_ty = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner);
-                    let slice_ty = TyKind::Slice(elem_ty).intern(Interner);
-                    let ty =
-                        TyKind::Ref(Mutability::Not, static_lifetime(), slice_ty).intern(Interner);
-                    self.write_expr_ty(expr, ty.clone());
-                    return ty;
-                }
+        if let Expr::Literal(Literal::ByteString(_)) = self.body[expr]
+            && let Some((inner, ..)) = expected.as_reference()
+        {
+            let inner = self.resolve_ty_shallow(inner);
+            if matches!(inner.kind(Interner), TyKind::Slice(_)) {
+                let elem_ty = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner);
+                let slice_ty = TyKind::Slice(elem_ty).intern(Interner);
+                let ty = TyKind::Ref(Mutability::Not, static_lifetime(), slice_ty).intern(Interner);
+                self.write_expr_ty(expr, ty.clone());
+                return ty;
             }
         }
 
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 d61e7de6672..afee9606bd5 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -830,10 +830,10 @@ fn named_associated_type_shorthand_candidates<R>(
             let data = t.hir_trait_id().trait_items(db);
 
             for (name, assoc_id) in &data.items {
-                if let AssocItemId::TypeAliasId(alias) = assoc_id {
-                    if let Some(result) = cb(name, &t, *alias) {
-                        return Some(result);
-                    }
+                if let AssocItemId::TypeAliasId(alias) = assoc_id
+                    && let Some(result) = cb(name, &t, *alias)
+                {
+                    return Some(result);
                 }
             }
             None
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs
index 5c06234fa07..9519c38eedd 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs
@@ -360,15 +360,14 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
             }
         }
 
-        if let Some(enum_segment) = enum_segment {
-            if segments.get(enum_segment).is_some_and(|it| it.args_and_bindings.is_some())
-                && segments.get(enum_segment + 1).is_some_and(|it| it.args_and_bindings.is_some())
-            {
-                self.on_diagnostic(PathLoweringDiagnostic::GenericArgsProhibited {
-                    segment: (enum_segment + 1) as u32,
-                    reason: GenericArgsProhibitedReason::EnumVariant,
-                });
-            }
+        if let Some(enum_segment) = enum_segment
+            && segments.get(enum_segment).is_some_and(|it| it.args_and_bindings.is_some())
+            && segments.get(enum_segment + 1).is_some_and(|it| it.args_and_bindings.is_some())
+        {
+            self.on_diagnostic(PathLoweringDiagnostic::GenericArgsProhibited {
+                segment: (enum_segment + 1) as u32,
+                reason: GenericArgsProhibitedReason::EnumVariant,
+            });
         }
 
         self.handle_type_ns_resolution(&resolution);
@@ -417,15 +416,14 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
             }
         }
 
-        if let Some(enum_segment) = enum_segment {
-            if segments.get(enum_segment).is_some_and(|it| it.args_and_bindings.is_some())
-                && segments.get(enum_segment + 1).is_some_and(|it| it.args_and_bindings.is_some())
-            {
-                self.on_diagnostic(PathLoweringDiagnostic::GenericArgsProhibited {
-                    segment: (enum_segment + 1) as u32,
-                    reason: GenericArgsProhibitedReason::EnumVariant,
-                });
-            }
+        if let Some(enum_segment) = enum_segment
+            && segments.get(enum_segment).is_some_and(|it| it.args_and_bindings.is_some())
+            && segments.get(enum_segment + 1).is_some_and(|it| it.args_and_bindings.is_some())
+        {
+            self.on_diagnostic(PathLoweringDiagnostic::GenericArgsProhibited {
+                segment: (enum_segment + 1) as u32,
+                reason: GenericArgsProhibitedReason::EnumVariant,
+            });
         }
 
         match &res {
@@ -576,13 +574,12 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
                 // This simplifies the code a bit.
                 let penultimate_idx = self.current_segment_idx.wrapping_sub(1);
                 let penultimate = self.segments.get(penultimate_idx);
-                if let Some(penultimate) = penultimate {
-                    if self.current_or_prev_segment.args_and_bindings.is_none()
-                        && penultimate.args_and_bindings.is_some()
-                    {
-                        self.current_segment_idx = penultimate_idx;
-                        self.current_or_prev_segment = penultimate;
-                    }
+                if let Some(penultimate) = penultimate
+                    && self.current_or_prev_segment.args_and_bindings.is_none()
+                    && penultimate.args_and_bindings.is_some()
+                {
+                    self.current_segment_idx = penultimate_idx;
+                    self.current_or_prev_segment = penultimate;
                 }
                 var.lookup(self.ctx.db).parent.into()
             }
@@ -607,37 +604,36 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
     ) -> Substitution {
         let mut lifetime_elision = self.ctx.lifetime_elision.clone();
 
-        if let Some(args) = self.current_or_prev_segment.args_and_bindings {
-            if args.parenthesized != GenericArgsParentheses::No {
-                let prohibit_parens = match def {
-                    GenericDefId::TraitId(trait_) => {
-                        // RTN is prohibited anyways if we got here.
-                        let is_rtn =
-                            args.parenthesized == GenericArgsParentheses::ReturnTypeNotation;
-                        let is_fn_trait = self
-                            .ctx
-                            .db
-                            .trait_signature(trait_)
-                            .flags
-                            .contains(TraitFlags::RUSTC_PAREN_SUGAR);
-                        is_rtn || !is_fn_trait
-                    }
-                    _ => true,
-                };
-
-                if prohibit_parens {
-                    let segment = self.current_segment_u32();
-                    self.on_diagnostic(
-                        PathLoweringDiagnostic::ParenthesizedGenericArgsWithoutFnTrait { segment },
-                    );
-
-                    return TyBuilder::unknown_subst(self.ctx.db, def);
+        if let Some(args) = self.current_or_prev_segment.args_and_bindings
+            && args.parenthesized != GenericArgsParentheses::No
+        {
+            let prohibit_parens = match def {
+                GenericDefId::TraitId(trait_) => {
+                    // RTN is prohibited anyways if we got here.
+                    let is_rtn = args.parenthesized == GenericArgsParentheses::ReturnTypeNotation;
+                    let is_fn_trait = self
+                        .ctx
+                        .db
+                        .trait_signature(trait_)
+                        .flags
+                        .contains(TraitFlags::RUSTC_PAREN_SUGAR);
+                    is_rtn || !is_fn_trait
                 }
+                _ => true,
+            };
 
-                // `Fn()`-style generics are treated like functions for the purpose of lifetime elision.
-                lifetime_elision =
-                    LifetimeElisionKind::AnonymousCreateParameter { report_in_path: false };
+            if prohibit_parens {
+                let segment = self.current_segment_u32();
+                self.on_diagnostic(
+                    PathLoweringDiagnostic::ParenthesizedGenericArgsWithoutFnTrait { segment },
+                );
+
+                return TyBuilder::unknown_subst(self.ctx.db, def);
             }
+
+            // `Fn()`-style generics are treated like functions for the purpose of lifetime elision.
+            lifetime_elision =
+                LifetimeElisionKind::AnonymousCreateParameter { report_in_path: false };
         }
 
         self.substs_from_args_and_bindings(
@@ -753,18 +749,20 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
                 match param {
                     GenericParamDataRef::LifetimeParamData(_) => error_lifetime().cast(Interner),
                     GenericParamDataRef::TypeParamData(param) => {
-                        if !infer_args && param.default.is_some() {
-                            if let Some(default) = default() {
-                                return default;
-                            }
+                        if !infer_args
+                            && param.default.is_some()
+                            && let Some(default) = default()
+                        {
+                            return default;
                         }
                         TyKind::Error.intern(Interner).cast(Interner)
                     }
                     GenericParamDataRef::ConstParamData(param) => {
-                        if !infer_args && param.default.is_some() {
-                            if let Some(default) = default() {
-                                return default;
-                            }
+                        if !infer_args
+                            && param.default.is_some()
+                            && let Some(default) = default()
+                        {
+                            return default;
                         }
                         let GenericParamId::ConstParamId(const_id) = param_id else {
                             unreachable!("non-const param ID for const param");
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 a6150a9bc17..b22781e9470 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
@@ -581,15 +581,15 @@ impl ReceiverAdjustments {
         }
         if self.unsize_array {
             ty = 'it: {
-                if let TyKind::Ref(m, l, inner) = ty.kind(Interner) {
-                    if let TyKind::Array(inner, _) = inner.kind(Interner) {
-                        break 'it TyKind::Ref(
-                            *m,
-                            l.clone(),
-                            TyKind::Slice(inner.clone()).intern(Interner),
-                        )
-                        .intern(Interner);
-                    }
+                if let TyKind::Ref(m, l, inner) = ty.kind(Interner)
+                    && let TyKind::Array(inner, _) = inner.kind(Interner)
+                {
+                    break 'it TyKind::Ref(
+                        *m,
+                        l.clone(),
+                        TyKind::Slice(inner.clone()).intern(Interner),
+                    )
+                    .intern(Interner);
                 }
                 // FIXME: report diagnostic if array unsizing happens without indirection.
                 ty
@@ -1549,11 +1549,11 @@ fn is_valid_impl_method_candidate(
             check_that!(receiver_ty.is_none());
             check_that!(name.is_none_or(|n| n == item_name));
 
-            if let Some(from_module) = visible_from_module {
-                if !db.assoc_visibility(c.into()).is_visible_from(db, from_module) {
-                    cov_mark::hit!(const_candidate_not_visible);
-                    return IsValidCandidate::NotVisible;
-                }
+            if let Some(from_module) = visible_from_module
+                && !db.assoc_visibility(c.into()).is_visible_from(db, from_module)
+            {
+                cov_mark::hit!(const_candidate_not_visible);
+                return IsValidCandidate::NotVisible;
             }
             let self_ty_matches = table.run_in_snapshot(|table| {
                 let expected_self_ty =
@@ -1638,11 +1638,11 @@ fn is_valid_impl_fn_candidate(
     let db = table.db;
     let data = db.function_signature(fn_id);
 
-    if let Some(from_module) = visible_from_module {
-        if !db.assoc_visibility(fn_id.into()).is_visible_from(db, from_module) {
-            cov_mark::hit!(autoderef_candidate_not_visible);
-            return IsValidCandidate::NotVisible;
-        }
+    if let Some(from_module) = visible_from_module
+        && !db.assoc_visibility(fn_id.into()).is_visible_from(db, from_module)
+    {
+        cov_mark::hit!(autoderef_candidate_not_visible);
+        return IsValidCandidate::NotVisible;
     }
     table.run_in_snapshot(|table| {
         let _p = tracing::info_span!("subst_for_def").entered();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
index fb0c0dee095..52df851c30d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
@@ -559,10 +559,9 @@ fn mutability_of_locals(
                         },
                         p,
                     ) = value
+                        && place_case(db, body, p) != ProjectionCase::Indirect
                     {
-                        if place_case(db, body, p) != ProjectionCase::Indirect {
-                            push_mut_span(p.local, statement.span, &mut result);
-                        }
+                        push_mut_span(p.local, statement.span, &mut result);
                     }
                 }
                 StatementKind::FakeRead(p) => {
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 9a97bd6dbe2..dfb8ae704b9 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
@@ -1082,18 +1082,18 @@ impl Evaluator<'_> {
         let stack_size = {
             let mut stack_ptr = self.stack.len();
             for (id, it) in body.locals.iter() {
-                if id == return_slot() {
-                    if let Some(destination) = destination {
-                        locals.ptr.insert(id, destination);
-                        continue;
-                    }
+                if id == return_slot()
+                    && let Some(destination) = destination
+                {
+                    locals.ptr.insert(id, destination);
+                    continue;
                 }
                 let (size, align) = self.size_align_of_sized(
                     &it.ty,
                     &locals,
                     "no unsized local in extending stack",
                 )?;
-                while stack_ptr % align != 0 {
+                while !stack_ptr.is_multiple_of(align) {
                     stack_ptr += 1;
                 }
                 let my_ptr = stack_ptr;
@@ -1673,14 +1673,14 @@ impl Evaluator<'_> {
         if let Some(it) = goal(kind) {
             return Ok(it);
         }
-        if let TyKind::Adt(id, subst) = kind {
-            if let AdtId::StructId(struct_id) = id.0 {
-                let field_types = self.db.field_types(struct_id.into());
-                if let Some(ty) =
-                    field_types.iter().last().map(|it| it.1.clone().substitute(Interner, subst))
-                {
-                    return self.coerce_unsized_look_through_fields(&ty, goal);
-                }
+        if let TyKind::Adt(id, subst) = kind
+            && let AdtId::StructId(struct_id) = id.0
+        {
+            let field_types = self.db.field_types(struct_id.into());
+            if let Some(ty) =
+                field_types.iter().last().map(|it| it.1.clone().substitute(Interner, subst))
+            {
+                return self.coerce_unsized_look_through_fields(&ty, goal);
             }
         }
         Err(MirEvalError::CoerceUnsizedError(ty.clone()))
@@ -1778,17 +1778,15 @@ impl Evaluator<'_> {
         locals: &Locals,
     ) -> Result<(usize, Arc<Layout>, Option<(usize, usize, i128)>)> {
         let adt = it.adt_id(self.db);
-        if let DefWithBodyId::VariantId(f) = locals.body.owner {
-            if let VariantId::EnumVariantId(it) = it {
-                if let AdtId::EnumId(e) = adt {
-                    if f.lookup(self.db).parent == e {
-                        // Computing the exact size of enums require resolving the enum discriminants. In order to prevent loops (and
-                        // infinite sized type errors) we use a dummy layout
-                        let i = self.const_eval_discriminant(it)?;
-                        return Ok((16, self.layout(&TyBuilder::unit())?, Some((0, 16, i))));
-                    }
-                }
-            }
+        if let DefWithBodyId::VariantId(f) = locals.body.owner
+            && let VariantId::EnumVariantId(it) = it
+            && let AdtId::EnumId(e) = adt
+            && f.lookup(self.db).parent == e
+        {
+            // Computing the exact size of enums require resolving the enum discriminants. In order to prevent loops (and
+            // infinite sized type errors) we use a dummy layout
+            let i = self.const_eval_discriminant(it)?;
+            return Ok((16, self.layout(&TyBuilder::unit())?, Some((0, 16, i))));
         }
         let layout = self.layout_adt(adt, subst)?;
         Ok(match &layout.variants {
@@ -1909,10 +1907,10 @@ impl Evaluator<'_> {
                         let name = const_id.name(self.db);
                         MirEvalError::ConstEvalError(name, Box::new(e))
                     })?;
-                if let chalk_ir::ConstValue::Concrete(c) = &result_owner.data(Interner).value {
-                    if let ConstScalar::Bytes(v, mm) = &c.interned {
-                        break 'b (v, mm);
-                    }
+                if let chalk_ir::ConstValue::Concrete(c) = &result_owner.data(Interner).value
+                    && let ConstScalar::Bytes(v, mm) = &c.interned
+                {
+                    break 'b (v, mm);
                 }
                 not_supported!("unevaluatable constant");
             }
@@ -2055,14 +2053,13 @@ impl Evaluator<'_> {
                 .is_sized()
                 .then(|| (layout.size.bytes_usize(), layout.align.abi.bytes() as usize)));
         }
-        if let DefWithBodyId::VariantId(f) = locals.body.owner {
-            if let Some((AdtId::EnumId(e), _)) = ty.as_adt() {
-                if f.lookup(self.db).parent == e {
-                    // Computing the exact size of enums require resolving the enum discriminants. In order to prevent loops (and
-                    // infinite sized type errors) we use a dummy size
-                    return Ok(Some((16, 16)));
-                }
-            }
+        if let DefWithBodyId::VariantId(f) = locals.body.owner
+            && let Some((AdtId::EnumId(e), _)) = ty.as_adt()
+            && f.lookup(self.db).parent == e
+        {
+            // Computing the exact size of enums require resolving the enum discriminants. In order to prevent loops (and
+            // infinite sized type errors) we use a dummy size
+            return Ok(Some((16, 16)));
         }
         let layout = self.layout(ty);
         if self.assert_placeholder_ty_is_unused
@@ -2103,7 +2100,7 @@ impl Evaluator<'_> {
         if !align.is_power_of_two() || align > 10000 {
             return Err(MirEvalError::UndefinedBehavior(format!("Alignment {align} is invalid")));
         }
-        while self.heap.len() % align != 0 {
+        while !self.heap.len().is_multiple_of(align) {
             self.heap.push(0);
         }
         if size.checked_add(self.heap.len()).is_none_or(|x| x > self.memory_limit) {
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 e9665d5ae9c..bb4c963a8ae 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
@@ -119,25 +119,25 @@ impl Evaluator<'_> {
             destination.write_from_bytes(self, &result)?;
             return Ok(true);
         }
-        if let ItemContainerId::TraitId(t) = def.lookup(self.db).container {
-            if self.db.lang_attr(t.into()) == Some(LangItem::Clone) {
-                let [self_ty] = generic_args.as_slice(Interner) else {
-                    not_supported!("wrong generic arg count for clone");
-                };
-                let Some(self_ty) = self_ty.ty(Interner) else {
-                    not_supported!("wrong generic arg kind for clone");
-                };
-                // Clone has special impls for tuples and function pointers
-                if matches!(
-                    self_ty.kind(Interner),
-                    TyKind::Function(_) | TyKind::Tuple(..) | TyKind::Closure(..)
-                ) {
-                    self.exec_clone(def, args, self_ty.clone(), locals, destination, span)?;
-                    return Ok(true);
-                }
-                // Return early to prevent caching clone as non special fn.
-                return Ok(false);
+        if let ItemContainerId::TraitId(t) = def.lookup(self.db).container
+            && self.db.lang_attr(t.into()) == Some(LangItem::Clone)
+        {
+            let [self_ty] = generic_args.as_slice(Interner) else {
+                not_supported!("wrong generic arg count for clone");
+            };
+            let Some(self_ty) = self_ty.ty(Interner) else {
+                not_supported!("wrong generic arg kind for clone");
+            };
+            // Clone has special impls for tuples and function pointers
+            if matches!(
+                self_ty.kind(Interner),
+                TyKind::Function(_) | TyKind::Tuple(..) | TyKind::Closure(..)
+            ) {
+                self.exec_clone(def, args, self_ty.clone(), locals, destination, span)?;
+                return Ok(true);
             }
+            // Return early to prevent caching clone as non special fn.
+            return Ok(false);
         }
         self.not_special_fn_cache.borrow_mut().insert(def);
         Ok(false)
@@ -1256,23 +1256,22 @@ impl Evaluator<'_> {
                     let addr = tuple.interval.addr.offset(offset);
                     args.push(IntervalAndTy::new(addr, field, self, locals)?);
                 }
-                if let Some(target) = LangItem::FnOnce.resolve_trait(self.db, self.crate_id) {
-                    if let Some(def) = target
+                if let Some(target) = LangItem::FnOnce.resolve_trait(self.db, self.crate_id)
+                    && let Some(def) = target
                         .trait_items(self.db)
                         .method_by_name(&Name::new_symbol_root(sym::call_once))
-                    {
-                        self.exec_fn_trait(
-                            def,
-                            &args,
-                            // FIXME: wrong for manual impls of `FnOnce`
-                            Substitution::empty(Interner),
-                            locals,
-                            destination,
-                            None,
-                            span,
-                        )?;
-                        return Ok(true);
-                    }
+                {
+                    self.exec_fn_trait(
+                        def,
+                        &args,
+                        // FIXME: wrong for manual impls of `FnOnce`
+                        Substitution::empty(Interner),
+                        locals,
+                        destination,
+                        None,
+                        span,
+                    )?;
+                    return Ok(true);
                 }
                 not_supported!("FnOnce was not available for executing const_eval_select");
             }
@@ -1367,12 +1366,11 @@ impl Evaluator<'_> {
                         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 signed
+                    && let Some((&l, &r)) = lhs.iter().zip(rhs).next_back()
+                    && l != r
+                {
+                    result = (l as i8).cmp(&(r as i8));
                 }
                 if let Some(e) = LangItem::Ordering.resolve_enum(self.db, self.crate_id) {
                     let ty = self.db.ty(e.into());
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
index bc331a23d98..f5547729045 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
@@ -114,12 +114,11 @@ impl Evaluator<'_> {
                             break;
                         }
                     }
-                    if is_signed {
-                        if let Some((&l, &r)) = l.iter().zip(r).next_back() {
-                            if l != r {
-                                result = (l as i8).cmp(&(r as i8));
-                            }
-                        }
+                    if is_signed
+                        && let Some((&l, &r)) = l.iter().zip(r).next_back()
+                        && l != r
+                    {
+                        result = (l as i8).cmp(&(r as i8));
                     }
                     let result = match result {
                         Ordering::Less => ["lt", "le", "ne"].contains(&name),
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 07d81472729..eb80e8706fa 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
@@ -320,11 +320,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
         expr_id: ExprId,
         current: BasicBlockId,
     ) -> Result<Option<(Operand, BasicBlockId)>> {
-        if !self.has_adjustments(expr_id) {
-            if let Expr::Literal(l) = &self.body[expr_id] {
-                let ty = self.expr_ty_without_adjust(expr_id);
-                return Ok(Some((self.lower_literal_to_operand(ty, l)?, current)));
-            }
+        if !self.has_adjustments(expr_id)
+            && let Expr::Literal(l) = &self.body[expr_id]
+        {
+            let ty = self.expr_ty_without_adjust(expr_id);
+            return Ok(Some((self.lower_literal_to_operand(ty, l)?, current)));
         }
         let Some((p, current)) = self.lower_expr_as_place(current, expr_id, true)? else {
             return Ok(None);
@@ -1039,18 +1039,18 @@ impl<'ctx> MirLowerCtx<'ctx> {
                         && rhs_ty.is_scalar()
                         && (lhs_ty == rhs_ty || builtin_inequal_impls)
                 };
-                if !is_builtin {
-                    if let Some((func_id, generic_args)) = self.infer.method_resolution(expr_id) {
-                        let func = Operand::from_fn(self.db, func_id, generic_args);
-                        return self.lower_call_and_args(
-                            func,
-                            [*lhs, *rhs].into_iter(),
-                            place,
-                            current,
-                            self.is_uninhabited(expr_id),
-                            expr_id.into(),
-                        );
-                    }
+                if !is_builtin
+                    && let Some((func_id, generic_args)) = self.infer.method_resolution(expr_id)
+                {
+                    let func = Operand::from_fn(self.db, func_id, generic_args);
+                    return self.lower_call_and_args(
+                        func,
+                        [*lhs, *rhs].into_iter(),
+                        place,
+                        current,
+                        self.is_uninhabited(expr_id),
+                        expr_id.into(),
+                    );
                 }
                 if let hir_def::hir::BinaryOp::Assignment { op: Some(op) } = op {
                     // last adjustment is `&mut` which we don't want it.
@@ -1596,10 +1596,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
 
     fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty {
         let mut ty = None;
-        if let Some(it) = self.infer.expr_adjustments.get(&e) {
-            if let Some(it) = it.last() {
-                ty = Some(it.target.clone());
-            }
+        if let Some(it) = self.infer.expr_adjustments.get(&e)
+            && let Some(it) = it.last()
+        {
+            ty = Some(it.target.clone());
         }
         ty.unwrap_or_else(|| self.expr_ty_without_adjust(e))
     }
@@ -1848,13 +1848,13 @@ impl<'ctx> MirLowerCtx<'ctx> {
         self.result.param_locals.extend(params.clone().map(|(it, ty)| {
             let local_id = self.result.locals.alloc(Local { ty });
             self.drop_scopes.last_mut().unwrap().locals.push(local_id);
-            if let Pat::Bind { id, subpat: None } = self.body[it] {
-                if matches!(
+            if let Pat::Bind { id, subpat: None } = self.body[it]
+                && matches!(
                     self.body[id].mode,
                     BindingAnnotation::Unannotated | BindingAnnotation::Mutable
-                ) {
-                    self.result.binding_locals.insert(id, local_id);
-                }
+                )
+            {
+                self.result.binding_locals.insert(id, local_id);
             }
             local_id
         }));
@@ -1887,10 +1887,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
             .into_iter()
             .skip(base_param_count + self_binding.is_some() as usize);
         for ((param, _), local) in params.zip(local_params) {
-            if let Pat::Bind { id, .. } = self.body[param] {
-                if local == self.binding_local(id)? {
-                    continue;
-                }
+            if let Pat::Bind { id, .. } = self.body[param]
+                && local == self.binding_local(id)?
+            {
+                continue;
             }
             let r = self.pattern_match(current, None, local.into(), param)?;
             if let Some(b) = r.1 {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
index e074c2d558e..42a14664626 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
@@ -189,17 +189,14 @@ impl MirLowerCtx<'_> {
                         self.expr_ty_without_adjust(expr_id),
                         expr_id.into(),
                         'b: {
-                            if let Some((f, _)) = self.infer.method_resolution(expr_id) {
-                                if let Some(deref_trait) =
+                            if let Some((f, _)) = self.infer.method_resolution(expr_id)
+                                && let Some(deref_trait) =
                                     self.resolve_lang_item(LangItem::DerefMut)?.as_trait()
-                                {
-                                    if let Some(deref_fn) = deref_trait
-                                        .trait_items(self.db)
-                                        .method_by_name(&Name::new_symbol_root(sym::deref_mut))
-                                    {
-                                        break 'b deref_fn == f;
-                                    }
-                                }
+                                && let Some(deref_fn) = deref_trait
+                                    .trait_items(self.db)
+                                    .method_by_name(&Name::new_symbol_root(sym::deref_mut))
+                            {
+                                break 'b deref_fn == f;
                             }
                             false
                         },
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
index 3325226b1d3..0440d850223 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
@@ -317,27 +317,26 @@ impl MirLowerCtx<'_> {
                     (current, current_else) =
                         self.pattern_match_inner(current, current_else, next_place, pat, mode)?;
                 }
-                if let &Some(slice) = slice {
-                    if mode != MatchingMode::Check {
-                        if let Pat::Bind { id, subpat: _ } = self.body[slice] {
-                            let next_place = cond_place.project(
-                                ProjectionElem::Subslice {
-                                    from: prefix.len() as u64,
-                                    to: suffix.len() as u64,
-                                },
-                                &mut self.result.projection_store,
-                            );
-                            let mode = self.infer.binding_modes[slice];
-                            (current, current_else) = self.pattern_match_binding(
-                                id,
-                                mode,
-                                next_place,
-                                (slice).into(),
-                                current,
-                                current_else,
-                            )?;
-                        }
-                    }
+                if let &Some(slice) = slice
+                    && mode != MatchingMode::Check
+                    && let Pat::Bind { id, subpat: _ } = self.body[slice]
+                {
+                    let next_place = cond_place.project(
+                        ProjectionElem::Subslice {
+                            from: prefix.len() as u64,
+                            to: suffix.len() as u64,
+                        },
+                        &mut self.result.projection_store,
+                    );
+                    let mode = self.infer.binding_modes[slice];
+                    (current, current_else) = self.pattern_match_binding(
+                        id,
+                        mode,
+                        next_place,
+                        (slice).into(),
+                        current,
+                        current_else,
+                    )?;
                 }
                 for (i, &pat) in suffix.iter().enumerate() {
                     let next_place = cond_place.project(
@@ -391,10 +390,10 @@ impl MirLowerCtx<'_> {
                         return Ok((current, current_else));
                     }
                     let (c, subst) = 'b: {
-                        if let Some(x) = self.infer.assoc_resolutions_for_pat(pattern) {
-                            if let AssocItemId::ConstId(c) = x.0 {
-                                break 'b (c, x.1);
-                            }
+                        if let Some(x) = self.infer.assoc_resolutions_for_pat(pattern)
+                            && let AssocItemId::ConstId(c) = x.0
+                        {
+                            break 'b (c, x.1);
                         }
                         if let ResolveValueResult::ValueNs(ValueNs::ConstId(c), _) = pr {
                             break 'b (c, Substitution::empty(Interner));
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
index b5de0e52f5b..775136dc0cb 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
@@ -149,7 +149,7 @@ impl TestDB {
             .into_iter()
             .filter_map(|file_id| {
                 let text = self.file_text(file_id.file_id(self));
-                let annotations = extract_annotations(&text.text(self));
+                let annotations = extract_annotations(text.text(self));
                 if annotations.is_empty() {
                     return None;
                 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs
index 7414b4fc607..08b9d242e71 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs
@@ -125,11 +125,10 @@ pub(crate) fn trait_solve_query(
         alias: AliasTy::Projection(projection_ty),
         ..
     }))) = &goal.value.goal.data(Interner)
+        && let TyKind::BoundVar(_) = projection_ty.self_type_parameter(db).kind(Interner)
     {
-        if let TyKind::BoundVar(_) = projection_ty.self_type_parameter(db).kind(Interner) {
-            // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
-            return Some(Solution::Ambig(Guidance::Unknown));
-        }
+        // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
+        return Some(Solution::Ambig(Guidance::Unknown));
     }
 
     // Chalk see `UnevaluatedConst` as a unique concrete value, but we see it as an alias for another const. So
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 d07c1aa33b4..209ec7926e8 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -333,13 +333,13 @@ impl FallibleTypeFolder<Interner> for UnevaluatedConstEvaluatorFolder<'_> {
         constant: Const,
         _outer_binder: DebruijnIndex,
     ) -> Result<Const, Self::Error> {
-        if let chalk_ir::ConstValue::Concrete(c) = &constant.data(Interner).value {
-            if let ConstScalar::UnevaluatedConst(id, subst) = &c.interned {
-                if let Ok(eval) = self.db.const_eval(*id, subst.clone(), None) {
-                    return Ok(eval);
-                } else {
-                    return Ok(unknown_const(constant.data(Interner).ty.clone()));
-                }
+        if let chalk_ir::ConstValue::Concrete(c) = &constant.data(Interner).value
+            && let ConstScalar::UnevaluatedConst(id, subst) = &c.interned
+        {
+            if let Ok(eval) = self.db.const_eval(*id, subst.clone(), None) {
+                return Ok(eval);
+            } else {
+                return Ok(unknown_const(constant.data(Interner).ty.clone()));
             }
         }
         Ok(constant)
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
index c1e814ec223..fca0162765e 100644
--- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -604,13 +604,13 @@ impl<'db> AnyDiagnostic<'db> {
                 }
             }
             BodyValidationDiagnostic::RemoveUnnecessaryElse { if_expr } => {
-                if let Ok(source_ptr) = source_map.expr_syntax(if_expr) {
-                    if let Some(ptr) = source_ptr.value.cast::<ast::IfExpr>() {
-                        return Some(
-                            RemoveUnnecessaryElse { if_expr: InFile::new(source_ptr.file_id, ptr) }
-                                .into(),
-                        );
-                    }
+                if let Ok(source_ptr) = source_map.expr_syntax(if_expr)
+                    && let Some(ptr) = source_ptr.value.cast::<ast::IfExpr>()
+                {
+                    return Some(
+                        RemoveUnnecessaryElse { if_expr: InFile::new(source_ptr.file_id, ptr) }
+                            .into(),
+                    );
                 }
             }
         }
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 4ddb04b24f7..a323f97997c 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -1020,21 +1020,21 @@ fn emit_macro_def_diagnostics<'db>(
     m: Macro,
 ) {
     let id = db.macro_def(m.id);
-    if let hir_expand::db::TokenExpander::DeclarativeMacro(expander) = db.macro_expander(id) {
-        if let Some(e) = expander.mac.err() {
-            let Some(ast) = id.ast_id().left() else {
-                never!("declarative expander for non decl-macro: {:?}", e);
-                return;
-            };
-            let krate = HasModule::krate(&m.id, db);
-            let edition = krate.data(db).edition;
-            emit_def_diagnostic_(
-                db,
-                acc,
-                &DefDiagnosticKind::MacroDefError { ast, message: e.to_string() },
-                edition,
-            );
-        }
+    if let hir_expand::db::TokenExpander::DeclarativeMacro(expander) = db.macro_expander(id)
+        && let Some(e) = expander.mac.err()
+    {
+        let Some(ast) = id.ast_id().left() else {
+            never!("declarative expander for non decl-macro: {:?}", e);
+            return;
+        };
+        let krate = HasModule::krate(&m.id, db);
+        let edition = krate.data(db).edition;
+        emit_def_diagnostic_(
+            db,
+            acc,
+            &DefDiagnosticKind::MacroDefError { ast, message: e.to_string() },
+            edition,
+        );
     }
 }
 
@@ -2564,10 +2564,10 @@ impl<'db> Param<'db> {
             Callee::Closure(closure, _) => {
                 let c = db.lookup_intern_closure(closure.into());
                 let body = db.body(c.0);
-                if let Expr::Closure { args, .. } = &body[c.1] {
-                    if let Pat::Bind { id, .. } = &body[args[self.idx]] {
-                        return Some(Local { parent: c.0, binding_id: *id });
-                    }
+                if let Expr::Closure { args, .. } = &body[c.1]
+                    && let Pat::Bind { id, .. } = &body[args[self.idx]]
+                {
+                    return Some(Local { parent: c.0, binding_id: *id });
                 }
                 None
             }
@@ -2761,26 +2761,20 @@ impl EvaluatedConst {
 
     pub fn render_debug(&self, db: &dyn HirDatabase) -> Result<String, MirEvalError> {
         let data = self.const_.data(Interner);
-        if let TyKind::Scalar(s) = data.ty.kind(Interner) {
-            if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) {
-                if let hir_ty::ConstValue::Concrete(c) = &data.value {
-                    if let hir_ty::ConstScalar::Bytes(b, _) = &c.interned {
-                        let value = u128::from_le_bytes(mir::pad16(b, false));
-                        let value_signed =
-                            i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_))));
-                        let mut result = if let Scalar::Int(_) = s {
-                            value_signed.to_string()
-                        } else {
-                            value.to_string()
-                        };
-                        if value >= 10 {
-                            format_to!(result, " ({value:#X})");
-                            return Ok(result);
-                        } else {
-                            return Ok(result);
-                        }
-                    }
-                }
+        if let TyKind::Scalar(s) = data.ty.kind(Interner)
+            && matches!(s, Scalar::Int(_) | Scalar::Uint(_))
+            && let hir_ty::ConstValue::Concrete(c) = &data.value
+            && let hir_ty::ConstScalar::Bytes(b, _) = &c.interned
+        {
+            let value = u128::from_le_bytes(mir::pad16(b, false));
+            let value_signed = i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_))));
+            let mut result =
+                if let Scalar::Int(_) = s { value_signed.to_string() } else { value.to_string() };
+            if value >= 10 {
+                format_to!(result, " ({value:#X})");
+                return Ok(result);
+            } else {
+                return Ok(result);
             }
         }
         mir::render_const_using_debug_impl(db, self.def, &self.const_)
@@ -4421,10 +4415,10 @@ impl Impl {
             let impls = db.trait_impls_in_crate(id);
             all.extend(impls.for_trait(trait_.id).map(Self::from))
         }
-        if let Some(block) = module.id.containing_block() {
-            if let Some(trait_impls) = db.trait_impls_in_block(block) {
-                all.extend(trait_impls.for_trait(trait_.id).map(Self::from));
-            }
+        if let Some(block) = module.id.containing_block()
+            && let Some(trait_impls) = db.trait_impls_in_block(block)
+        {
+            all.extend(trait_impls.for_trait(trait_.id).map(Self::from));
         }
         all
     }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index adba59236a4..d207305b4c6 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -933,19 +933,18 @@ impl<'db> SemanticsImpl<'db> {
                 InFile::new(file.file_id, last),
                 false,
                 &mut |InFile { value: last, file_id: last_fid }, _ctx| {
-                    if let Some(InFile { value: first, file_id: first_fid }) = scratch.next() {
-                        if first_fid == last_fid {
-                            if let Some(p) = first.parent() {
-                                let range = first.text_range().cover(last.text_range());
-                                let node = find_root(&p)
-                                    .covering_element(range)
-                                    .ancestors()
-                                    .take_while(|it| it.text_range() == range)
-                                    .find_map(N::cast);
-                                if let Some(node) = node {
-                                    res.push(node);
-                                }
-                            }
+                    if let Some(InFile { value: first, file_id: first_fid }) = scratch.next()
+                        && first_fid == last_fid
+                        && let Some(p) = first.parent()
+                    {
+                        let range = first.text_range().cover(last.text_range());
+                        let node = find_root(&p)
+                            .covering_element(range)
+                            .ancestors()
+                            .take_while(|it| it.text_range() == range)
+                            .find_map(N::cast);
+                        if let Some(node) = node {
+                            res.push(node);
                         }
                     }
                 },
@@ -1391,10 +1390,10 @@ impl<'db> SemanticsImpl<'db> {
                     }
                 })()
                 .is_none();
-                if was_not_remapped {
-                    if let ControlFlow::Break(b) = f(InFile::new(expansion, token), ctx) {
-                        return Some(b);
-                    }
+                if was_not_remapped
+                    && let ControlFlow::Break(b) = f(InFile::new(expansion, token), ctx)
+                {
+                    return Some(b);
                 }
             }
         }
@@ -2068,14 +2067,12 @@ impl<'db> SemanticsImpl<'db> {
                 break false;
             }
 
-            if let Some(parent) = ast::Expr::cast(parent.clone()) {
-                if let Some(ExprOrPatId::ExprId(expr_id)) =
+            if let Some(parent) = ast::Expr::cast(parent.clone())
+                && let Some(ExprOrPatId::ExprId(expr_id)) =
                     source_map.node_expr(InFile { file_id, value: &parent })
-                {
-                    if let Expr::Unsafe { .. } = body[expr_id] {
-                        break true;
-                    }
-                }
+                && let Expr::Unsafe { .. } = body[expr_id]
+            {
+                break true;
             }
 
             let Some(parent_) = parent.parent() else { break false };
@@ -2354,32 +2351,30 @@ struct RenameConflictsVisitor<'a> {
 
 impl RenameConflictsVisitor<'_> {
     fn resolve_path(&mut self, node: ExprOrPatId, path: &Path) {
-        if let Path::BarePath(path) = path {
-            if let Some(name) = path.as_ident() {
-                if *name.symbol() == self.new_name {
-                    if let Some(conflicting) = self.resolver.rename_will_conflict_with_renamed(
-                        self.db,
-                        name,
-                        path,
-                        self.body.expr_or_pat_path_hygiene(node),
-                        self.to_be_renamed,
-                    ) {
-                        self.conflicts.insert(conflicting);
-                    }
-                } else if *name.symbol() == self.old_name {
-                    if let Some(conflicting) =
-                        self.resolver.rename_will_conflict_with_another_variable(
-                            self.db,
-                            name,
-                            path,
-                            self.body.expr_or_pat_path_hygiene(node),
-                            &self.new_name,
-                            self.to_be_renamed,
-                        )
-                    {
-                        self.conflicts.insert(conflicting);
-                    }
+        if let Path::BarePath(path) = path
+            && let Some(name) = path.as_ident()
+        {
+            if *name.symbol() == self.new_name {
+                if let Some(conflicting) = self.resolver.rename_will_conflict_with_renamed(
+                    self.db,
+                    name,
+                    path,
+                    self.body.expr_or_pat_path_hygiene(node),
+                    self.to_be_renamed,
+                ) {
+                    self.conflicts.insert(conflicting);
                 }
+            } else if *name.symbol() == self.old_name
+                && let Some(conflicting) = self.resolver.rename_will_conflict_with_another_variable(
+                    self.db,
+                    name,
+                    path,
+                    self.body.expr_or_pat_path_hygiene(node),
+                    &self.new_name,
+                    self.to_be_renamed,
+                )
+            {
+                self.conflicts.insert(conflicting);
             }
         }
     }
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 0b554a9d4e3..d25fb1d8cdb 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -995,11 +995,11 @@ impl<'db> SourceAnalyzer<'db> {
 
         // Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are
         // trying to resolve foo::bar.
-        if let Some(use_tree) = parent().and_then(ast::UseTree::cast) {
-            if use_tree.coloncolon_token().is_some() {
-                return resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &store)
-                    .map(|it| (it, None));
-            }
+        if let Some(use_tree) = parent().and_then(ast::UseTree::cast)
+            && use_tree.coloncolon_token().is_some()
+        {
+            return resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &store)
+                .map(|it| (it, None));
         }
 
         let meta_path = path
@@ -1035,24 +1035,19 @@ impl<'db> SourceAnalyzer<'db> {
                 // }
                 // ```
                 Some(it) if matches!(it, PathResolution::Def(ModuleDef::BuiltinType(_))) => {
-                    if let Some(mod_path) = hir_path.mod_path() {
-                        if let Some(ModuleDefId::ModuleId(id)) =
+                    if let Some(mod_path) = hir_path.mod_path()
+                        && let Some(ModuleDefId::ModuleId(id)) =
                             self.resolver.resolve_module_path_in_items(db, mod_path).take_types()
+                    {
+                        let parent_hir_name = parent_hir_path.segments().get(1).map(|it| it.name);
+                        let module = crate::Module { id };
+                        if module
+                            .scope(db, None)
+                            .into_iter()
+                            .any(|(name, _)| Some(&name) == parent_hir_name)
                         {
-                            let parent_hir_name =
-                                parent_hir_path.segments().get(1).map(|it| it.name);
-                            let module = crate::Module { id };
-                            if module
-                                .scope(db, None)
-                                .into_iter()
-                                .any(|(name, _)| Some(&name) == parent_hir_name)
-                            {
-                                return Some((
-                                    PathResolution::Def(ModuleDef::Module(module)),
-                                    None,
-                                ));
-                            };
-                        }
+                            return Some((PathResolution::Def(ModuleDef::Module(module)), None));
+                        };
                     }
                     Some((it, None))
                 }
@@ -1282,22 +1277,22 @@ impl<'db> SourceAnalyzer<'db> {
         db: &'db dyn HirDatabase,
         macro_expr: InFile<&ast::MacroExpr>,
     ) -> bool {
-        if let Some((def, body, sm, Some(infer))) = self.body_() {
-            if let Some(expanded_expr) = sm.macro_expansion_expr(macro_expr) {
-                let mut is_unsafe = false;
-                let mut walk_expr = |expr_id| {
-                    unsafe_operations(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),
-                    ExprOrPatId::PatId(expanded_pat) => {
-                        body.walk_exprs_in_pat(expanded_pat, &mut walk_expr)
-                    }
+        if let Some((def, body, sm, Some(infer))) = self.body_()
+            && let Some(expanded_expr) = sm.macro_expansion_expr(macro_expr)
+        {
+            let mut is_unsafe = false;
+            let mut walk_expr = |expr_id| {
+                unsafe_operations(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),
+                ExprOrPatId::PatId(expanded_pat) => {
+                    body.walk_exprs_in_pat(expanded_pat, &mut walk_expr)
                 }
-                return is_unsafe;
             }
+            return is_unsafe;
         }
         false
     }
@@ -1575,12 +1570,11 @@ fn resolve_hir_path_(
 
         // If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
         // within the trait's associated types.
-        if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) {
-            if let Some(type_alias_id) =
+        if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty)
+            && let Some(type_alias_id) =
                 trait_id.trait_items(db).associated_type_by_name(unresolved.name)
-            {
-                return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
-            }
+        {
+            return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
         }
 
         let res = match ty {
@@ -1726,12 +1720,11 @@ fn resolve_hir_path_qualifier(
 
         // If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
         // within the trait's associated types.
-        if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) {
-            if let Some(type_alias_id) =
+        if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty)
+            && let Some(type_alias_id) =
                 trait_id.trait_items(db).associated_type_by_name(unresolved.name)
-            {
-                return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
-            }
+        {
+            return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
         }
 
         let res = match ty {
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 4b354e64062..e4089218305 100644
--- a/src/tools/rust-analyzer/crates/hir/src/term_search.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/term_search.rs
@@ -122,10 +122,10 @@ impl<'db> LookupTable<'db> {
         }
 
         // Collapse suggestions if there are many
-        if let Some(res) = &res {
-            if res.len() > self.many_threshold {
-                return Some(vec![Expr::Many(ty.clone())]);
-            }
+        if let Some(res) = &res
+            && res.len() > self.many_threshold
+        {
+            return Some(vec![Expr::Many(ty.clone())]);
         }
 
         res
@@ -160,10 +160,10 @@ impl<'db> LookupTable<'db> {
         }
 
         // Collapse suggestions if there are many
-        if let Some(res) = &res {
-            if res.len() > self.many_threshold {
-                return Some(vec![Expr::Many(ty.clone())]);
-            }
+        if let Some(res) = &res
+            && res.len() > self.many_threshold
+        {
+            return Some(vec![Expr::Many(ty.clone())]);
         }
 
         res
diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
index 843831948ad..78f534d014b 100644
--- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
@@ -336,10 +336,10 @@ impl<'db> Expr<'db> {
 
         if let Expr::Method { func, params, .. } = self {
             res.extend(params.iter().flat_map(|it| it.traits_used(db)));
-            if let Some(it) = func.as_assoc_item(db) {
-                if let Some(it) = it.container_or_implemented_trait(db) {
-                    res.push(it);
-                }
+            if let Some(it) = func.as_assoc_item(db)
+                && let Some(it) = it.container_or_implemented_trait(db)
+            {
+                res.push(it);
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs
index dcdc7ea9cdc..27dbdcf2c4d 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs
@@ -82,10 +82,10 @@ fn fetch_borrowed_types(node: &ast::Adt) -> Option<Vec<ast::RefType>> {
             record_field_list
                 .fields()
                 .filter_map(|r_field| {
-                    if let ast::Type::RefType(ref_type) = r_field.ty()? {
-                        if ref_type.lifetime().is_none() {
-                            return Some(ref_type);
-                        }
+                    if let ast::Type::RefType(ref_type) = r_field.ty()?
+                        && ref_type.lifetime().is_none()
+                    {
+                        return Some(ref_type);
                     }
 
                     None
@@ -102,10 +102,10 @@ fn find_ref_types_from_field_list(field_list: &ast::FieldList) -> Option<Vec<ast
         ast::FieldList::RecordFieldList(record_list) => record_list
             .fields()
             .filter_map(|f| {
-                if let ast::Type::RefType(ref_type) = f.ty()? {
-                    if ref_type.lifetime().is_none() {
-                        return Some(ref_type);
-                    }
+                if let ast::Type::RefType(ref_type) = f.ty()?
+                    && ref_type.lifetime().is_none()
+                {
+                    return Some(ref_type);
                 }
 
                 None
@@ -114,10 +114,10 @@ fn find_ref_types_from_field_list(field_list: &ast::FieldList) -> Option<Vec<ast
         ast::FieldList::TupleFieldList(tuple_field_list) => tuple_field_list
             .fields()
             .filter_map(|f| {
-                if let ast::Type::RefType(ref_type) = f.ty()? {
-                    if ref_type.lifetime().is_none() {
-                        return Some(ref_type);
-                    }
+                if let ast::Type::RefType(ref_type) = f.ty()?
+                    && ref_type.lifetime().is_none()
+                {
+                    return Some(ref_type);
                 }
 
                 None
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index ab183ac7089..11201afb8a7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -183,13 +183,11 @@ fn add_missing_impl_members_inner(
             .clone()
             .into_iter()
             .chain(other_items.iter().cloned())
-            .map(either::Either::Right)
             .collect::<Vec<_>>();
 
         let mut editor = edit.make_editor(impl_def.syntax());
         if let Some(assoc_item_list) = impl_def.assoc_item_list() {
-            let items = new_assoc_items.into_iter().filter_map(either::Either::right).collect();
-            assoc_item_list.add_items(&mut editor, items);
+            assoc_item_list.add_items(&mut editor, new_assoc_items);
         } else {
             let assoc_item_list = make::assoc_item_list(Some(new_assoc_items)).clone_for_update();
             editor.insert_all(
@@ -201,14 +199,12 @@ fn add_missing_impl_members_inner(
 
         if let Some(cap) = ctx.config.snippet_cap {
             let mut placeholder = None;
-            if let DefaultMethods::No = mode {
-                if let Some(ast::AssocItem::Fn(func)) = &first_new_item {
-                    if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast)
-                        && m.syntax().text() == "todo!()"
-                    {
-                        placeholder = Some(m);
-                    }
-                }
+            if let DefaultMethods::No = mode
+                && let Some(ast::AssocItem::Fn(func)) = &first_new_item
+                && let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast)
+                && m.syntax().text() == "todo!()"
+            {
+                placeholder = Some(m);
             }
 
             if let Some(macro_call) = placeholder {
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 3b447d1f6d5..753a9e56c35 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
@@ -207,10 +207,10 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_>
             // negate all tail expressions in the closure body
             let tail_cb = &mut |e: &_| tail_cb_impl(&mut editor, &make, e);
             walk_expr(&closure_body, &mut |expr| {
-                if let ast::Expr::ReturnExpr(ret_expr) = expr {
-                    if let Some(ret_expr_arg) = &ret_expr.expr() {
-                        for_each_tail_expr(ret_expr_arg, tail_cb);
-                    }
+                if let ast::Expr::ReturnExpr(ret_expr) = expr
+                    && let Some(ret_expr_arg) = &ret_expr.expr()
+                {
+                    for_each_tail_expr(ret_expr_arg, tail_cb);
                 }
             });
             for_each_tail_expr(&closure_body, tail_cb);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
index d7b7e8d9cad..9d5d3f22370 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
@@ -86,12 +86,11 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
                     e @ ast::Expr::CallExpr(_) => Some(e.clone()),
                     _ => None,
                 };
-                if let Some(ast::Expr::CallExpr(call)) = e {
-                    if let Some(arg_list) = call.arg_list() {
-                        if let Some(arg) = arg_list.args().next() {
-                            editor.replace(call.syntax(), arg.syntax());
-                        }
-                    }
+                if let Some(ast::Expr::CallExpr(call)) = e
+                    && let Some(arg_list) = call.arg_list()
+                    && let Some(arg) = arg_list.args().next()
+                {
+                    editor.replace(call.syntax(), arg.syntax());
                 }
             });
             let edit = editor.finish();
@@ -276,12 +275,12 @@ fn is_invalid_body(
                 e @ ast::Expr::CallExpr(_) => Some(e.clone()),
                 _ => None,
             };
-            if let Some(ast::Expr::CallExpr(call)) = e {
-                if let Some(ast::Expr::PathExpr(p)) = call.expr() {
-                    let res = p.path().and_then(|p| sema.resolve_path(&p));
-                    if let Some(hir::PathResolution::Def(hir::ModuleDef::Variant(v))) = res {
-                        return invalid |= v != some_variant;
-                    }
+            if let Some(ast::Expr::CallExpr(call)) = e
+                && let Some(ast::Expr::PathExpr(p)) = call.expr()
+            {
+                let res = p.path().and_then(|p| sema.resolve_path(&p));
+                if let Some(hir::PathResolution::Def(hir::ModuleDef::Variant(v))) = res {
+                    return invalid |= v != some_variant;
                 }
             }
             invalid = true
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
index 43515de71e2..916bb67ebb4 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
@@ -101,21 +101,21 @@ pub(crate) fn convert_closure_to_fn(acc: &mut Assists, ctx: &AssistContext<'_>)
     // but we need to locate `AstPtr`s inside the body.
     let mut wrap_body_in_block = true;
     if let ast::Expr::BlockExpr(block) = &body {
-        if let Some(async_token) = block.async_token() {
-            if !is_async {
-                is_async = true;
-                ret_ty = ret_ty.future_output(ctx.db())?;
-                let token_idx = async_token.index();
-                let whitespace_tokens_after_count = async_token
-                    .siblings_with_tokens(Direction::Next)
-                    .skip(1)
-                    .take_while(|token| token.kind() == SyntaxKind::WHITESPACE)
-                    .count();
-                body.syntax().splice_children(
-                    token_idx..token_idx + whitespace_tokens_after_count + 1,
-                    Vec::new(),
-                );
-            }
+        if let Some(async_token) = block.async_token()
+            && !is_async
+        {
+            is_async = true;
+            ret_ty = ret_ty.future_output(ctx.db())?;
+            let token_idx = async_token.index();
+            let whitespace_tokens_after_count = async_token
+                .siblings_with_tokens(Direction::Next)
+                .skip(1)
+                .take_while(|token| token.kind() == SyntaxKind::WHITESPACE)
+                .count();
+            body.syntax().splice_children(
+                token_idx..token_idx + whitespace_tokens_after_count + 1,
+                Vec::new(),
+            );
         }
         if let Some(gen_token) = block.gen_token() {
             is_gen = true;
@@ -513,10 +513,10 @@ fn capture_as_arg(ctx: &AssistContext<'_>, capture: &ClosureCapture) -> ast::Exp
         CaptureKind::MutableRef | CaptureKind::UniqueSharedRef => true,
         CaptureKind::Move => return place,
     };
-    if let ast::Expr::PrefixExpr(expr) = &place {
-        if expr.op_kind() == Some(ast::UnaryOp::Deref) {
-            return expr.expr().expect("`display_place_source_code()` produced an invalid expr");
-        }
+    if let ast::Expr::PrefixExpr(expr) = &place
+        && expr.op_kind() == Some(ast::UnaryOp::Deref)
+    {
+        return expr.expr().expect("`display_place_source_code()` produced an invalid expr");
     }
     make::expr_ref(place, needs_mut)
 }
@@ -642,11 +642,11 @@ fn peel_blocks_and_refs_and_parens(mut expr: ast::Expr) -> ast::Expr {
             expr = ast::Expr::cast(parent).unwrap();
             continue;
         }
-        if let Some(stmt_list) = ast::StmtList::cast(parent) {
-            if let Some(block) = stmt_list.syntax().parent().and_then(ast::BlockExpr::cast) {
-                expr = ast::Expr::BlockExpr(block);
-                continue;
-            }
+        if let Some(stmt_list) = ast::StmtList::cast(parent)
+            && let Some(block) = stmt_list.syntax().parent().and_then(ast::BlockExpr::cast)
+        {
+            expr = ast::Expr::BlockExpr(block);
+            continue;
         }
         break;
     }
@@ -662,12 +662,11 @@ fn expr_of_pat(pat: ast::Pat) -> Option<ast::Expr> {
             if let Some(let_stmt) = ast::LetStmt::cast(ancestor.clone()) {
                 break 'find_expr let_stmt.initializer();
             }
-            if ast::MatchArm::can_cast(ancestor.kind()) {
-                if let Some(match_) =
+            if ast::MatchArm::can_cast(ancestor.kind())
+                && let Some(match_) =
                     ancestor.parent().and_then(|it| it.parent()).and_then(ast::MatchExpr::cast)
-                {
-                    break 'find_expr match_.expr();
-                }
+            {
+                break 'find_expr match_.expr();
             }
             if ast::ExprStmt::can_cast(ancestor.kind()) {
                 break;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs
index db41927f1df..f1cc3d90b9c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs
@@ -1,9 +1,7 @@
 use ide_db::{famous_defs::FamousDefs, traits::resolve_target_trait};
-use itertools::Itertools;
-use syntax::{
-    ast::{self, AstNode, HasGenericArgs, HasName, make},
-    ted,
-};
+use syntax::ast::edit::IndentLevel;
+use syntax::ast::{self, AstNode, HasGenericArgs, HasName, make};
+use syntax::syntax_editor::{Element, Position};
 
 use crate::{AssistContext, AssistId, Assists};
 
@@ -49,11 +47,12 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_>
     };
 
     let associated_items = impl_.assoc_item_list()?;
+    let associated_l_curly = associated_items.l_curly_token()?;
     let from_fn = associated_items.assoc_items().find_map(|item| {
-        if let ast::AssocItem::Fn(f) = item {
-            if f.name()?.text() == "from" {
-                return Some(f);
-            }
+        if let ast::AssocItem::Fn(f) = item
+            && f.name()?.text() == "from"
+        {
+            return Some(f);
         };
         None
     })?;
@@ -75,30 +74,25 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_>
         "Convert From to TryFrom",
         impl_.syntax().text_range(),
         |builder| {
-            let trait_ty = builder.make_mut(trait_ty);
-            let from_fn_return_type = builder.make_mut(from_fn_return_type);
-            let from_fn_name = builder.make_mut(from_fn_name);
-            let tail_expr = builder.make_mut(tail_expr);
-            let return_exprs = return_exprs.map(|r| builder.make_mut(r)).collect_vec();
-            let associated_items = builder.make_mut(associated_items);
-
-            ted::replace(
+            let mut editor = builder.make_editor(impl_.syntax());
+            editor.replace(
                 trait_ty.syntax(),
                 make::ty(&format!("TryFrom<{from_type}>")).syntax().clone_for_update(),
             );
-            ted::replace(
+            editor.replace(
                 from_fn_return_type.syntax(),
                 make::ty("Result<Self, Self::Error>").syntax().clone_for_update(),
             );
-            ted::replace(from_fn_name.syntax(), make::name("try_from").syntax().clone_for_update());
-            ted::replace(
+            editor
+                .replace(from_fn_name.syntax(), make::name("try_from").syntax().clone_for_update());
+            editor.replace(
                 tail_expr.syntax(),
                 wrap_ok(tail_expr.clone()).syntax().clone_for_update(),
             );
 
             for r in return_exprs {
                 let t = r.expr().unwrap_or_else(make::ext::expr_unit);
-                ted::replace(t.syntax(), wrap_ok(t.clone()).syntax().clone_for_update());
+                editor.replace(t.syntax(), wrap_ok(t.clone()).syntax().clone_for_update());
             }
 
             let error_type = ast::AssocItem::TypeAlias(make::ty_alias(
@@ -110,15 +104,24 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_>
             ))
             .clone_for_update();
 
-            if let Some(cap) = ctx.config.snippet_cap {
-                if let ast::AssocItem::TypeAlias(type_alias) = &error_type {
-                    if let Some(ty) = type_alias.ty() {
-                        builder.add_placeholder_snippet(cap, ty);
-                    }
-                }
+            if let Some(cap) = ctx.config.snippet_cap
+                && let ast::AssocItem::TypeAlias(type_alias) = &error_type
+                && let Some(ty) = type_alias.ty()
+            {
+                let placeholder = builder.make_placeholder_snippet(cap);
+                editor.add_annotation(ty.syntax(), placeholder);
             }
 
-            associated_items.add_item_at_start(error_type);
+            let indent = IndentLevel::from_token(&associated_l_curly) + 1;
+            editor.insert_all(
+                Position::after(associated_l_curly),
+                vec![
+                    make::tokens::whitespace(&format!("\n{indent}")).syntax_element(),
+                    error_type.syntax().syntax_element(),
+                    make::tokens::whitespace("\n").syntax_element(),
+                ],
+            );
+            builder.add_file_edits(ctx.vfs_file_id(), editor);
         },
     )
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
index b80276a95fb..3d9cde0e0a6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
@@ -65,10 +65,10 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) -
     };
 
     let into_fn = impl_.assoc_item_list()?.assoc_items().find_map(|item| {
-        if let ast::AssocItem::Fn(f) = item {
-            if f.name()?.text() == "into" {
-                return Some(f);
-            }
+        if let ast::AssocItem::Fn(f) = item
+            && f.name()?.text() == "into"
+        {
+            return Some(f);
         };
         None
     })?;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
index cca4cb9d8f7..247c1011589 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
@@ -265,10 +265,10 @@ fn replace_body_return_values(body: ast::Expr, struct_name: &str) {
 
     let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_wrap, e);
     walk_expr(&body, &mut |expr| {
-        if let ast::Expr::ReturnExpr(ret_expr) = expr {
-            if let Some(ret_expr_arg) = &ret_expr.expr() {
-                for_each_tail_expr(ret_expr_arg, tail_cb);
-            }
+        if let ast::Expr::ReturnExpr(ret_expr) = expr
+            && let Some(ret_expr_arg) = &ret_expr.expr()
+        {
+            for_each_tail_expr(ret_expr_arg, tail_cb);
         }
     });
     for_each_tail_expr(&body, tail_cb);
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 80756197fb7..3d78895477b 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
@@ -1,9 +1,14 @@
 use either::Either;
+use hir::FileRangeWrapper;
 use ide_db::defs::{Definition, NameRefClass};
+use std::ops::RangeInclusive;
 use syntax::{
-    SyntaxKind, SyntaxNode,
-    ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility},
-    match_ast, ted,
+    SyntaxElement, SyntaxKind, SyntaxNode, T, TextSize,
+    ast::{
+        self, AstNode, HasAttrs, HasGenericParams, HasVisibility, syntax_factory::SyntaxFactory,
+    },
+    match_ast,
+    syntax_editor::{Element, Position, SyntaxEditor},
 };
 
 use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder};
@@ -71,7 +76,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
         Either::Right(v) => Either::Right(ctx.sema.to_def(v)?),
     };
     let target = strukt_or_variant.as_ref().either(|s| s.syntax(), |v| v.syntax()).text_range();
-
+    let syntax = strukt_or_variant.as_ref().either(|s| s.syntax(), |v| v.syntax());
     acc.add(
         AssistId::refactor_rewrite("convert_tuple_struct_to_named_struct"),
         "Convert to named struct",
@@ -79,58 +84,55 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
         |edit| {
             let names = generate_names(tuple_fields.fields());
             edit_field_references(ctx, edit, tuple_fields.fields(), &names);
+            let mut editor = edit.make_editor(syntax);
             edit_struct_references(ctx, edit, strukt_def, &names);
-            edit_struct_def(ctx, edit, &strukt_or_variant, tuple_fields, names);
+            edit_struct_def(&mut editor, &strukt_or_variant, tuple_fields, names);
+            edit.add_file_edits(ctx.vfs_file_id(), editor);
         },
     )
 }
 
 fn edit_struct_def(
-    ctx: &AssistContext<'_>,
-    edit: &mut SourceChangeBuilder,
+    editor: &mut SyntaxEditor,
     strukt: &Either<ast::Struct, ast::Variant>,
     tuple_fields: ast::TupleFieldList,
     names: Vec<ast::Name>,
 ) {
     let record_fields = tuple_fields.fields().zip(names).filter_map(|(f, name)| {
-        let field = ast::make::record_field(f.visibility(), name, f.ty()?).clone_for_update();
-        ted::insert_all(
-            ted::Position::first_child_of(field.syntax()),
+        let field = ast::make::record_field(f.visibility(), name, f.ty()?);
+        let mut field_editor = SyntaxEditor::new(field.syntax().clone());
+        field_editor.insert_all(
+            Position::first_child_of(field.syntax()),
             f.attrs().map(|attr| attr.syntax().clone_subtree().clone_for_update().into()).collect(),
         );
-        Some(field)
+        ast::RecordField::cast(field_editor.finish().new_root().clone())
     });
-    let record_fields = ast::make::record_field_list(record_fields);
-    let tuple_fields_text_range = tuple_fields.syntax().text_range();
-
-    edit.edit_file(ctx.vfs_file_id());
+    let make = SyntaxFactory::without_mappings();
+    let record_fields = make.record_field_list(record_fields);
+    let tuple_fields_before = Position::before(tuple_fields.syntax());
 
     if let Either::Left(strukt) = strukt {
         if let Some(w) = strukt.where_clause() {
-            edit.delete(w.syntax().text_range());
-            edit.insert(
-                tuple_fields_text_range.start(),
-                ast::make::tokens::single_newline().text(),
-            );
-            edit.insert(tuple_fields_text_range.start(), w.syntax().text());
+            editor.delete(w.syntax());
+            let mut insert_element = Vec::new();
+            insert_element.push(ast::make::tokens::single_newline().syntax_element());
+            insert_element.push(w.syntax().clone_for_update().syntax_element());
             if w.syntax().last_token().is_none_or(|t| t.kind() != SyntaxKind::COMMA) {
-                edit.insert(tuple_fields_text_range.start(), ",");
+                insert_element.push(ast::make::token(T![,]).into());
             }
-            edit.insert(
-                tuple_fields_text_range.start(),
-                ast::make::tokens::single_newline().text(),
-            );
+            insert_element.push(ast::make::tokens::single_newline().syntax_element());
+            editor.insert_all(tuple_fields_before, insert_element);
         } else {
-            edit.insert(tuple_fields_text_range.start(), ast::make::tokens::single_space().text());
+            editor.insert(tuple_fields_before, ast::make::tokens::single_space());
         }
         if let Some(t) = strukt.semicolon_token() {
-            edit.delete(t.text_range());
+            editor.delete(t);
         }
     } else {
-        edit.insert(tuple_fields_text_range.start(), ast::make::tokens::single_space().text());
+        editor.insert(tuple_fields_before, ast::make::tokens::single_space());
     }
 
-    edit.replace(tuple_fields_text_range, record_fields.to_string());
+    editor.replace(tuple_fields.syntax(), record_fields.syntax());
 }
 
 fn edit_struct_references(
@@ -145,27 +147,22 @@ fn edit_struct_references(
     };
     let usages = strukt_def.usages(&ctx.sema).include_self_refs().all();
 
-    let edit_node = |edit: &mut SourceChangeBuilder, node: SyntaxNode| -> Option<()> {
+    let edit_node = |node: SyntaxNode| -> Option<SyntaxNode> {
+        let make = SyntaxFactory::without_mappings();
         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.file_id(ctx.db()));
-                    edit.replace(
-                        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(
-                                |(pat, name)| {
-                                    ast::make::record_pat_field(
-                                        ast::make::name_ref(&name.to_string()),
-                                        pat,
-                                    )
-                                },
-                            ), None),
-                        )
-                        .to_string(),
-                    );
+                    Some(make.record_pat_with_fields(
+                        tuple_struct_pat.path()?,
+                        ast::make::record_pat_field_list(tuple_struct_pat.fields().zip(names).map(
+                            |(pat, name)| {
+                                ast::make::record_pat_field(
+                                    ast::make::name_ref(&name.to_string()),
+                                    pat,
+                                )
+                            },
+                        ), None),
+                    ).syntax().clone())
                 },
                 // for tuple struct creations like Foo(42)
                 ast::CallExpr(call_expr) => {
@@ -181,10 +178,8 @@ fn edit_struct_references(
                     }
 
                     let arg_list = call_expr.syntax().descendants().find_map(ast::ArgList::cast)?;
-
-                    edit.replace(
-                        ctx.sema.original_range(&node).range,
-                        ast::make::record_expr(
+                    Some(
+                        make.record_expr(
                             path,
                             ast::make::record_expr_field_list(arg_list.args().zip(names).map(
                                 |(expr, name)| {
@@ -194,25 +189,58 @@ fn edit_struct_references(
                                     )
                                 },
                             )),
-                        )
-                        .to_string(),
-                    );
+                        ).syntax().clone()
+                    )
                 },
-                _ => return None,
+                _ => None,
             }
         }
-        Some(())
     };
 
     for (file_id, refs) in usages {
-        edit.edit_file(file_id.file_id(ctx.db()));
-        for r in refs {
-            for node in r.name.syntax().ancestors() {
-                if edit_node(edit, node).is_some() {
-                    break;
+        let source = ctx.sema.parse(file_id);
+        let source = source.syntax();
+
+        let mut editor = edit.make_editor(source);
+        for r in refs.iter().rev() {
+            if let Some((old_node, new_node)) = r
+                .name
+                .syntax()
+                .ancestors()
+                .find_map(|node| Some((node.clone(), edit_node(node.clone())?)))
+            {
+                if let Some(old_node) = ctx.sema.original_syntax_node_rooted(&old_node) {
+                    editor.replace(old_node, new_node);
+                } else {
+                    let FileRangeWrapper { file_id: _, range } = ctx.sema.original_range(&old_node);
+                    let parent = source.covering_element(range);
+                    match parent {
+                        SyntaxElement::Token(token) => {
+                            editor.replace(token, new_node.syntax_element());
+                        }
+                        SyntaxElement::Node(parent_node) => {
+                            // replace the part of macro
+                            // ```
+                            // foo!(a, Test::A(0));
+                            //     ^^^^^^^^^^^^^^^ // parent_node
+                            //         ^^^^^^^^^^  // replace_range
+                            // ```
+                            let start = parent_node
+                                .children_with_tokens()
+                                .find(|t| t.text_range().contains(range.start()));
+                            let end = parent_node
+                                .children_with_tokens()
+                                .find(|t| t.text_range().contains(range.end() - TextSize::new(1)));
+                            if let (Some(start), Some(end)) = (start, end) {
+                                let replace_range = RangeInclusive::new(start, end);
+                                editor.replace_all(replace_range, vec![new_node.into()]);
+                            }
+                        }
+                    }
                 }
             }
         }
+        edit.add_file_edits(file_id.file_id(ctx.db()), editor);
     }
 }
 
@@ -230,22 +258,28 @@ fn edit_field_references(
         let def = Definition::Field(field);
         let usages = def.usages(&ctx.sema).all();
         for (file_id, refs) in usages {
-            edit.edit_file(file_id.file_id(ctx.db()));
+            let source = ctx.sema.parse(file_id);
+            let source = source.syntax();
+            let mut editor = edit.make_editor(source);
             for r in refs {
-                if let Some(name_ref) = r.name.as_name_ref() {
-                    edit.replace(ctx.sema.original_range(name_ref.syntax()).range, name.text());
+                if let Some(name_ref) = r.name.as_name_ref()
+                    && let Some(original) = ctx.sema.original_ast_node(name_ref.clone())
+                {
+                    editor.replace(original.syntax(), name.syntax());
                 }
             }
+            edit.add_file_edits(file_id.file_id(ctx.db()), editor);
         }
     }
 }
 
 fn generate_names(fields: impl Iterator<Item = ast::TupleField>) -> Vec<ast::Name> {
+    let make = SyntaxFactory::without_mappings();
     fields
         .enumerate()
         .map(|(i, _)| {
             let idx = i + 1;
-            ast::make::name(&format!("field{idx}"))
+            make.name(&format!("field{idx}"))
         })
         .collect()
 }
@@ -1013,8 +1047,7 @@ where
 pub struct $0Foo(#[my_custom_attr] u32);
 "#,
             r#"
-pub struct Foo { #[my_custom_attr]
-field1: u32 }
+pub struct Foo { #[my_custom_attr]field1: u32 }
 "#,
         );
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
index e582aa814ae..1af5db17f04 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
@@ -100,10 +100,10 @@ fn is_bool_literal_expr(
     sema: &Semantics<'_, RootDatabase>,
     expr: &ast::Expr,
 ) -> Option<ArmBodyExpression> {
-    if let ast::Expr::Literal(lit) = expr {
-        if let ast::LiteralKind::Bool(b) = lit.kind() {
-            return Some(ArmBodyExpression::Literal(b));
-        }
+    if let ast::Expr::Literal(lit) = expr
+        && let ast::LiteralKind::Bool(b) = lit.kind()
+    {
+        return Some(ArmBodyExpression::Literal(b));
     }
 
     if !sema.type_of_expr(expr)?.original.is_bool() {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs
index efadde9e364..9976e34e730 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs
@@ -106,73 +106,73 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
         },
     );
 
-    if let Some(let_stmt) = try_expr.syntax().parent().and_then(ast::LetStmt::cast) {
-        if let_stmt.let_else().is_none() {
-            let pat = let_stmt.pat()?;
-            acc.add(
-                AssistId::refactor_rewrite("desugar_try_expr_let_else"),
-                "Replace try expression with let else",
-                target,
-                |builder| {
-                    let make = SyntaxFactory::with_mappings();
-                    let mut editor = builder.make_editor(let_stmt.syntax());
+    if let Some(let_stmt) = try_expr.syntax().parent().and_then(ast::LetStmt::cast)
+        && let_stmt.let_else().is_none()
+    {
+        let pat = let_stmt.pat()?;
+        acc.add(
+            AssistId::refactor_rewrite("desugar_try_expr_let_else"),
+            "Replace try expression with let else",
+            target,
+            |builder| {
+                let make = SyntaxFactory::with_mappings();
+                let mut editor = builder.make_editor(let_stmt.syntax());
 
-                    let indent_level = IndentLevel::from_node(let_stmt.syntax());
-                    let new_let_stmt = make.let_else_stmt(
-                        try_enum.happy_pattern(pat),
-                        let_stmt.ty(),
-                        expr,
-                        make.block_expr(
-                            iter::once(
-                                make.expr_stmt(
-                                    make.expr_return(Some(match try_enum {
-                                        TryEnum::Option => make.expr_path(make.ident_path("None")),
-                                        TryEnum::Result => make
-                                            .expr_call(
-                                                make.expr_path(make.ident_path("Err")),
-                                                make.arg_list(iter::once(
-                                                    match ctx.config.expr_fill_default {
-                                                        ExprFillDefaultMode::Todo => make
-                                                            .expr_macro(
-                                                                make.ident_path("todo"),
-                                                                make.token_tree(
-                                                                    syntax::SyntaxKind::L_PAREN,
-                                                                    [],
-                                                                ),
-                                                            )
-                                                            .into(),
-                                                        ExprFillDefaultMode::Underscore => {
-                                                            make.expr_underscore().into()
-                                                        }
-                                                        ExprFillDefaultMode::Default => make
-                                                            .expr_macro(
-                                                                make.ident_path("todo"),
-                                                                make.token_tree(
-                                                                    syntax::SyntaxKind::L_PAREN,
-                                                                    [],
-                                                                ),
-                                                            )
-                                                            .into(),
-                                                    },
-                                                )),
-                                            )
-                                            .into(),
-                                    }))
-                                    .indent(indent_level + 1)
-                                    .into(),
-                                )
+                let indent_level = IndentLevel::from_node(let_stmt.syntax());
+                let new_let_stmt = make.let_else_stmt(
+                    try_enum.happy_pattern(pat),
+                    let_stmt.ty(),
+                    expr,
+                    make.block_expr(
+                        iter::once(
+                            make.expr_stmt(
+                                make.expr_return(Some(match try_enum {
+                                    TryEnum::Option => make.expr_path(make.ident_path("None")),
+                                    TryEnum::Result => make
+                                        .expr_call(
+                                            make.expr_path(make.ident_path("Err")),
+                                            make.arg_list(iter::once(
+                                                match ctx.config.expr_fill_default {
+                                                    ExprFillDefaultMode::Todo => make
+                                                        .expr_macro(
+                                                            make.ident_path("todo"),
+                                                            make.token_tree(
+                                                                syntax::SyntaxKind::L_PAREN,
+                                                                [],
+                                                            ),
+                                                        )
+                                                        .into(),
+                                                    ExprFillDefaultMode::Underscore => {
+                                                        make.expr_underscore().into()
+                                                    }
+                                                    ExprFillDefaultMode::Default => make
+                                                        .expr_macro(
+                                                            make.ident_path("todo"),
+                                                            make.token_tree(
+                                                                syntax::SyntaxKind::L_PAREN,
+                                                                [],
+                                                            ),
+                                                        )
+                                                        .into(),
+                                                },
+                                            )),
+                                        )
+                                        .into(),
+                                }))
+                                .indent(indent_level + 1)
                                 .into(),
-                            ),
-                            None,
-                        )
-                        .indent(indent_level),
-                    );
-                    editor.replace(let_stmt.syntax(), new_let_stmt.syntax());
-                    editor.add_mappings(make.finish_with_mappings());
-                    builder.add_file_edits(ctx.vfs_file_id(), editor);
-                },
-            );
-        }
+                            )
+                            .into(),
+                        ),
+                        None,
+                    )
+                    .indent(indent_level),
+                );
+                editor.replace(let_stmt.syntax(), new_let_stmt.syntax());
+                editor.add_mappings(make.finish_with_mappings());
+                builder.add_file_edits(ctx.vfs_file_id(), editor);
+            },
+        );
     }
     Some(())
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs
index 307414c7971..66552dd65f5 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs
@@ -272,16 +272,16 @@ impl Refs {
                 .clone()
                 .into_iter()
                 .filter(|r| {
-                    if let Definition::Trait(tr) = r.def {
-                        if tr.items(ctx.db()).into_iter().any(|ai| {
+                    if let Definition::Trait(tr) = r.def
+                        && tr.items(ctx.db()).into_iter().any(|ai| {
                             if let AssocItem::Function(f) = ai {
                                 def_is_referenced_in(Definition::Function(f), ctx)
                             } else {
                                 false
                             }
-                        }) {
-                            return true;
-                        }
+                        })
+                    {
+                        return true;
                     }
 
                     def_is_referenced_in(r.def, ctx)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index 00cbef1c01c..890b8dd6412 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -175,10 +175,10 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
 
             let fn_def = format_function(ctx, module, &fun, old_indent).clone_for_update();
 
-            if let Some(cap) = ctx.config.snippet_cap {
-                if let Some(name) = fn_def.name() {
-                    builder.add_tabstop_before(cap, name);
-                }
+            if let Some(cap) = ctx.config.snippet_cap
+                && let Some(name) = fn_def.name()
+            {
+                builder.add_tabstop_before(cap, name);
             }
 
             let fn_def = match fun.self_param_adt(ctx) {
@@ -289,10 +289,10 @@ fn extraction_target(node: &SyntaxNode, selection_range: TextRange) -> Option<Fu
 
     // Covering element returned the parent block of one or multiple statements that have been selected
     if let Some(stmt_list) = ast::StmtList::cast(node.clone()) {
-        if let Some(block_expr) = stmt_list.syntax().parent().and_then(ast::BlockExpr::cast) {
-            if block_expr.syntax().text_range() == selection_range {
-                return FunctionBody::from_expr(block_expr.into());
-            }
+        if let Some(block_expr) = stmt_list.syntax().parent().and_then(ast::BlockExpr::cast)
+            && block_expr.syntax().text_range() == selection_range
+        {
+            return FunctionBody::from_expr(block_expr.into());
         }
 
         // Extract the full statements.
@@ -915,11 +915,10 @@ impl FunctionBody {
                     ast::Fn(fn_) => {
                         let func = sema.to_def(&fn_)?;
                         let mut ret_ty = func.ret_type(sema.db);
-                        if func.is_async(sema.db) {
-                            if let Some(async_ret) = func.async_ret_type(sema.db) {
+                        if func.is_async(sema.db)
+                            && let Some(async_ret) = func.async_ret_type(sema.db) {
                                 ret_ty = async_ret;
                             }
-                        }
                         (fn_.const_token().is_some(), fn_.body().map(ast::Expr::BlockExpr), Some(ret_ty))
                     },
                     ast::Static(statik) => {
@@ -1172,19 +1171,19 @@ impl GenericParent {
 /// Search `parent`'s ancestors for items with potentially applicable generic parameters
 fn generic_parents(parent: &SyntaxNode) -> Vec<GenericParent> {
     let mut list = Vec::new();
-    if let Some(parent_item) = parent.ancestors().find_map(ast::Item::cast) {
-        if let ast::Item::Fn(ref fn_) = parent_item {
-            if let Some(parent_parent) =
-                parent_item.syntax().parent().and_then(|it| it.parent()).and_then(ast::Item::cast)
-            {
-                match parent_parent {
-                    ast::Item::Impl(impl_) => list.push(GenericParent::Impl(impl_)),
-                    ast::Item::Trait(trait_) => list.push(GenericParent::Trait(trait_)),
-                    _ => (),
-                }
+    if let Some(parent_item) = parent.ancestors().find_map(ast::Item::cast)
+        && let ast::Item::Fn(ref fn_) = parent_item
+    {
+        if let Some(parent_parent) =
+            parent_item.syntax().parent().and_then(|it| it.parent()).and_then(ast::Item::cast)
+        {
+            match parent_parent {
+                ast::Item::Impl(impl_) => list.push(GenericParent::Impl(impl_)),
+                ast::Item::Trait(trait_) => list.push(GenericParent::Trait(trait_)),
+                _ => (),
             }
-            list.push(GenericParent::Fn(fn_.clone()));
         }
+        list.push(GenericParent::Fn(fn_.clone()));
     }
     list
 }
@@ -1337,10 +1336,10 @@ fn locals_defined_in_body(
     //        see https://github.com/rust-lang/rust-analyzer/pull/7535#discussion_r570048550
     let mut res = FxIndexSet::default();
     body.walk_pat(&mut |pat| {
-        if let ast::Pat::IdentPat(pat) = pat {
-            if let Some(local) = sema.to_def(&pat) {
-                res.insert(local);
-            }
+        if let ast::Pat::IdentPat(pat) = pat
+            && let Some(local) = sema.to_def(&pat)
+        {
+            res.insert(local);
         }
     });
     res
@@ -1445,11 +1444,11 @@ fn impl_type_name(impl_node: &ast::Impl) -> Option<String> {
 fn fixup_call_site(builder: &mut SourceChangeBuilder, body: &FunctionBody) {
     let parent_match_arm = body.parent().and_then(ast::MatchArm::cast);
 
-    if let Some(parent_match_arm) = parent_match_arm {
-        if parent_match_arm.comma_token().is_none() {
-            let parent_match_arm = builder.make_mut(parent_match_arm);
-            ted::append_child_raw(parent_match_arm.syntax(), make::token(T![,]));
-        }
+    if let Some(parent_match_arm) = parent_match_arm
+        && parent_match_arm.comma_token().is_none()
+    {
+        let parent_match_arm = builder.make_mut(parent_match_arm);
+        ted::append_child_raw(parent_match_arm.syntax(), make::token(T![,]));
     }
 }
 
@@ -2120,30 +2119,30 @@ fn update_external_control_flow(handler: &FlowHandler<'_>, syntax: &SyntaxNode)
                 _ => {}
             },
             WalkEvent::Leave(e) => {
-                if nested_scope.is_none() {
-                    if let Some(expr) = ast::Expr::cast(e.clone()) {
-                        match expr {
-                            ast::Expr::ReturnExpr(return_expr) => {
-                                let expr = return_expr.expr();
-                                if let Some(replacement) = make_rewritten_flow(handler, expr) {
-                                    ted::replace(return_expr.syntax(), replacement.syntax())
-                                }
-                            }
-                            ast::Expr::BreakExpr(break_expr) if nested_loop.is_none() => {
-                                let expr = break_expr.expr();
-                                if let Some(replacement) = make_rewritten_flow(handler, expr) {
-                                    ted::replace(break_expr.syntax(), replacement.syntax())
-                                }
+                if nested_scope.is_none()
+                    && let Some(expr) = ast::Expr::cast(e.clone())
+                {
+                    match expr {
+                        ast::Expr::ReturnExpr(return_expr) => {
+                            let expr = return_expr.expr();
+                            if let Some(replacement) = make_rewritten_flow(handler, expr) {
+                                ted::replace(return_expr.syntax(), replacement.syntax())
                             }
-                            ast::Expr::ContinueExpr(continue_expr) if nested_loop.is_none() => {
-                                if let Some(replacement) = make_rewritten_flow(handler, None) {
-                                    ted::replace(continue_expr.syntax(), replacement.syntax())
-                                }
+                        }
+                        ast::Expr::BreakExpr(break_expr) if nested_loop.is_none() => {
+                            let expr = break_expr.expr();
+                            if let Some(replacement) = make_rewritten_flow(handler, expr) {
+                                ted::replace(break_expr.syntax(), replacement.syntax())
                             }
-                            _ => {
-                                // do nothing
+                        }
+                        ast::Expr::ContinueExpr(continue_expr) if nested_loop.is_none() => {
+                            if let Some(replacement) = make_rewritten_flow(handler, None) {
+                                ted::replace(continue_expr.syntax(), replacement.syntax())
                             }
                         }
+                        _ => {
+                            // do nothing
+                        }
                     }
                 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
index b82b7984d4a..c6a6b97df82 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
@@ -69,13 +69,12 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
 
     let mut impl_parent: Option<ast::Impl> = None;
     let mut impl_child_count: usize = 0;
-    if let Some(parent_assoc_list) = node.parent() {
-        if let Some(parent_impl) = parent_assoc_list.parent() {
-            if let Some(impl_) = ast::Impl::cast(parent_impl) {
-                impl_child_count = parent_assoc_list.children().count();
-                impl_parent = Some(impl_);
-            }
-        }
+    if let Some(parent_assoc_list) = node.parent()
+        && let Some(parent_impl) = parent_assoc_list.parent()
+        && let Some(impl_) = ast::Impl::cast(parent_impl)
+    {
+        impl_child_count = parent_assoc_list.children().count();
+        impl_parent = Some(impl_);
     }
 
     let mut curr_parent_module: Option<ast::Module> = None;
@@ -436,10 +435,10 @@ impl Module {
                     }
                 })
                 .for_each(|(node, def)| {
-                    if node_set.insert(node.to_string()) {
-                        if let Some(import) = self.process_def_in_sel(def, &node, &module, ctx) {
-                            check_intersection_and_push(&mut imports_to_remove, import);
-                        }
+                    if node_set.insert(node.to_string())
+                        && let Some(import) = self.process_def_in_sel(def, &node, &module, ctx)
+                    {
+                        check_intersection_and_push(&mut imports_to_remove, import);
                     }
                 })
         }
@@ -542,15 +541,16 @@ impl Module {
                     import_path_to_be_removed = Some(text_range);
                 }
 
-                if def_in_mod && def_out_sel {
-                    if let Some(first_path_in_use_tree) = use_tree_str.last() {
-                        let first_path_in_use_tree_str = first_path_in_use_tree.to_string();
-                        if !first_path_in_use_tree_str.contains("super")
-                            && !first_path_in_use_tree_str.contains("crate")
-                        {
-                            let super_path = make::ext::ident_path("super");
-                            use_tree_str.push(super_path);
-                        }
+                if def_in_mod
+                    && def_out_sel
+                    && let Some(first_path_in_use_tree) = use_tree_str.last()
+                {
+                    let first_path_in_use_tree_str = first_path_in_use_tree.to_string();
+                    if !first_path_in_use_tree_str.contains("super")
+                        && !first_path_in_use_tree_str.contains("crate")
+                    {
+                        let super_path = make::ext::ident_path("super");
+                        use_tree_str.push(super_path);
                     }
                 }
 
@@ -563,12 +563,11 @@ impl Module {
         if let Some(mut use_tree_paths) = use_tree_paths {
             use_tree_paths.reverse();
 
-            if uses_exist_out_sel || !uses_exist_in_sel || !def_in_mod || !def_out_sel {
-                if let Some(first_path_in_use_tree) = use_tree_paths.first() {
-                    if first_path_in_use_tree.to_string().contains("super") {
-                        use_tree_paths.insert(0, make::ext::ident_path("super"));
-                    }
-                }
+            if (uses_exist_out_sel || !uses_exist_in_sel || !def_in_mod || !def_out_sel)
+                && let Some(first_path_in_use_tree) = use_tree_paths.first()
+                && first_path_in_use_tree.to_string().contains("super")
+            {
+                use_tree_paths.insert(0, make::ext::ident_path("super"));
             }
 
             let is_item = matches!(
@@ -691,11 +690,9 @@ fn check_def_in_mod_and_out_sel(
                 _ => source.file_id.original_file(ctx.db()).file_id(ctx.db()) == curr_file_id,
             };
 
-            if have_same_parent {
-                if let ModuleSource::Module(module_) = source.value {
-                    let in_sel = !selection_range.contains_range(module_.syntax().text_range());
-                    return (have_same_parent, in_sel);
-                }
+            if have_same_parent && let ModuleSource::Module(module_) = source.value {
+                let in_sel = !selection_range.contains_range(module_.syntax().text_range());
+                return (have_same_parent, in_sel);
             }
 
             return (have_same_parent, false);
@@ -772,12 +769,12 @@ fn get_use_tree_paths_from_path(
         .filter(|x| x.to_string() != path.to_string())
         .filter_map(ast::UseTree::cast)
         .find_map(|use_tree| {
-            if let Some(upper_tree_path) = use_tree.path() {
-                if upper_tree_path.to_string() != path.to_string() {
-                    use_tree_str.push(upper_tree_path.clone());
-                    get_use_tree_paths_from_path(upper_tree_path, use_tree_str);
-                    return Some(use_tree);
-                }
+            if let Some(upper_tree_path) = use_tree.path()
+                && upper_tree_path.to_string() != path.to_string()
+            {
+                use_tree_str.push(upper_tree_path.clone());
+                get_use_tree_paths_from_path(upper_tree_path, use_tree_str);
+                return Some(use_tree);
             }
             None
         })?;
@@ -786,11 +783,11 @@ fn get_use_tree_paths_from_path(
 }
 
 fn add_change_vis(vis: Option<ast::Visibility>, node_or_token_opt: Option<syntax::SyntaxElement>) {
-    if vis.is_none() {
-        if let Some(node_or_token) = node_or_token_opt {
-            let pub_crate_vis = make::visibility_pub_crate().clone_for_update();
-            ted::insert(ted::Position::before(node_or_token), pub_crate_vis.syntax());
-        }
+    if vis.is_none()
+        && let Some(node_or_token) = node_or_token_opt
+    {
+        let pub_crate_vis = make::visibility_pub_crate().clone_for_update();
+        ted::insert(ted::Position::before(node_or_token), pub_crate_vis.syntax());
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index 9095b1825f5..c56d0b3de5d 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -215,12 +215,12 @@ fn tag_generics_in_variant(ty: &ast::Type, generics: &mut [(ast::GenericParam, b
                 ast::GenericParam::LifetimeParam(lt)
                     if matches!(token.kind(), T![lifetime_ident]) =>
                 {
-                    if let Some(lt) = lt.lifetime() {
-                        if lt.text().as_str() == token.text() {
-                            *tag = true;
-                            tagged_one = true;
-                            break;
-                        }
+                    if let Some(lt) = lt.lifetime()
+                        && lt.text().as_str() == token.text()
+                    {
+                        *tag = true;
+                        tagged_one = true;
+                        break;
                     }
                 }
                 param if matches!(token.kind(), T![ident]) => {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
index d843ac64567..79f22381952 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
@@ -72,10 +72,10 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
             let ty_alias = make::ty_alias("Type", generic_params, None, None, Some((ty, None)))
                 .clone_for_update();
 
-            if let Some(cap) = ctx.config.snippet_cap {
-                if let Some(name) = ty_alias.name() {
-                    edit.add_annotation(name.syntax(), builder.make_tabstop_before(cap));
-                }
+            if let Some(cap) = ctx.config.snippet_cap
+                && let Some(name) = ty_alias.name()
+            {
+                edit.add_annotation(name.syntax(), builder.make_tabstop_before(cap));
             }
 
             let indent = IndentLevel::from_node(node);
@@ -111,17 +111,17 @@ fn collect_used_generics<'gp>(
         match ty {
             ast::Type::PathType(ty) => {
                 if let Some(path) = ty.path() {
-                    if let Some(name_ref) = path.as_single_name_ref() {
-                        if let Some(param) = known_generics.iter().find(|gp| {
+                    if let Some(name_ref) = path.as_single_name_ref()
+                        && let Some(param) = known_generics.iter().find(|gp| {
                             match gp {
                                 ast::GenericParam::ConstParam(cp) => cp.name(),
                                 ast::GenericParam::TypeParam(tp) => tp.name(),
                                 _ => None,
                             }
                             .is_some_and(|n| n.text() == name_ref.text())
-                        }) {
-                            generics.push(param);
-                        }
+                        })
+                    {
+                        generics.push(param);
                     }
                     generics.extend(
                         path.segments()
@@ -160,20 +160,18 @@ fn collect_used_generics<'gp>(
                     .and_then(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
             ),
             ast::Type::ArrayType(ar) => {
-                if let Some(ast::Expr::PathExpr(p)) = ar.const_arg().and_then(|x| x.expr()) {
-                    if let Some(path) = p.path() {
-                        if let Some(name_ref) = path.as_single_name_ref() {
-                            if let Some(param) = known_generics.iter().find(|gp| {
-                                if let ast::GenericParam::ConstParam(cp) = gp {
-                                    cp.name().is_some_and(|n| n.text() == name_ref.text())
-                                } else {
-                                    false
-                                }
-                            }) {
-                                generics.push(param);
-                            }
+                if let Some(ast::Expr::PathExpr(p)) = ar.const_arg().and_then(|x| x.expr())
+                    && let Some(path) = p.path()
+                    && let Some(name_ref) = path.as_single_name_ref()
+                    && let Some(param) = known_generics.iter().find(|gp| {
+                        if let ast::GenericParam::ConstParam(cp) = gp {
+                            cp.name().is_some_and(|n| n.text() == name_ref.text())
+                        } else {
+                            false
                         }
-                    }
+                    })
+                {
+                    generics.push(param);
                 }
             }
             _ => (),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
index db2d316d58e..c9c1969b9e0 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
@@ -404,11 +404,10 @@ impl Anchor {
                 }
                 if let Some(expr) =
                     node.parent().and_then(ast::StmtList::cast).and_then(|it| it.tail_expr())
+                    && expr.syntax() == &node
                 {
-                    if expr.syntax() == &node {
-                        cov_mark::hit!(test_extract_var_last_expr);
-                        return Some(Anchor::Before(node));
-                    }
+                    cov_mark::hit!(test_extract_var_last_expr);
+                    return Some(Anchor::Before(node));
                 }
 
                 if let Some(parent) = node.parent() {
@@ -427,10 +426,10 @@ impl Anchor {
                 }
 
                 if let Some(stmt) = ast::Stmt::cast(node.clone()) {
-                    if let ast::Stmt::ExprStmt(stmt) = stmt {
-                        if stmt.expr().as_ref() == Some(to_extract) {
-                            return Some(Anchor::Replace(stmt));
-                        }
+                    if let ast::Stmt::ExprStmt(stmt) = stmt
+                        && stmt.expr().as_ref() == Some(to_extract)
+                    {
+                        return Some(Anchor::Replace(stmt));
                     }
                     return Some(Anchor::Before(node));
                 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
index 60638980760..2c81e2883a3 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
@@ -2,9 +2,11 @@ use hir::{HasCrate, HasVisibility};
 use ide_db::{FxHashSet, path_transform::PathTransform};
 use syntax::{
     ast::{
-        self, AstNode, HasGenericParams, HasName, HasVisibility as _, edit_in_place::Indent, make,
+        self, AstNode, HasGenericParams, HasName, HasVisibility as _,
+        edit::{AstNodeEdit, IndentLevel},
+        make,
     },
-    ted,
+    syntax_editor::Position,
 };
 
 use crate::{
@@ -165,54 +167,66 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
                     is_unsafe,
                     is_gen,
                 )
-                .clone_for_update();
-
-                // Get the impl to update, or create one if we need to.
-                let impl_def = match impl_def {
-                    Some(impl_def) => edit.make_mut(impl_def),
+                .indent(IndentLevel(1));
+                let item = ast::AssocItem::Fn(f.clone());
+
+                let mut editor = edit.make_editor(strukt.syntax());
+                let fn_: Option<ast::AssocItem> = match impl_def {
+                    Some(impl_def) => match impl_def.assoc_item_list() {
+                        Some(assoc_item_list) => {
+                            let item = item.indent(IndentLevel::from_node(impl_def.syntax()));
+                            assoc_item_list.add_items(&mut editor, vec![item.clone()]);
+                            Some(item)
+                        }
+                        None => {
+                            let assoc_item_list = make::assoc_item_list(Some(vec![item]));
+                            editor.insert(
+                                Position::last_child_of(impl_def.syntax()),
+                                assoc_item_list.syntax(),
+                            );
+                            assoc_item_list.assoc_items().next()
+                        }
+                    },
                     None => {
                         let name = &strukt_name.to_string();
                         let ty_params = strukt.generic_param_list();
                         let ty_args = ty_params.as_ref().map(|it| it.to_generic_args());
                         let where_clause = strukt.where_clause();
+                        let assoc_item_list = make::assoc_item_list(Some(vec![item]));
 
                         let impl_def = make::impl_(
                             ty_params,
                             ty_args,
                             make::ty_path(make::ext::ident_path(name)),
                             where_clause,
-                            None,
+                            Some(assoc_item_list),
                         )
                         .clone_for_update();
 
                         // Fixup impl_def indentation
                         let indent = strukt.indent_level();
-                        impl_def.reindent_to(indent);
+                        let impl_def = impl_def.indent(indent);
 
                         // Insert the impl block.
                         let strukt = edit.make_mut(strukt.clone());
-                        ted::insert_all(
-                            ted::Position::after(strukt.syntax()),
+                        editor.insert_all(
+                            Position::after(strukt.syntax()),
                             vec![
                                 make::tokens::whitespace(&format!("\n\n{indent}")).into(),
                                 impl_def.syntax().clone().into(),
                             ],
                         );
-
-                        impl_def
+                        impl_def.assoc_item_list().and_then(|list| list.assoc_items().next())
                     }
                 };
 
-                // Fixup function indentation.
-                // FIXME: Should really be handled by `AssocItemList::add_item`
-                f.reindent_to(impl_def.indent_level() + 1);
-
-                let assoc_items = impl_def.get_or_create_assoc_item_list();
-                assoc_items.add_item(f.clone().into());
-
-                if let Some(cap) = ctx.config.snippet_cap {
-                    edit.add_tabstop_before(cap, f)
+                if let Some(cap) = ctx.config.snippet_cap
+                    && let Some(fn_) = fn_
+                {
+                    let tabstop = edit.make_tabstop_before(cap);
+                    editor.add_annotation(fn_.syntax(), tabstop);
                 }
+                edit.add_file_edits(ctx.vfs_file_id(), editor);
             },
         )?;
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs
index d4d1b3490cb..77232dfebdf 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_documentation_template.rs
@@ -148,11 +148,11 @@ fn make_example_for_fn(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<St
     let self_name = self_name(ast_func);
 
     format_to!(example, "use {use_path};\n\n");
-    if let Some(self_name) = &self_name {
-        if let Some(mut_) = is_ref_mut_self(ast_func) {
-            let mut_ = if mut_ { "mut " } else { "" };
-            format_to!(example, "let {mut_}{self_name} = ;\n");
-        }
+    if let Some(self_name) = &self_name
+        && let Some(mut_) = is_ref_mut_self(ast_func)
+    {
+        let mut_ = if mut_ { "mut " } else { "" };
+        format_to!(example, "let {mut_}{self_name} = ;\n");
     }
     for param_name in &ref_mut_params {
         format_to!(example, "let mut {param_name} = ;\n");
@@ -170,10 +170,10 @@ fn make_example_for_fn(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<St
         format_to!(example, "{function_call};\n");
     }
     // Check the mutated values
-    if let Some(self_name) = &self_name {
-        if is_ref_mut_self(ast_func) == Some(true) {
-            format_to!(example, "assert_eq!({self_name}, );");
-        }
+    if let Some(self_name) = &self_name
+        && is_ref_mut_self(ast_func) == Some(true)
+    {
+        format_to!(example, "assert_eq!({self_name}, );");
     }
     for param_name in &ref_mut_params {
         format_to!(example, "assert_eq!({param_name}, );");
@@ -313,12 +313,28 @@ fn crate_name(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<String> {
 /// `None` if function without a body; some bool to guess if function can panic
 fn can_panic(ast_func: &ast::Fn) -> Option<bool> {
     let body = ast_func.body()?.to_string();
-    let can_panic = body.contains("panic!(")
-        // FIXME it would be better to not match `debug_assert*!` macro invocations
-        || body.contains("assert!(")
-        || body.contains(".unwrap()")
-        || body.contains(".expect(");
-    Some(can_panic)
+    let mut iter = body.chars();
+    let assert_postfix = |s| {
+        ["!(", "_eq!(", "_ne!(", "_matches!("].iter().any(|postfix| str::starts_with(s, postfix))
+    };
+
+    while !iter.as_str().is_empty() {
+        let s = iter.as_str();
+        iter.next();
+        if s.strip_prefix("debug_assert").is_some_and(assert_postfix) {
+            iter.nth(10);
+            continue;
+        }
+        if s.strip_prefix("assert").is_some_and(assert_postfix)
+            || s.starts_with("panic!(")
+            || s.starts_with(".unwrap()")
+            || s.starts_with(".expect(")
+        {
+            return Some(true);
+        }
+    }
+
+    Some(false)
 }
 
 /// Helper function to get the name that should be given to `self` arguments
@@ -678,6 +694,24 @@ pub fn panics_if(a: bool) {
     }
 
     #[test]
+    fn guesses_debug_assert_macro_cannot_panic() {
+        check_assist(
+            generate_documentation_template,
+            r#"
+pub fn $0debug_panics_if_not(a: bool) {
+    debug_assert!(a == true);
+}
+"#,
+            r#"
+/// .
+pub fn debug_panics_if_not(a: bool) {
+    debug_assert!(a == true);
+}
+"#,
+        );
+    }
+
+    #[test]
     fn guesses_assert_macro_can_panic() {
         check_assist(
             generate_documentation_template,
@@ -700,6 +734,28 @@ pub fn panics_if_not(a: bool) {
     }
 
     #[test]
+    fn guesses_assert_eq_macro_can_panic() {
+        check_assist(
+            generate_documentation_template,
+            r#"
+pub fn $0panics_if_not(a: bool) {
+    assert_eq!(a, true);
+}
+"#,
+            r#"
+/// .
+///
+/// # Panics
+///
+/// Panics if .
+pub fn panics_if_not(a: bool) {
+    assert_eq!(a, true);
+}
+"#,
+        );
+    }
+
+    #[test]
     fn guesses_unwrap_can_panic() {
         check_assist(
             generate_documentation_template,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs
index b63baa696d9..3c327a63b0f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs
@@ -111,10 +111,10 @@ pub(crate) fn generate_fn_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>)
                     ],
                 );
 
-                if let Some(cap) = ctx.config.snippet_cap {
-                    if let Some(name) = ty_alias.name() {
-                        edit.add_annotation(name.syntax(), builder.make_placeholder_snippet(cap));
-                    }
+                if let Some(cap) = ctx.config.snippet_cap
+                    && let Some(name) = ty_alias.name()
+                {
+                    edit.add_annotation(name.syntax(), builder.make_placeholder_snippet(cap));
                 }
 
                 builder.add_file_edits(ctx.vfs_file_id(), edit);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
index 3290a70e1c6..613b32fcc16 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
@@ -70,10 +70,10 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let TargetInfo { target_module, adt_info, target, file } =
         fn_target_info(ctx, path, &call, fn_name)?;
 
-    if let Some(m) = target_module {
-        if !is_editable_crate(m.krate(), ctx.db()) {
-            return None;
-        }
+    if let Some(m) = target_module
+        && !is_editable_crate(m.krate(), ctx.db())
+    {
+        return None;
     }
 
     let function_builder =
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs
index 20ee9253d37..807b9194b2d 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs
@@ -433,12 +433,11 @@ fn build_source_change(
         new_fn.indent(1.into());
 
         // Insert a tabstop only for last method we generate
-        if i == record_fields_count - 1 {
-            if let Some(cap) = ctx.config.snippet_cap {
-                if let Some(name) = new_fn.name() {
-                    builder.add_tabstop_before(cap, name);
-                }
-            }
+        if i == record_fields_count - 1
+            && let Some(cap) = ctx.config.snippet_cap
+            && let Some(name) = new_fn.name()
+        {
+            builder.add_tabstop_before(cap, name);
         }
 
         assoc_item_list.add_item(new_fn.clone().into());
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
index 31cadcf5ea8..b38ee6f7dce 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
@@ -58,11 +58,11 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
 
             let mut editor = edit.make_editor(nominal.syntax());
             // Add a tabstop after the left curly brace
-            if let Some(cap) = ctx.config.snippet_cap {
-                if let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) {
-                    let tabstop = edit.make_tabstop_after(cap);
-                    editor.add_annotation(l_curly, tabstop);
-                }
+            if let Some(cap) = ctx.config.snippet_cap
+                && let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token())
+            {
+                let tabstop = edit.make_tabstop_after(cap);
+                editor.add_annotation(l_curly, tabstop);
             }
 
             insert_impl(&mut editor, &impl_, &nominal);
@@ -201,7 +201,6 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) ->
                     &impl_,
                     &target_scope,
                 );
-                let assoc_items = assoc_items.into_iter().map(either::Either::Right).collect();
                 let assoc_item_list = make::assoc_item_list(Some(assoc_items));
                 make_impl_(Some(assoc_item_list))
             };
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs
index 9c4bcdd4030..ae1ae24d1ec 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs
@@ -104,7 +104,14 @@ pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>
         format!("Generate `{trait_new}` impl from this `{trait_name}` trait"),
         target,
         |edit| {
-            edit.insert(target.start(), format!("$0{impl_def}\n\n{indent}"));
+            edit.insert(
+                target.start(),
+                if ctx.config.snippet_cap.is_some() {
+                    format!("$0{impl_def}\n\n{indent}")
+                } else {
+                    format!("{impl_def}\n\n{indent}")
+                },
+            );
         },
     )
 }
@@ -161,7 +168,10 @@ fn process_ret_type(ref_ty: &ast::RetType) -> Option<ast::Type> {
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable};
+    use crate::{
+        AssistConfig,
+        tests::{TEST_CONFIG, check_assist, check_assist_not_applicable, check_assist_with_config},
+    };
 
     use super::*;
 
@@ -405,4 +415,41 @@ impl AsRef$0<i32> for [T; 3] {}
 "#,
         );
     }
+
+    #[test]
+    fn no_snippets() {
+        check_assist_with_config(
+            generate_mut_trait_impl,
+            AssistConfig { snippet_cap: None, ..TEST_CONFIG },
+            r#"
+//- minicore: index
+pub enum Axis { X = 0, Y = 1, Z = 2 }
+
+impl<T> core::ops::Index$0<Axis> for [T; 3] {
+    type Output = T;
+
+    fn index(&self, index: Axis) -> &Self::Output {
+        &self[index as usize]
+    }
+}
+"#,
+            r#"
+pub enum Axis { X = 0, Y = 1, Z = 2 }
+
+impl<T> core::ops::IndexMut<Axis> for [T; 3] {
+    fn index_mut(&mut self, index: Axis) -> &mut Self::Output {
+        &mut self[index as usize]
+    }
+}
+
+impl<T> core::ops::Index<Axis> for [T; 3] {
+    type Output = T;
+
+    fn index(&self, index: Axis) -> &Self::Output {
+        &self[index as usize]
+    }
+}
+"#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
index 5bda1226cda..351f134612f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
@@ -168,7 +168,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
                 );
                 fn_.syntax().clone()
             } else {
-                let items = vec![either::Either::Right(ast::AssocItem::Fn(fn_))];
+                let items = vec![ast::AssocItem::Fn(fn_)];
                 let list = make::assoc_item_list(Some(items));
                 editor.insert(Position::after(impl_def.syntax()), list.syntax());
                 list.syntax().clone()
@@ -176,7 +176,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
         } else {
             // Generate a new impl to add the method to
             let indent_level = strukt.indent_level();
-            let body = vec![either::Either::Right(ast::AssocItem::Fn(fn_))];
+            let body = vec![ast::AssocItem::Fn(fn_)];
             let list = make::assoc_item_list(Some(body));
             let impl_def = generate_impl_with_item(&ast::Adt::Struct(strukt.clone()), Some(list));
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs
index 92a4bd35b3e..56500cf0680 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs
@@ -2,12 +2,8 @@ use crate::assist_context::{AssistContext, Assists};
 use ide_db::assists::AssistId;
 use syntax::{
     AstNode, SyntaxKind, T,
-    ast::{
-        self, HasGenericParams, HasName, HasVisibility,
-        edit_in_place::{HasVisibilityEdit, Indent},
-        make,
-    },
-    ted::{self, Position},
+    ast::{self, HasGenericParams, HasName, HasVisibility, edit_in_place::Indent, make},
+    syntax_editor::{Position, SyntaxEditor},
 };
 
 // NOTES :
@@ -88,8 +84,8 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
         return None;
     }
 
-    let assoc_items = impl_ast.assoc_item_list()?;
-    let first_element = assoc_items.assoc_items().next();
+    let impl_assoc_items = impl_ast.assoc_item_list()?;
+    let first_element = impl_assoc_items.assoc_items().next();
     first_element.as_ref()?;
 
     let impl_name = impl_ast.self_ty()?;
@@ -99,20 +95,16 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
         "Generate trait from impl",
         impl_ast.syntax().text_range(),
         |builder| {
-            let impl_ast = builder.make_mut(impl_ast);
-            let trait_items = assoc_items.clone_for_update();
-            let impl_items = builder.make_mut(assoc_items);
-            let impl_name = builder.make_mut(impl_name);
-
-            trait_items.assoc_items().for_each(|item| {
-                strip_body(&item);
-                remove_items_visibility(&item);
-            });
-
-            impl_items.assoc_items().for_each(|item| {
-                remove_items_visibility(&item);
-            });
-
+            let trait_items: ast::AssocItemList = {
+                let trait_items = impl_assoc_items.clone_subtree();
+                let mut trait_items_editor = SyntaxEditor::new(trait_items.syntax().clone());
+
+                trait_items.assoc_items().for_each(|item| {
+                    strip_body(&mut trait_items_editor, &item);
+                    remove_items_visibility(&mut trait_items_editor, &item);
+                });
+                ast::AssocItemList::cast(trait_items_editor.finish().new_root().clone()).unwrap()
+            };
             let trait_ast = make::trait_(
                 false,
                 "NewTrait",
@@ -130,6 +122,7 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
                 trait_name_ref.syntax().clone().into(),
                 make::tokens::single_space().into(),
                 make::token(T![for]).into(),
+                make::tokens::single_space().into(),
             ];
 
             if let Some(params) = impl_ast.generic_param_list() {
@@ -137,10 +130,15 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
                 elements.insert(1, gen_args.syntax().clone().into());
             }
 
-            ted::insert_all(Position::before(impl_name.syntax()), elements);
+            let mut editor = builder.make_editor(impl_ast.syntax());
+            impl_assoc_items.assoc_items().for_each(|item| {
+                remove_items_visibility(&mut editor, &item);
+            });
+
+            editor.insert_all(Position::before(impl_name.syntax()), elements);
 
             // Insert trait before TraitImpl
-            ted::insert_all_raw(
+            editor.insert_all(
                 Position::before(impl_ast.syntax()),
                 vec![
                     trait_ast.syntax().clone().into(),
@@ -150,11 +148,12 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
 
             // Link the trait name & trait ref names together as a placeholder snippet group
             if let Some(cap) = ctx.config.snippet_cap {
-                builder.add_placeholder_snippet_group(
-                    cap,
-                    vec![trait_name.syntax().clone(), trait_name_ref.syntax().clone()],
-                );
+                let placeholder = builder.make_placeholder_snippet(cap);
+                editor.add_annotation(trait_name.syntax(), placeholder);
+                editor.add_annotation(trait_name_ref.syntax(), placeholder);
             }
+
+            builder.add_file_edits(ctx.vfs_file_id(), editor);
         },
     );
 
@@ -162,31 +161,33 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
 }
 
 /// `E0449` Trait items always share the visibility of their trait
-fn remove_items_visibility(item: &ast::AssocItem) {
+fn remove_items_visibility(editor: &mut SyntaxEditor, item: &ast::AssocItem) {
     if let Some(has_vis) = ast::AnyHasVisibility::cast(item.syntax().clone()) {
         if let Some(vis) = has_vis.visibility()
             && let Some(token) = vis.syntax().next_sibling_or_token()
             && token.kind() == SyntaxKind::WHITESPACE
         {
-            ted::remove(token);
+            editor.delete(token);
+        }
+        if let Some(vis) = has_vis.visibility() {
+            editor.delete(vis.syntax());
         }
-        has_vis.set_visibility(None);
     }
 }
 
-fn strip_body(item: &ast::AssocItem) {
-    if let ast::AssocItem::Fn(f) = item {
-        if let Some(body) = f.body() {
-            // In contrast to function bodies, we want to see no ws before a semicolon.
-            // So let's remove them if we see any.
-            if let Some(prev) = body.syntax().prev_sibling_or_token() {
-                if prev.kind() == SyntaxKind::WHITESPACE {
-                    ted::remove(prev);
-                }
-            }
-
-            ted::replace(body.syntax(), make::tokens::semicolon());
+fn strip_body(editor: &mut SyntaxEditor, item: &ast::AssocItem) {
+    if let ast::AssocItem::Fn(f) = item
+        && let Some(body) = f.body()
+    {
+        // In contrast to function bodies, we want to see no ws before a semicolon.
+        // So let's remove them if we see any.
+        if let Some(prev) = body.syntax().prev_sibling_or_token()
+            && prev.kind() == SyntaxKind::WHITESPACE
+        {
+            editor.delete(prev);
         }
+
+        editor.replace(body.syntax(), make::tokens::semicolon());
     };
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
index 1549b414dcc..5367350052c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
@@ -393,19 +393,17 @@ fn inline(
     // `FileReference` incorrect
     if let Some(imp) =
         sema.ancestors_with_macros(fn_body.syntax().clone()).find_map(ast::Impl::cast)
+        && !node.syntax().ancestors().any(|anc| &anc == imp.syntax())
+        && let Some(t) = imp.self_ty()
     {
-        if !node.syntax().ancestors().any(|anc| &anc == imp.syntax()) {
-            if let Some(t) = imp.self_ty() {
-                while let Some(self_tok) = body
-                    .syntax()
-                    .descendants_with_tokens()
-                    .filter_map(NodeOrToken::into_token)
-                    .find(|tok| tok.kind() == SyntaxKind::SELF_TYPE_KW)
-                {
-                    let replace_with = t.clone_subtree().syntax().clone_for_update();
-                    ted::replace(self_tok, replace_with);
-                }
-            }
+        while let Some(self_tok) = body
+            .syntax()
+            .descendants_with_tokens()
+            .filter_map(NodeOrToken::into_token)
+            .find(|tok| tok.kind() == SyntaxKind::SELF_TYPE_KW)
+        {
+            let replace_with = t.clone_subtree().syntax().clone_for_update();
+            ted::replace(self_tok, replace_with);
         }
     }
 
@@ -415,10 +413,10 @@ fn inline(
     for stmt in fn_body.statements() {
         if let Some(let_stmt) = ast::LetStmt::cast(stmt.syntax().to_owned()) {
             for has_token in let_stmt.syntax().children_with_tokens() {
-                if let Some(node) = has_token.as_node() {
-                    if let Some(ident_pat) = ast::IdentPat::cast(node.to_owned()) {
-                        func_let_vars.insert(ident_pat.syntax().text().to_string());
-                    }
+                if let Some(node) = has_token.as_node()
+                    && let Some(ident_pat) = ast::IdentPat::cast(node.to_owned())
+                {
+                    func_let_vars.insert(ident_pat.syntax().text().to_string());
                 }
             }
         }
@@ -534,16 +532,15 @@ fn inline(
         }
     }
 
-    if let Some(generic_arg_list) = generic_arg_list.clone() {
-        if let Some((target, source)) = &sema.scope(node.syntax()).zip(sema.scope(fn_body.syntax()))
-        {
-            body.reindent_to(IndentLevel(0));
-            if let Some(new_body) = ast::BlockExpr::cast(
-                PathTransform::function_call(target, source, function, generic_arg_list)
-                    .apply(body.syntax()),
-            ) {
-                body = new_body;
-            }
+    if let Some(generic_arg_list) = generic_arg_list.clone()
+        && let Some((target, source)) = &sema.scope(node.syntax()).zip(sema.scope(fn_body.syntax()))
+    {
+        body.reindent_to(IndentLevel(0));
+        if let Some(new_body) = ast::BlockExpr::cast(
+            PathTransform::function_call(target, source, function, generic_arg_list)
+                .apply(body.syntax()),
+        ) {
+            body = new_body;
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
index 4511072b041..ae8d130df23 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
@@ -9,10 +9,11 @@ use ide_db::{
     search::FileReference,
 };
 use itertools::Itertools;
+use syntax::ast::syntax_factory::SyntaxFactory;
+use syntax::syntax_editor::SyntaxEditor;
 use syntax::{
     AstNode, NodeOrToken, SyntaxNode,
-    ast::{self, HasGenericParams, HasName, make},
-    ted,
+    ast::{self, HasGenericParams, HasName},
 };
 
 use crate::{
@@ -68,37 +69,41 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>)
             let mut definition_deleted = false;
 
             let mut inline_refs_for_file = |file_id, refs: Vec<FileReference>| {
-                builder.edit_file(file_id);
+                let source = ctx.sema.parse(file_id);
+                let mut editor = builder.make_editor(source.syntax());
 
                 let (path_types, path_type_uses) =
                     split_refs_and_uses(builder, refs, |path_type| {
                         path_type.syntax().ancestors().nth(3).and_then(ast::PathType::cast)
                     });
-
                 path_type_uses
                     .iter()
                     .flat_map(ast_to_remove_for_path_in_use_stmt)
-                    .for_each(|x| builder.delete(x.syntax().text_range()));
+                    .for_each(|x| editor.delete(x.syntax()));
+
                 for (target, replacement) in path_types.into_iter().filter_map(|path_type| {
-                    let replacement = inline(&ast_alias, &path_type)?.to_text(&concrete_type);
-                    let target = path_type.syntax().text_range();
+                    let replacement =
+                        inline(&ast_alias, &path_type)?.replace_generic(&concrete_type);
+                    let target = path_type.syntax().clone();
                     Some((target, replacement))
                 }) {
-                    builder.replace(target, replacement);
+                    editor.replace(target, replacement);
                 }
 
-                if file_id == ctx.vfs_file_id() {
-                    builder.delete(ast_alias.syntax().text_range());
+                if file_id.file_id(ctx.db()) == ctx.vfs_file_id() {
+                    editor.delete(ast_alias.syntax());
                     definition_deleted = true;
                 }
+                builder.add_file_edits(file_id.file_id(ctx.db()), editor);
             };
 
             for (file_id, refs) in usages.into_iter() {
-                inline_refs_for_file(file_id.file_id(ctx.db()), refs);
+                inline_refs_for_file(file_id, refs);
             }
             if !definition_deleted {
-                builder.edit_file(ctx.vfs_file_id());
-                builder.delete(ast_alias.syntax().text_range());
+                let mut editor = builder.make_editor(ast_alias.syntax());
+                editor.delete(ast_alias.syntax());
+                builder.add_file_edits(ctx.vfs_file_id(), editor)
             }
         },
     )
@@ -146,23 +151,26 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
         }
     }
 
-    let target = alias_instance.syntax().text_range();
-
     acc.add(
         AssistId::refactor_inline("inline_type_alias"),
         "Inline type alias",
-        target,
-        |builder| builder.replace(target, replacement.to_text(&concrete_type)),
+        alias_instance.syntax().text_range(),
+        |builder| {
+            let mut editor = builder.make_editor(alias_instance.syntax());
+            let replace = replacement.replace_generic(&concrete_type);
+            editor.replace(alias_instance.syntax(), replace);
+            builder.add_file_edits(ctx.vfs_file_id(), editor);
+        },
     )
 }
 
 impl Replacement {
-    fn to_text(&self, concrete_type: &ast::Type) -> String {
+    fn replace_generic(&self, concrete_type: &ast::Type) -> SyntaxNode {
         match self {
             Replacement::Generic { lifetime_map, const_and_type_map } => {
                 create_replacement(lifetime_map, const_and_type_map, concrete_type)
             }
-            Replacement::Plain => concrete_type.to_string(),
+            Replacement::Plain => concrete_type.syntax().clone_subtree().clone_for_update(),
         }
     }
 }
@@ -199,8 +207,8 @@ impl LifetimeMap {
         alias_generics: &ast::GenericParamList,
     ) -> Option<Self> {
         let mut inner = FxHashMap::default();
-
-        let wildcard_lifetime = make::lifetime("'_");
+        let make = SyntaxFactory::without_mappings();
+        let wildcard_lifetime = make.lifetime("'_");
         let lifetimes = alias_generics
             .lifetime_params()
             .filter_map(|lp| lp.lifetime())
@@ -299,15 +307,14 @@ fn create_replacement(
     lifetime_map: &LifetimeMap,
     const_and_type_map: &ConstAndTypeMap,
     concrete_type: &ast::Type,
-) -> String {
-    let updated_concrete_type = concrete_type.clone_for_update();
-    let mut replacements = Vec::new();
-    let mut removals = Vec::new();
+) -> SyntaxNode {
+    let updated_concrete_type = concrete_type.syntax().clone_subtree();
+    let mut editor = SyntaxEditor::new(updated_concrete_type.clone());
 
-    for syntax in updated_concrete_type.syntax().descendants() {
-        let syntax_string = syntax.to_string();
-        let syntax_str = syntax_string.as_str();
+    let mut replacements: Vec<(SyntaxNode, SyntaxNode)> = Vec::new();
+    let mut removals: Vec<NodeOrToken<SyntaxNode, _>> = Vec::new();
 
+    for syntax in updated_concrete_type.descendants() {
         if let Some(old_lifetime) = ast::Lifetime::cast(syntax.clone()) {
             if let Some(new_lifetime) = lifetime_map.0.get(&old_lifetime.to_string()) {
                 if new_lifetime.text() == "'_" {
@@ -322,12 +329,16 @@ fn create_replacement(
 
                 replacements.push((syntax.clone(), new_lifetime.syntax().clone_for_update()));
             }
-        } else if let Some(replacement_syntax) = const_and_type_map.0.get(syntax_str) {
+        } else if let Some(name_ref) = ast::NameRef::cast(syntax.clone()) {
+            let Some(replacement_syntax) = const_and_type_map.0.get(&name_ref.to_string()) else {
+                continue;
+            };
             let new_string = replacement_syntax.to_string();
             let new = if new_string == "_" {
-                make::wildcard_pat().syntax().clone_for_update()
+                let make = SyntaxFactory::without_mappings();
+                make.wildcard_pat().syntax().clone()
             } else {
-                replacement_syntax.clone_for_update()
+                replacement_syntax.clone()
             };
 
             replacements.push((syntax.clone(), new));
@@ -335,14 +346,13 @@ fn create_replacement(
     }
 
     for (old, new) in replacements {
-        ted::replace(old, new);
+        editor.replace(old, new);
     }
 
     for syntax in removals {
-        ted::remove(syntax);
+        editor.delete(syntax);
     }
-
-    updated_concrete_type.to_string()
+    editor.finish().new_root().clone()
 }
 
 fn get_type_alias(ctx: &AssistContext<'_>, path: &ast::PathType) -> Option<ast::TypeAlias> {
@@ -377,12 +387,15 @@ impl ConstOrTypeGeneric {
     }
 
     fn replacement_value(&self) -> Option<SyntaxNode> {
-        Some(match self {
-            ConstOrTypeGeneric::ConstArg(ca) => ca.expr()?.syntax().clone(),
-            ConstOrTypeGeneric::TypeArg(ta) => ta.syntax().clone(),
-            ConstOrTypeGeneric::ConstParam(cp) => cp.default_val()?.syntax().clone(),
-            ConstOrTypeGeneric::TypeParam(tp) => tp.default_type()?.syntax().clone(),
-        })
+        Some(
+            match self {
+                ConstOrTypeGeneric::ConstArg(ca) => ca.expr()?.syntax().clone(),
+                ConstOrTypeGeneric::TypeArg(ta) => ta.syntax().clone(),
+                ConstOrTypeGeneric::ConstParam(cp) => cp.default_val()?.syntax().clone(),
+                ConstOrTypeGeneric::TypeParam(tp) => tp.default_type()?.syntax().clone(),
+            }
+            .clone_for_update(),
+        )
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs
index 0c1dc9eb934..a645c8b90af 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs
@@ -43,10 +43,10 @@ pub(crate) fn move_const_to_impl(acc: &mut Assists, ctx: &AssistContext<'_>) ->
     let db = ctx.db();
     let const_: ast::Const = ctx.find_node_at_offset()?;
     // Don't show the assist when the cursor is at the const's body.
-    if let Some(body) = const_.body() {
-        if body.syntax().text_range().contains(ctx.offset()) {
-            return None;
-        }
+    if let Some(body) = const_.body()
+        && body.syntax().text_range().contains(ctx.offset())
+    {
+        return None;
     }
 
     let parent_fn = const_.syntax().ancestors().find_map(ast::Fn::cast)?;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs
index 1b0c3139353..21debf6745a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs
@@ -62,10 +62,10 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) ->
         return None;
     };
 
-    if let Some(parent) = tgt.syntax().parent() {
-        if matches!(parent.kind(), syntax::SyntaxKind::BIN_EXPR | syntax::SyntaxKind::LET_STMT) {
-            return None;
-        }
+    if let Some(parent) = tgt.syntax().parent()
+        && matches!(parent.kind(), syntax::SyntaxKind::BIN_EXPR | syntax::SyntaxKind::LET_STMT)
+    {
+        return None;
     }
     let target = tgt.syntax().text_range();
 
@@ -90,10 +90,10 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) ->
     let mut editor = SyntaxEditor::new(edit_tgt);
     for (stmt, rhs) in assignments {
         let mut stmt = stmt.syntax().clone();
-        if let Some(parent) = stmt.parent() {
-            if ast::ExprStmt::cast(parent.clone()).is_some() {
-                stmt = parent.clone();
-            }
+        if let Some(parent) = stmt.parent()
+            && ast::ExprStmt::cast(parent.clone()).is_some()
+        {
+            stmt = parent.clone();
         }
         editor.replace(stmt, rhs.syntax());
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
index 94b49c5df09..2cbb24a64fd 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
@@ -80,15 +80,15 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
             // parse inside string to escape `"`
             let escaped = value.escape_default().to_string();
             let suffix = string_suffix(token.text()).unwrap_or_default();
-            if let Some(offsets) = token.quote_offsets() {
-                if token.text()[offsets.contents - token.syntax().text_range().start()] == escaped {
-                    let end_quote = offsets.quotes.1;
-                    let end_quote =
-                        TextRange::new(end_quote.start(), end_quote.end() - TextSize::of(suffix));
-                    edit.replace(offsets.quotes.0, "\"");
-                    edit.replace(end_quote, "\"");
-                    return;
-                }
+            if let Some(offsets) = token.quote_offsets()
+                && token.text()[offsets.contents - token.syntax().text_range().start()] == escaped
+            {
+                let end_quote = offsets.quotes.1;
+                let end_quote =
+                    TextRange::new(end_quote.start(), end_quote.end() - TextSize::of(suffix));
+                edit.replace(offsets.quotes.0, "\"");
+                edit.replace(end_quote, "\"");
+                return;
             }
 
             edit.replace(token.syntax().text_range(), format!("\"{escaped}\"{suffix}"));
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index 45bb6ce9129..175f2613170 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -221,11 +221,7 @@ fn impl_def_from_trait(
         } else {
             Some(first.clone())
         };
-        let items = first_item
-            .into_iter()
-            .chain(other.iter().cloned())
-            .map(either::Either::Right)
-            .collect();
+        let items = first_item.into_iter().chain(other.iter().cloned()).collect();
         make::assoc_item_list(Some(items))
     } else {
         make::assoc_item_list(None)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
index fa005a411d3..9f742131e5c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
@@ -102,10 +102,10 @@ pub(crate) fn replace_qualified_name_with_use(
 
 fn drop_generic_args(path: &ast::Path) -> ast::Path {
     let path = path.clone_for_update();
-    if let Some(segment) = path.segment() {
-        if let Some(generic_args) = segment.generic_arg_list() {
-            ted::remove(generic_args.syntax());
-        }
+    if let Some(segment) = path.segment()
+        && let Some(generic_args) = segment.generic_arg_list()
+    {
+        ted::remove(generic_args.syntax());
     }
     path
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
index ac10a829bbf..b9385775b47 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
@@ -41,10 +41,10 @@ pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
         return None;
     }
     // Do nothing if the method is a member of trait.
-    if let Some(impl_) = function.syntax().ancestors().nth(2).and_then(ast::Impl::cast) {
-        if impl_.trait_().is_some() {
-            return None;
-        }
+    if let Some(impl_) = function.syntax().ancestors().nth(2).and_then(ast::Impl::cast)
+        && impl_.trait_().is_some()
+    {
+        return None;
     }
 
     // Remove the `async` keyword plus whitespace after it, if any.
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs
index cf38262fbf4..eea6c85e8df 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs
@@ -72,20 +72,20 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) ->
         let mut exprs_to_unwrap = Vec::new();
         let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_unwrap, e);
         walk_expr(&body_expr, &mut |expr| {
-            if let ast::Expr::ReturnExpr(ret_expr) = expr {
-                if let Some(ret_expr_arg) = &ret_expr.expr() {
-                    for_each_tail_expr(ret_expr_arg, tail_cb);
-                }
+            if let ast::Expr::ReturnExpr(ret_expr) = expr
+                && let Some(ret_expr_arg) = &ret_expr.expr()
+            {
+                for_each_tail_expr(ret_expr_arg, tail_cb);
             }
         });
         for_each_tail_expr(&body_expr, tail_cb);
 
         let is_unit_type = is_unit_type(&happy_type);
         if is_unit_type {
-            if let Some(NodeOrToken::Token(token)) = ret_type.syntax().next_sibling_or_token() {
-                if token.kind() == SyntaxKind::WHITESPACE {
-                    editor.delete(token);
-                }
+            if let Some(NodeOrToken::Token(token)) = ret_type.syntax().next_sibling_or_token()
+                && token.kind() == SyntaxKind::WHITESPACE
+            {
+                editor.delete(token);
             }
 
             editor.delete(ret_type.syntax());
@@ -162,10 +162,10 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) ->
             }
         }
 
-        if let Some(cap) = ctx.config.snippet_cap {
-            if let Some(final_placeholder) = final_placeholder {
-                editor.add_annotation(final_placeholder.syntax(), builder.make_tabstop_after(cap));
-            }
+        if let Some(cap) = ctx.config.snippet_cap
+            && let Some(final_placeholder) = final_placeholder
+        {
+            editor.add_annotation(final_placeholder.syntax(), builder.make_tabstop_after(cap));
         }
 
         editor.add_mappings(make.finish_with_mappings());
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
index ecfecbb04ff..46f3e85e123 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
@@ -47,10 +47,10 @@ pub(crate) fn unwrap_tuple(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
     if tuple_pat.fields().count() != tuple_init.fields().count() {
         return None;
     }
-    if let Some(tys) = &tuple_ty {
-        if tuple_pat.fields().count() != tys.fields().count() {
-            return None;
-        }
+    if let Some(tys) = &tuple_ty
+        && tuple_pat.fields().count() != tys.fields().count()
+    {
+        return None;
     }
 
     let parent = let_kw.parent()?;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs
index d7189aa5dbb..0f089c9b66e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs
@@ -101,24 +101,24 @@ pub(crate) fn wrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
                 let mut exprs_to_wrap = Vec::new();
                 let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_wrap, e);
                 walk_expr(&body_expr, &mut |expr| {
-                    if let Expr::ReturnExpr(ret_expr) = expr {
-                        if let Some(ret_expr_arg) = &ret_expr.expr() {
-                            for_each_tail_expr(ret_expr_arg, tail_cb);
-                        }
+                    if let Expr::ReturnExpr(ret_expr) = expr
+                        && let Some(ret_expr_arg) = &ret_expr.expr()
+                    {
+                        for_each_tail_expr(ret_expr_arg, tail_cb);
                     }
                 });
                 for_each_tail_expr(&body_expr, tail_cb);
 
                 for ret_expr_arg in exprs_to_wrap {
-                    if let Some(ty) = ctx.sema.type_of_expr(&ret_expr_arg) {
-                        if ty.adjusted().could_unify_with(ctx.db(), &semantic_new_return_ty) {
-                            // The type is already correct, don't wrap it.
-                            // We deliberately don't use `could_unify_with_deeply()`, because as long as the outer
-                            // enum matches it's okay for us, as we don't trigger the assist if the return type
-                            // is already `Option`/`Result`, so mismatched exact type is more likely a mistake
-                            // than something intended.
-                            continue;
-                        }
+                    if let Some(ty) = ctx.sema.type_of_expr(&ret_expr_arg)
+                        && ty.adjusted().could_unify_with(ctx.db(), &semantic_new_return_ty)
+                    {
+                        // The type is already correct, don't wrap it.
+                        // We deliberately don't use `could_unify_with_deeply()`, because as long as the outer
+                        // enum matches it's okay for us, as we don't trigger the assist if the return type
+                        // is already `Option`/`Result`, so mismatched exact type is more likely a mistake
+                        // than something intended.
+                        continue;
                     }
 
                     let happy_wrapped = make.expr_call(
@@ -147,13 +147,13 @@ pub(crate) fn wrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
                         ast::GenericArg::LifetimeArg(_) => false,
                         _ => true,
                     });
-                    if let Some(error_type_arg) = error_type_arg {
-                        if let Some(cap) = ctx.config.snippet_cap {
-                            editor.add_annotation(
-                                error_type_arg.syntax(),
-                                builder.make_placeholder_snippet(cap),
-                            );
-                        }
+                    if let Some(error_type_arg) = error_type_arg
+                        && let Some(cap) = ctx.config.snippet_cap
+                    {
+                        editor.add_annotation(
+                            error_type_arg.syntax(),
+                            builder.make_placeholder_snippet(cap),
+                        );
                     }
                 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
index 5183566d136..7d5740b748b 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
@@ -200,13 +200,12 @@ fn wrap_derive(
             ],
         );
 
-        if let Some(snippet_cap) = ctx.config.snippet_cap {
-            if let Some(first_meta) =
+        if let Some(snippet_cap) = ctx.config.snippet_cap
+            && let Some(first_meta) =
                 cfg_attr.meta().and_then(|meta| meta.token_tree()).and_then(|tt| tt.l_paren_token())
-            {
-                let tabstop = edit.make_tabstop_after(snippet_cap);
-                editor.add_annotation(first_meta, tabstop);
-            }
+        {
+            let tabstop = edit.make_tabstop_after(snippet_cap);
+            editor.add_annotation(first_meta, tabstop);
         }
 
         editor.add_mappings(make.finish_with_mappings());
@@ -256,13 +255,12 @@ fn wrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>, attr: ast::Attr) ->
 
         editor.replace(attr.syntax(), cfg_attr.syntax());
 
-        if let Some(snippet_cap) = ctx.config.snippet_cap {
-            if let Some(first_meta) =
+        if let Some(snippet_cap) = ctx.config.snippet_cap
+            && let Some(first_meta) =
                 cfg_attr.meta().and_then(|meta| meta.token_tree()).and_then(|tt| tt.l_paren_token())
-            {
-                let tabstop = edit.make_tabstop_after(snippet_cap);
-                editor.add_annotation(first_meta, tabstop);
-            }
+        {
+            let tabstop = edit.make_tabstop_after(snippet_cap);
+            editor.add_annotation(first_meta, tabstop);
         }
 
         editor.add_mappings(make.finish_with_mappings());
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 15c7a6a3fc2..91aac9cf7b6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -23,12 +23,11 @@ use syntax::{
     ast::{
         self, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
         edit::{AstNodeEdit, IndentLevel},
-        edit_in_place::{AttrsOwnerEdit, Removable},
+        edit_in_place::AttrsOwnerEdit,
         make,
         syntax_factory::SyntaxFactory,
     },
-    syntax_editor::SyntaxEditor,
-    ted,
+    syntax_editor::{Removable, SyntaxEditor},
 };
 
 use crate::{
@@ -131,10 +130,10 @@ pub fn filter_assoc_items(
             if ignore_items == IgnoreAssocItems::DocHiddenAttrPresent
                 && assoc_item.attrs(sema.db).has_doc_hidden()
             {
-                if let hir::AssocItem::Function(f) = assoc_item {
-                    if !f.has_body(sema.db) {
-                        return true;
-                    }
+                if let hir::AssocItem::Function(f) = assoc_item
+                    && !f.has_body(sema.db)
+                {
+                    return true;
                 }
                 return false;
             }
@@ -207,7 +206,7 @@ pub fn add_trait_assoc_items_to_impl(
                         stdx::never!("formatted `AssocItem` could not be cast back to `AssocItem`");
                     }
                 }
-                original_item.clone_for_update()
+                original_item
             }
             .reset_indent();
 
@@ -221,31 +220,37 @@ pub fn add_trait_assoc_items_to_impl(
             cloned_item.remove_attrs_and_docs();
             cloned_item
         })
-        .map(|item| {
-            match &item {
-                ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
-                    let body = AstNodeEdit::indent(
-                        &make::block_expr(
-                            None,
-                            Some(match config.expr_fill_default {
-                                ExprFillDefaultMode::Todo => make::ext::expr_todo(),
-                                ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
-                                ExprFillDefaultMode::Default => make::ext::expr_todo(),
-                            }),
-                        ),
-                        IndentLevel::single(),
-                    );
-                    ted::replace(fn_.get_or_create_body().syntax(), body.syntax());
-                }
-                ast::AssocItem::TypeAlias(type_alias) => {
-                    if let Some(type_bound_list) = type_alias.type_bound_list() {
-                        type_bound_list.remove()
-                    }
+        .filter_map(|item| match item {
+            ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
+                let fn_ = fn_.clone_subtree();
+                let new_body = &make::block_expr(
+                    None,
+                    Some(match config.expr_fill_default {
+                        ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+                        ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+                        ExprFillDefaultMode::Default => make::ext::expr_todo(),
+                    }),
+                );
+                let new_body = AstNodeEdit::indent(new_body, IndentLevel::single());
+                let mut fn_editor = SyntaxEditor::new(fn_.syntax().clone());
+                fn_.replace_or_insert_body(&mut fn_editor, new_body);
+                let new_fn_ = fn_editor.finish().new_root().clone();
+                ast::AssocItem::cast(new_fn_)
+            }
+            ast::AssocItem::TypeAlias(type_alias) => {
+                let type_alias = type_alias.clone_subtree();
+                if let Some(type_bound_list) = type_alias.type_bound_list() {
+                    let mut type_alias_editor = SyntaxEditor::new(type_alias.syntax().clone());
+                    type_bound_list.remove(&mut type_alias_editor);
+                    let type_alias = type_alias_editor.finish().new_root().clone();
+                    ast::AssocItem::cast(type_alias)
+                } else {
+                    Some(ast::AssocItem::TypeAlias(type_alias))
                 }
-                _ => {}
             }
-            AstNodeEdit::indent(&item, new_indent_level)
+            item => Some(item),
         })
+        .map(|item| AstNodeEdit::indent(&item, new_indent_level))
         .collect()
 }
 
@@ -514,10 +519,10 @@ pub(crate) fn find_struct_impl(
         if !(same_ty && not_trait_impl) { None } else { Some(impl_blk) }
     });
 
-    if let Some(ref impl_blk) = block {
-        if has_any_fn(impl_blk, names) {
-            return None;
-        }
+    if let Some(ref impl_blk) = block
+        && has_any_fn(impl_blk, names)
+    {
+        return None;
     }
 
     Some(block)
@@ -526,12 +531,11 @@ pub(crate) fn find_struct_impl(
 fn has_any_fn(imp: &ast::Impl, names: &[String]) -> bool {
     if let Some(il) = imp.assoc_item_list() {
         for item in il.assoc_items() {
-            if let ast::AssocItem::Fn(f) = item {
-                if let Some(name) = f.name() {
-                    if names.iter().any(|n| n.eq_ignore_ascii_case(&name.text())) {
-                        return true;
-                    }
-                }
+            if let ast::AssocItem::Fn(f) = item
+                && let Some(name) = f.name()
+                && names.iter().any(|n| n.eq_ignore_ascii_case(&name.text()))
+            {
+                return true;
             }
         }
     }
@@ -1021,12 +1025,12 @@ pub(crate) fn trimmed_text_range(source_file: &SourceFile, initial_range: TextRa
 pub(crate) fn convert_param_list_to_arg_list(list: ast::ParamList) -> ast::ArgList {
     let mut args = vec![];
     for param in list.params() {
-        if let Some(ast::Pat::IdentPat(pat)) = param.pat() {
-            if let Some(name) = pat.name() {
-                let name = name.to_string();
-                let expr = make::expr_path(make::ext::ident_path(&name));
-                args.push(expr);
-            }
+        if let Some(ast::Pat::IdentPat(pat)) = param.pat()
+            && let Some(name) = pat.name()
+        {
+            let name = name.to_string();
+            let expr = make::expr_path(make::ext::ident_path(&name));
+            args.push(expr);
         }
     }
     make::arg_list(args)
@@ -1138,12 +1142,11 @@ pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bo
         };
         match expr {
             ast::Expr::CallExpr(call) => {
-                if let Some(ast::Expr::PathExpr(path_expr)) = call.expr() {
-                    if let Some(PathResolution::Def(ModuleDef::Function(func))) =
+                if let Some(ast::Expr::PathExpr(path_expr)) = call.expr()
+                    && let Some(PathResolution::Def(ModuleDef::Function(func))) =
                         path_expr.path().and_then(|path| sema.resolve_path(&path))
-                    {
-                        is_const &= func.is_const(sema.db);
-                    }
+                {
+                    is_const &= func.is_const(sema.db);
                 }
             }
             ast::Expr::MethodCallExpr(call) => {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
index 65072d936f6..11d26228ba2 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -111,10 +111,11 @@ impl Completions {
         ctx: &CompletionContext<'_>,
         super_chain_len: Option<usize>,
     ) {
-        if let Some(len) = super_chain_len {
-            if len > 0 && len < ctx.depth_from_crate_root {
-                self.add_keyword(ctx, "super::");
-            }
+        if let Some(len) = super_chain_len
+            && len > 0
+            && len < ctx.depth_from_crate_root
+        {
+            self.add_keyword(ctx, "super::");
         }
     }
 
@@ -643,10 +644,10 @@ fn enum_variants_with_paths(
 
     let variants = enum_.variants(ctx.db);
 
-    if let Some(impl_) = impl_.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) {
-        if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_)) {
-            variants.iter().for_each(|variant| process_variant(*variant));
-        }
+    if let Some(impl_) = impl_.as_ref().and_then(|impl_| ctx.sema.to_def(impl_))
+        && impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_))
+    {
+        variants.iter().for_each(|variant| process_variant(*variant));
     }
 
     for variant in variants {
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 5340d65a142..f75123324f3 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
@@ -258,12 +258,11 @@ fn complete_methods(
         fn on_trait_method(&mut self, func: hir::Function) -> ControlFlow<()> {
             // This needs to come before the `seen_methods` test, so that if we see the same method twice,
             // once as inherent and once not, we will include it.
-            if let ItemContainer::Trait(trait_) = func.container(self.ctx.db) {
-                if self.ctx.exclude_traits.contains(&trait_)
-                    || trait_.complete(self.ctx.db) == Complete::IgnoreMethods
-                {
-                    return ControlFlow::Continue(());
-                }
+            if let ItemContainer::Trait(trait_) = func.container(self.ctx.db)
+                && (self.ctx.exclude_traits.contains(&trait_)
+                    || trait_.complete(self.ctx.db) == Complete::IgnoreMethods)
+            {
+                return ControlFlow::Continue(());
             }
 
             if func.self_param(self.ctx.db).is_some()
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs
index 809e71cc119..fb78386976d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs
@@ -128,10 +128,10 @@ fn params_from_stmt_list_scope(
     {
         let module = scope.module().into();
         scope.process_all_names(&mut |name, def| {
-            if let hir::ScopeDef::Local(local) = def {
-                if let Ok(ty) = local.ty(ctx.db).display_source_code(ctx.db, module, true) {
-                    cb(name, ty);
-                }
+            if let hir::ScopeDef::Local(local) = def
+                && let Ok(ty) = local.ty(ctx.db).display_source_code(ctx.db, module, true)
+            {
+                cb(name, ty);
             }
         });
     }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
index bcf8c0ec527..cdd77e79b5c 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -228,24 +228,22 @@ fn add_function_impl_(
         .set_documentation(func.docs(ctx.db))
         .set_relevance(CompletionRelevance { exact_name_match: true, ..Default::default() });
 
-    if let Some(source) = ctx.sema.source(func) {
-        if let Some(transformed_fn) =
+    if let Some(source) = ctx.sema.source(func)
+        && let Some(transformed_fn) =
             get_transformed_fn(ctx, source.value, impl_def, async_sugaring)
-        {
-            let function_decl =
-                function_declaration(ctx, &transformed_fn, source.file_id.macro_file());
-            match ctx.config.snippet_cap {
-                Some(cap) => {
-                    let snippet = format!("{function_decl} {{\n    $0\n}}");
-                    item.snippet_edit(cap, TextEdit::replace(replacement_range, snippet));
-                }
-                None => {
-                    let header = format!("{function_decl} {{");
-                    item.text_edit(TextEdit::replace(replacement_range, header));
-                }
-            };
-            item.add_to(acc, ctx.db);
-        }
+    {
+        let function_decl = function_declaration(ctx, &transformed_fn, source.file_id.macro_file());
+        match ctx.config.snippet_cap {
+            Some(cap) => {
+                let snippet = format!("{function_decl} {{\n    $0\n}}");
+                item.snippet_edit(cap, TextEdit::replace(replacement_range, snippet));
+            }
+            None => {
+                let header = format!("{function_decl} {{");
+                item.text_edit(TextEdit::replace(replacement_range, header));
+            }
+        };
+        item.add_to(acc, ctx.db);
     }
 }
 
@@ -447,36 +445,36 @@ fn add_const_impl(
 ) {
     let const_name = const_.name(ctx.db).map(|n| n.display_no_db(ctx.edition).to_smolstr());
 
-    if let Some(const_name) = const_name {
-        if let Some(source) = ctx.sema.source(const_) {
-            let assoc_item = ast::AssocItem::Const(source.value);
-            if let Some(transformed_item) = get_transformed_assoc_item(ctx, assoc_item, impl_def) {
-                let transformed_const = match transformed_item {
-                    ast::AssocItem::Const(const_) => const_,
-                    _ => unreachable!(),
-                };
-
-                let label =
-                    make_const_compl_syntax(ctx, &transformed_const, source.file_id.macro_file());
-                let replacement = format!("{label} ");
-
-                let mut item =
-                    CompletionItem::new(SymbolKind::Const, replacement_range, label, ctx.edition);
-                item.lookup_by(format_smolstr!("const {const_name}"))
-                    .set_documentation(const_.docs(ctx.db))
-                    .set_relevance(CompletionRelevance {
-                        exact_name_match: true,
-                        ..Default::default()
-                    });
-                match ctx.config.snippet_cap {
-                    Some(cap) => item.snippet_edit(
-                        cap,
-                        TextEdit::replace(replacement_range, format!("{replacement}$0;")),
-                    ),
-                    None => item.text_edit(TextEdit::replace(replacement_range, replacement)),
-                };
-                item.add_to(acc, ctx.db);
-            }
+    if let Some(const_name) = const_name
+        && let Some(source) = ctx.sema.source(const_)
+    {
+        let assoc_item = ast::AssocItem::Const(source.value);
+        if let Some(transformed_item) = get_transformed_assoc_item(ctx, assoc_item, impl_def) {
+            let transformed_const = match transformed_item {
+                ast::AssocItem::Const(const_) => const_,
+                _ => unreachable!(),
+            };
+
+            let label =
+                make_const_compl_syntax(ctx, &transformed_const, source.file_id.macro_file());
+            let replacement = format!("{label} ");
+
+            let mut item =
+                CompletionItem::new(SymbolKind::Const, replacement_range, label, ctx.edition);
+            item.lookup_by(format_smolstr!("const {const_name}"))
+                .set_documentation(const_.docs(ctx.db))
+                .set_relevance(CompletionRelevance {
+                    exact_name_match: true,
+                    ..Default::default()
+                });
+            match ctx.config.snippet_cap {
+                Some(cap) => item.snippet_edit(
+                    cap,
+                    TextEdit::replace(replacement_range, format!("{replacement}$0;")),
+                ),
+                None => item.text_edit(TextEdit::replace(replacement_range, replacement)),
+            };
+            item.add_to(acc, ctx.db);
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs
index 013747e4d0c..33333000457 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs
@@ -26,18 +26,17 @@ pub(crate) fn complete_mod(
     let mut current_module = ctx.module;
     // For `mod $0`, `ctx.module` is its parent, but for `mod f$0`, it's `mod f` itself, but we're
     // interested in its parent.
-    if ctx.original_token.kind() == SyntaxKind::IDENT {
-        if let Some(module) =
+    if ctx.original_token.kind() == SyntaxKind::IDENT
+        && let Some(module) =
             ctx.original_token.parent_ancestors().nth(1).and_then(ast::Module::cast)
-        {
-            match ctx.sema.to_def(&module) {
-                Some(module) if module == current_module => {
-                    if let Some(parent) = current_module.parent(ctx.db) {
-                        current_module = parent;
-                    }
+    {
+        match ctx.sema.to_def(&module) {
+            Some(module) if module == current_module => {
+                if let Some(parent) = current_module.parent(ctx.db) {
+                    current_module = parent;
                 }
-                _ => {}
             }
+            _ => {}
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs
index 62fae1cb237..815ce5145db 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs
@@ -64,18 +64,17 @@ pub(crate) fn complete_pattern(
 
     if let Some(hir::Adt::Enum(e)) =
         ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
+        && (refutable || single_variant_enum(e))
     {
-        if refutable || single_variant_enum(e) {
-            super::enum_variants_with_paths(
-                acc,
-                ctx,
-                e,
-                &pattern_ctx.impl_,
-                |acc, ctx, variant, path| {
-                    acc.add_qualified_variant_pat(ctx, pattern_ctx, variant, path);
-                },
-            );
-        }
+        super::enum_variants_with_paths(
+            acc,
+            ctx,
+            e,
+            &pattern_ctx.impl_,
+            |acc, ctx, variant, path| {
+                acc.add_qualified_variant_pat(ctx, pattern_ctx, variant, path);
+            },
+        );
     }
 
     // FIXME: ideally, we should look at the type we are matching against and
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
index d0023852acf..0058611a615 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
@@ -65,26 +65,19 @@ pub(crate) fn complete_postfix(
 
     let cfg = ctx.config.import_path_config(ctx.is_nightly);
 
-    if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
-        if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) {
-            if let Some(drop_fn) = ctx.famous_defs().core_mem_drop() {
-                if let Some(path) =
-                    ctx.module.find_path(ctx.db, ItemInNs::Values(drop_fn.into()), cfg)
-                {
-                    cov_mark::hit!(postfix_drop_completion);
-                    let mut item = postfix_snippet(
-                        "drop",
-                        "fn drop(&mut self)",
-                        &format!(
-                            "{path}($0{receiver_text})",
-                            path = path.display(ctx.db, ctx.edition)
-                        ),
-                    );
-                    item.set_documentation(drop_fn.docs(ctx.db));
-                    item.add_to(acc, ctx.db);
-                }
-            }
-        }
+    if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop()
+        && receiver_ty.impls_trait(ctx.db, drop_trait, &[])
+        && let Some(drop_fn) = ctx.famous_defs().core_mem_drop()
+        && let Some(path) = ctx.module.find_path(ctx.db, ItemInNs::Values(drop_fn.into()), cfg)
+    {
+        cov_mark::hit!(postfix_drop_completion);
+        let mut item = postfix_snippet(
+            "drop",
+            "fn drop(&mut self)",
+            &format!("{path}($0{receiver_text})", path = path.display(ctx.db, ctx.edition)),
+        );
+        item.set_documentation(drop_fn.docs(ctx.db));
+        item.add_to(acc, ctx.db);
     }
 
     postfix_snippet("ref", "&expr", &format!("&{receiver_text}")).add_to(acc, ctx.db);
@@ -117,56 +110,50 @@ pub(crate) fn complete_postfix(
 
     let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty.strip_references());
     let mut is_in_cond = false;
-    if let Some(parent) = dot_receiver_including_refs.syntax().parent() {
-        if let Some(second_ancestor) = parent.parent() {
-            let sec_ancestor_kind = second_ancestor.kind();
-            if let Some(expr) = <Either<ast::IfExpr, ast::WhileExpr>>::cast(second_ancestor) {
-                is_in_cond = match expr {
-                    Either::Left(it) => it.condition().is_some_and(|cond| *cond.syntax() == parent),
-                    Either::Right(it) => {
-                        it.condition().is_some_and(|cond| *cond.syntax() == parent)
-                    }
-                }
+    if let Some(parent) = dot_receiver_including_refs.syntax().parent()
+        && let Some(second_ancestor) = parent.parent()
+    {
+        let sec_ancestor_kind = second_ancestor.kind();
+        if let Some(expr) = <Either<ast::IfExpr, ast::WhileExpr>>::cast(second_ancestor) {
+            is_in_cond = match expr {
+                Either::Left(it) => it.condition().is_some_and(|cond| *cond.syntax() == parent),
+                Either::Right(it) => it.condition().is_some_and(|cond| *cond.syntax() == parent),
             }
-            match &try_enum {
-                Some(try_enum) if is_in_cond => match try_enum {
-                    TryEnum::Result => {
-                        postfix_snippet(
-                            "let",
-                            "let Ok(_)",
-                            &format!("let Ok($0) = {receiver_text}"),
-                        )
-                        .add_to(acc, ctx.db);
-                        postfix_snippet(
-                            "letm",
-                            "let Ok(mut _)",
-                            &format!("let Ok(mut $0) = {receiver_text}"),
-                        )
-                        .add_to(acc, ctx.db);
-                    }
-                    TryEnum::Option => {
-                        postfix_snippet(
-                            "let",
-                            "let Some(_)",
-                            &format!("let Some($0) = {receiver_text}"),
-                        )
-                        .add_to(acc, ctx.db);
-                        postfix_snippet(
-                            "letm",
-                            "let Some(mut _)",
-                            &format!("let Some(mut $0) = {receiver_text}"),
-                        )
-                        .add_to(acc, ctx.db);
-                    }
-                },
-                _ if matches!(sec_ancestor_kind, STMT_LIST | EXPR_STMT) => {
-                    postfix_snippet("let", "let", &format!("let $0 = {receiver_text};"))
-                        .add_to(acc, ctx.db);
-                    postfix_snippet("letm", "let mut", &format!("let mut $0 = {receiver_text};"))
+        }
+        match &try_enum {
+            Some(try_enum) if is_in_cond => match try_enum {
+                TryEnum::Result => {
+                    postfix_snippet("let", "let Ok(_)", &format!("let Ok($0) = {receiver_text}"))
                         .add_to(acc, ctx.db);
+                    postfix_snippet(
+                        "letm",
+                        "let Ok(mut _)",
+                        &format!("let Ok(mut $0) = {receiver_text}"),
+                    )
+                    .add_to(acc, ctx.db);
+                }
+                TryEnum::Option => {
+                    postfix_snippet(
+                        "let",
+                        "let Some(_)",
+                        &format!("let Some($0) = {receiver_text}"),
+                    )
+                    .add_to(acc, ctx.db);
+                    postfix_snippet(
+                        "letm",
+                        "let Some(mut _)",
+                        &format!("let Some(mut $0) = {receiver_text}"),
+                    )
+                    .add_to(acc, ctx.db);
                 }
-                _ => (),
+            },
+            _ if matches!(sec_ancestor_kind, STMT_LIST | EXPR_STMT) => {
+                postfix_snippet("let", "let", &format!("let $0 = {receiver_text};"))
+                    .add_to(acc, ctx.db);
+                postfix_snippet("letm", "let mut", &format!("let mut $0 = {receiver_text};"))
+                    .add_to(acc, ctx.db);
             }
+            _ => (),
         }
     }
 
@@ -258,25 +245,25 @@ pub(crate) fn complete_postfix(
             )
             .add_to(acc, ctx.db);
             postfix_snippet("not", "!expr", &format!("!{receiver_text}")).add_to(acc, ctx.db);
-        } else if let Some(trait_) = ctx.famous_defs().core_iter_IntoIterator() {
-            if receiver_ty.impls_trait(ctx.db, trait_, &[]) {
-                postfix_snippet(
-                    "for",
-                    "for ele in expr {}",
-                    &format!("for ele in {receiver_text} {{\n    $0\n}}"),
-                )
-                .add_to(acc, ctx.db);
-            }
+        } else if let Some(trait_) = ctx.famous_defs().core_iter_IntoIterator()
+            && receiver_ty.impls_trait(ctx.db, trait_, &[])
+        {
+            postfix_snippet(
+                "for",
+                "for ele in expr {}",
+                &format!("for ele in {receiver_text} {{\n    $0\n}}"),
+            )
+            .add_to(acc, ctx.db);
         }
     }
 
     let mut block_should_be_wrapped = true;
     if dot_receiver.syntax().kind() == BLOCK_EXPR {
         block_should_be_wrapped = false;
-        if let Some(parent) = dot_receiver.syntax().parent() {
-            if matches!(parent.kind(), IF_EXPR | WHILE_EXPR | LOOP_EXPR | FOR_EXPR) {
-                block_should_be_wrapped = true;
-            }
+        if let Some(parent) = dot_receiver.syntax().parent()
+            && matches!(parent.kind(), IF_EXPR | WHILE_EXPR | LOOP_EXPR | FOR_EXPR)
+        {
+            block_should_be_wrapped = true;
         }
     };
     {
@@ -292,10 +279,10 @@ pub(crate) fn complete_postfix(
         postfix_snippet("const", "const {}", &const_completion_string).add_to(acc, ctx.db);
     }
 
-    if let ast::Expr::Literal(literal) = dot_receiver_including_refs.clone() {
-        if let Some(literal_text) = ast::String::cast(literal.token()) {
-            add_format_like_completions(acc, ctx, &dot_receiver_including_refs, cap, &literal_text);
-        }
+    if let ast::Expr::Literal(literal) = dot_receiver_including_refs.clone()
+        && let Some(literal_text) = ast::String::cast(literal.token())
+    {
+        add_format_like_completions(acc, ctx, &dot_receiver_including_refs, cap, &literal_text);
     }
 
     postfix_snippet(
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs
index d2ab193ec3d..f39b6416493 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs
@@ -54,12 +54,10 @@ pub(crate) fn complete_use_path(
                     for (name, def) in module_scope {
                         if let (Some(attrs), Some(defining_crate)) =
                             (def.attrs(ctx.db), def.krate(ctx.db))
+                            && (!ctx.check_stability(Some(&attrs))
+                                || ctx.is_doc_hidden(&attrs, defining_crate))
                         {
-                            if !ctx.check_stability(Some(&attrs))
-                                || ctx.is_doc_hidden(&attrs, defining_crate)
-                            {
-                                continue;
-                            }
+                            continue;
                         }
                         let is_name_already_imported =
                             already_imported_names.contains(name.as_str());
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs
index 38761f77a2c..28d906d91ce 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/vis.rs
@@ -20,11 +20,11 @@ pub(crate) fn complete_vis_path(
             // Try completing next child module of the path that is still a parent of the current module
             let next_towards_current =
                 ctx.module.path_to_root(ctx.db).into_iter().take_while(|it| it != module).last();
-            if let Some(next) = next_towards_current {
-                if let Some(name) = next.name(ctx.db) {
-                    cov_mark::hit!(visibility_qualified);
-                    acc.add_module(ctx, path_ctx, next, name, vec![]);
-                }
+            if let Some(next) = next_towards_current
+                && let Some(name) = next.name(ctx.db)
+            {
+                cov_mark::hit!(visibility_qualified);
+                acc.add_module(ctx, path_ctx, next, name, vec![]);
             }
 
             acc.add_super_keyword(ctx, *super_chain_len);
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 ea5fb39338b..2eabf99fc69 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
@@ -287,24 +287,22 @@ fn expand(
                 &spec_attr,
                 fake_ident_token.clone(),
             ),
-        ) {
-            if let Some((fake_mapped_token, _)) =
-                fake_mapped_tokens.into_iter().min_by_key(|(_, rank)| *rank)
-            {
-                return Some(ExpansionResult {
-                    original_file: original_file.value,
-                    speculative_file,
-                    original_offset,
-                    speculative_offset: fake_ident_token.text_range().start(),
-                    fake_ident_token,
-                    derive_ctx: Some((
-                        actual_expansion,
-                        fake_expansion,
-                        fake_mapped_token.text_range().start(),
-                        orig_attr,
-                    )),
-                });
-            }
+        ) && let Some((fake_mapped_token, _)) =
+            fake_mapped_tokens.into_iter().min_by_key(|(_, rank)| *rank)
+        {
+            return Some(ExpansionResult {
+                original_file: original_file.value,
+                speculative_file,
+                original_offset,
+                speculative_offset: fake_ident_token.text_range().start(),
+                fake_ident_token,
+                derive_ctx: Some((
+                    actual_expansion,
+                    fake_expansion,
+                    fake_mapped_token.text_range().start(),
+                    orig_attr,
+                )),
+            });
         }
 
         if let Some(spec_adt) =
@@ -535,14 +533,13 @@ fn analyze<'db>(
                     NameRefKind::Path(PathCompletionCtx { kind: PathKind::Expr { .. }, path, .. }, ..),
                 ..
             } = &nameref_ctx
+                && is_in_token_of_for_loop(path)
             {
-                if is_in_token_of_for_loop(path) {
-                    // for pat $0
-                    // there is nothing to complete here except `in` keyword
-                    // don't bother populating the context
-                    // Ideally this special casing wouldn't be needed, but the parser recovers
-                    return None;
-                }
+                // for pat $0
+                // there is nothing to complete here except `in` keyword
+                // don't bother populating the context
+                // Ideally this special casing wouldn't be needed, but the parser recovers
+                return None;
             }
 
             qual_ctx = qualifier_ctx;
@@ -951,29 +948,26 @@ fn classify_name_ref<'db>(
     let inbetween_body_and_decl_check = |node: SyntaxNode| {
         if let Some(NodeOrToken::Node(n)) =
             syntax::algo::non_trivia_sibling(node.into(), syntax::Direction::Prev)
+            && let Some(item) = ast::Item::cast(n)
         {
-            if let Some(item) = ast::Item::cast(n) {
-                let is_inbetween = match &item {
-                    ast::Item::Const(it) => it.body().is_none() && it.semicolon_token().is_none(),
-                    ast::Item::Enum(it) => it.variant_list().is_none(),
-                    ast::Item::ExternBlock(it) => it.extern_item_list().is_none(),
-                    ast::Item::Fn(it) => it.body().is_none() && it.semicolon_token().is_none(),
-                    ast::Item::Impl(it) => it.assoc_item_list().is_none(),
-                    ast::Item::Module(it) => {
-                        it.item_list().is_none() && it.semicolon_token().is_none()
-                    }
-                    ast::Item::Static(it) => it.body().is_none(),
-                    ast::Item::Struct(it) => {
-                        it.field_list().is_none() && it.semicolon_token().is_none()
-                    }
-                    ast::Item::Trait(it) => it.assoc_item_list().is_none(),
-                    ast::Item::TypeAlias(it) => it.ty().is_none() && it.semicolon_token().is_none(),
-                    ast::Item::Union(it) => it.record_field_list().is_none(),
-                    _ => false,
-                };
-                if is_inbetween {
-                    return Some(item);
+            let is_inbetween = match &item {
+                ast::Item::Const(it) => it.body().is_none() && it.semicolon_token().is_none(),
+                ast::Item::Enum(it) => it.variant_list().is_none(),
+                ast::Item::ExternBlock(it) => it.extern_item_list().is_none(),
+                ast::Item::Fn(it) => it.body().is_none() && it.semicolon_token().is_none(),
+                ast::Item::Impl(it) => it.assoc_item_list().is_none(),
+                ast::Item::Module(it) => it.item_list().is_none() && it.semicolon_token().is_none(),
+                ast::Item::Static(it) => it.body().is_none(),
+                ast::Item::Struct(it) => {
+                    it.field_list().is_none() && it.semicolon_token().is_none()
                 }
+                ast::Item::Trait(it) => it.assoc_item_list().is_none(),
+                ast::Item::TypeAlias(it) => it.ty().is_none() && it.semicolon_token().is_none(),
+                ast::Item::Union(it) => it.record_field_list().is_none(),
+                _ => false,
+            };
+            if is_inbetween {
+                return Some(item);
             }
         }
         None
@@ -1502,10 +1496,10 @@ fn classify_name_ref<'db>(
                 }
             };
         }
-    } else if let Some(segment) = path.segment() {
-        if segment.coloncolon_token().is_some() {
-            path_ctx.qualified = Qualified::Absolute;
-        }
+    } else if let Some(segment) = path.segment()
+        && segment.coloncolon_token().is_some()
+    {
+        path_ctx.qualified = Qualified::Absolute;
     }
 
     let mut qualifier_ctx = QualifierCtx::default();
@@ -1530,38 +1524,30 @@ fn classify_name_ref<'db>(
         if let Some(top) = top_node {
             if let Some(NodeOrToken::Node(error_node)) =
                 syntax::algo::non_trivia_sibling(top.clone().into(), syntax::Direction::Prev)
+                && error_node.kind() == SyntaxKind::ERROR
             {
-                if error_node.kind() == SyntaxKind::ERROR {
-                    for token in
-                        error_node.children_with_tokens().filter_map(NodeOrToken::into_token)
-                    {
-                        match token.kind() {
-                            SyntaxKind::UNSAFE_KW => qualifier_ctx.unsafe_tok = Some(token),
-                            SyntaxKind::ASYNC_KW => qualifier_ctx.async_tok = Some(token),
-                            SyntaxKind::SAFE_KW => qualifier_ctx.safe_tok = Some(token),
-                            _ => {}
-                        }
+                for token in error_node.children_with_tokens().filter_map(NodeOrToken::into_token) {
+                    match token.kind() {
+                        SyntaxKind::UNSAFE_KW => qualifier_ctx.unsafe_tok = Some(token),
+                        SyntaxKind::ASYNC_KW => qualifier_ctx.async_tok = Some(token),
+                        SyntaxKind::SAFE_KW => qualifier_ctx.safe_tok = Some(token),
+                        _ => {}
                     }
-                    qualifier_ctx.vis_node = error_node.children().find_map(ast::Visibility::cast);
                 }
+                qualifier_ctx.vis_node = error_node.children().find_map(ast::Visibility::cast);
             }
 
-            if let PathKind::Item { .. } = path_ctx.kind {
-                if qualifier_ctx.none() {
-                    if let Some(t) = top.first_token() {
-                        if let Some(prev) = t
-                            .prev_token()
-                            .and_then(|t| syntax::algo::skip_trivia_token(t, Direction::Prev))
-                        {
-                            if ![T![;], T!['}'], T!['{']].contains(&prev.kind()) {
-                                // This was inferred to be an item position path, but it seems
-                                // to be part of some other broken node which leaked into an item
-                                // list
-                                return None;
-                            }
-                        }
-                    }
-                }
+            if let PathKind::Item { .. } = path_ctx.kind
+                && qualifier_ctx.none()
+                && let Some(t) = top.first_token()
+                && let Some(prev) =
+                    t.prev_token().and_then(|t| syntax::algo::skip_trivia_token(t, Direction::Prev))
+                && ![T![;], T!['}'], T!['{']].contains(&prev.kind())
+            {
+                // This was inferred to be an item position path, but it seems
+                // to be part of some other broken node which leaked into an item
+                // list
+                return None;
             }
         }
     }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
index dcaac3997b2..f27cd078166 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
@@ -636,10 +636,10 @@ impl Builder {
     }
     pub(crate) fn set_detail(&mut self, detail: Option<impl Into<String>>) -> &mut Builder {
         self.detail = detail.map(Into::into);
-        if let Some(detail) = &self.detail {
-            if never!(detail.contains('\n'), "multiline detail:\n{}", detail) {
-                self.detail = Some(detail.split('\n').next().unwrap().to_owned());
-            }
+        if let Some(detail) = &self.detail
+            && never!(detail.contains('\n'), "multiline detail:\n{}", detail)
+        {
+            self.detail = Some(detail.split('\n').next().unwrap().to_owned());
         }
         self
     }
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 1fdd4cdb1c6..a70a1138d2f 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
@@ -208,9 +208,9 @@ pub fn completions(
     // when the user types a bare `_` (that is it does not belong to an identifier)
     // the user might just wanted to type a `_` for type inference or pattern discarding
     // so try to suppress completions in those cases
-    if trigger_character == Some('_') && ctx.original_token.kind() == syntax::SyntaxKind::UNDERSCORE
-    {
-        if let CompletionAnalysis::NameRef(NameRefContext {
+    if trigger_character == Some('_')
+        && ctx.original_token.kind() == syntax::SyntaxKind::UNDERSCORE
+        && let CompletionAnalysis::NameRef(NameRefContext {
             kind:
                 NameRefKind::Path(
                     path_ctx @ PathCompletionCtx {
@@ -220,11 +220,9 @@ pub fn completions(
                 ),
             ..
         }) = analysis
-        {
-            if path_ctx.is_trivial_path() {
-                return None;
-            }
-        }
+        && path_ctx.is_trivial_path()
+    {
+        return None;
     }
 
     {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
index c6b8af3c79a..3d7a4067c2c 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -164,19 +164,18 @@ pub(crate) fn render_field(
         let expected_fn_type =
             ctx.completion.expected_type.as_ref().is_some_and(|ty| ty.is_fn() || ty.is_closure());
 
-        if !expected_fn_type {
-            if let Some(receiver) = &dot_access.receiver {
-                if let Some(receiver) = ctx.completion.sema.original_ast_node(receiver.clone()) {
-                    builder.insert(receiver.syntax().text_range().start(), "(".to_owned());
-                    builder.insert(ctx.source_range().end(), ")".to_owned());
-
-                    let is_parens_needed =
-                        !matches!(dot_access.kind, DotAccessKind::Method { has_parens: true });
-
-                    if is_parens_needed {
-                        builder.insert(ctx.source_range().end(), "()".to_owned());
-                    }
-                }
+        if !expected_fn_type
+            && let Some(receiver) = &dot_access.receiver
+            && let Some(receiver) = ctx.completion.sema.original_ast_node(receiver.clone())
+        {
+            builder.insert(receiver.syntax().text_range().start(), "(".to_owned());
+            builder.insert(ctx.source_range().end(), ")".to_owned());
+
+            let is_parens_needed =
+                !matches!(dot_access.kind, DotAccessKind::Method { has_parens: true });
+
+            if is_parens_needed {
+                builder.insert(ctx.source_range().end(), "()".to_owned());
             }
         }
 
@@ -184,12 +183,11 @@ pub(crate) fn render_field(
     } else {
         item.insert_text(field_with_receiver(receiver.as_deref(), &escaped_name));
     }
-    if let Some(receiver) = &dot_access.receiver {
-        if let Some(original) = ctx.completion.sema.original_ast_node(receiver.clone()) {
-            if let Some(ref_mode) = compute_ref_match(ctx.completion, ty) {
-                item.ref_match(ref_mode, original.syntax().text_range().start());
-            }
-        }
+    if let Some(receiver) = &dot_access.receiver
+        && let Some(original) = ctx.completion.sema.original_ast_node(receiver.clone())
+        && let Some(ref_mode) = compute_ref_match(ctx.completion, ty)
+    {
+        item.ref_match(ref_mode, original.syntax().text_range().start());
     }
     item.doc_aliases(ctx.doc_aliases);
     item.build(db)
@@ -437,26 +435,21 @@ fn render_resolution_path(
         path_ctx,
         PathCompletionCtx { kind: PathKind::Type { .. }, has_type_args: false, .. }
     ) && config.callable.is_some();
-    if type_path_no_ty_args {
-        if let Some(cap) = cap {
-            let has_non_default_type_params = match resolution {
-                ScopeDef::ModuleDef(hir::ModuleDef::Adt(it)) => it.has_non_default_type_params(db),
-                ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(it)) => {
-                    it.has_non_default_type_params(db)
-                }
-                _ => false,
-            };
-
-            if has_non_default_type_params {
-                cov_mark::hit!(inserts_angle_brackets_for_generics);
-                item.lookup_by(name.clone())
-                    .label(SmolStr::from_iter([&name, "<…>"]))
-                    .trigger_call_info()
-                    .insert_snippet(
-                        cap,
-                        format!("{}<$0>", local_name.display(db, completion.edition)),
-                    );
+    if type_path_no_ty_args && let Some(cap) = cap {
+        let has_non_default_type_params = match resolution {
+            ScopeDef::ModuleDef(hir::ModuleDef::Adt(it)) => it.has_non_default_type_params(db),
+            ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(it)) => {
+                it.has_non_default_type_params(db)
             }
+            _ => false,
+        };
+
+        if has_non_default_type_params {
+            cov_mark::hit!(inserts_angle_brackets_for_generics);
+            item.lookup_by(name.clone())
+                .label(SmolStr::from_iter([&name, "<…>"]))
+                .trigger_call_info()
+                .insert_snippet(cap, format!("{}<$0>", local_name.display(db, completion.edition)));
         }
     }
 
@@ -634,23 +627,24 @@ fn compute_ref_match(
     if expected_type.could_unify_with(ctx.db, completion_ty) {
         return None;
     }
-    if let Some(expected_without_ref) = &expected_without_ref {
-        if completion_ty.autoderef(ctx.db).any(|ty| ty == *expected_without_ref) {
-            cov_mark::hit!(suggest_ref);
-            let mutability = if expected_type.is_mutable_reference() {
-                hir::Mutability::Mut
-            } else {
-                hir::Mutability::Shared
-            };
-            return Some(CompletionItemRefMode::Reference(mutability));
-        }
+    if let Some(expected_without_ref) = &expected_without_ref
+        && completion_ty.autoderef(ctx.db).any(|ty| ty == *expected_without_ref)
+    {
+        cov_mark::hit!(suggest_ref);
+        let mutability = if expected_type.is_mutable_reference() {
+            hir::Mutability::Mut
+        } else {
+            hir::Mutability::Shared
+        };
+        return Some(CompletionItemRefMode::Reference(mutability));
     }
 
-    if let Some(completion_without_ref) = completion_without_ref {
-        if completion_without_ref == *expected_type && completion_without_ref.is_copy(ctx.db) {
-            cov_mark::hit!(suggest_deref);
-            return Some(CompletionItemRefMode::Dereference);
-        }
+    if let Some(completion_without_ref) = completion_without_ref
+        && completion_without_ref == *expected_type
+        && completion_without_ref.is_copy(ctx.db)
+    {
+        cov_mark::hit!(suggest_deref);
+        return Some(CompletionItemRefMode::Dereference);
     }
 
     None
@@ -664,10 +658,10 @@ fn path_ref_match(
 ) {
     if let Some(original_path) = &path_ctx.original_path {
         // At least one char was typed by the user already, in that case look for the original path
-        if let Some(original_path) = completion.sema.original_ast_node(original_path.clone()) {
-            if let Some(ref_mode) = compute_ref_match(completion, ty) {
-                item.ref_match(ref_mode, original_path.syntax().text_range().start());
-            }
+        if let Some(original_path) = completion.sema.original_ast_node(original_path.clone())
+            && let Some(ref_mode) = compute_ref_match(completion, ty)
+        {
+            item.ref_match(ref_mode, original_path.syntax().text_range().start());
         }
     } else {
         // completion requested on an empty identifier, there is no path here yet.
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
index f11b3023679..707a8aed4fb 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
@@ -25,10 +25,10 @@ fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem>
         .detail(detail)
         .set_relevance(ctx.completion_relevance());
 
-    if let Some(actm) = const_.as_assoc_item(db) {
-        if let Some(trt) = actm.container_or_implemented_trait(db) {
-            item.trait_name(trt.name(db).display_no_db(ctx.completion.edition).to_smolstr());
-        }
+    if let Some(actm) = const_.as_assoc_item(db)
+        && let Some(trt) = actm.container_or_implemented_trait(db)
+    {
+        item.trait_name(trt.name(db).display_no_db(ctx.completion.edition).to_smolstr());
     }
     item.insert_text(escaped_name);
 
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 7669aec8f53..c466019f991 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
@@ -132,10 +132,10 @@ fn render(
             super::path_ref_match(completion, path_ctx, &ret_type, &mut item);
         }
         FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
-            if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone()) {
-                if let Some(ref_mode) = compute_ref_match(completion, &ret_type) {
-                    item.ref_match(ref_mode, original_expr.syntax().text_range().start());
-                }
+            if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone())
+                && let Some(ref_mode) = compute_ref_match(completion, &ret_type)
+            {
+                item.ref_match(ref_mode, original_expr.syntax().text_range().start());
             }
         }
         _ => (),
@@ -169,12 +169,10 @@ fn render(
             item.add_import(import_to_add);
         }
         None => {
-            if let Some(actm) = assoc_item {
-                if let Some(trt) = actm.container_or_implemented_trait(db) {
-                    item.trait_name(
-                        trt.name(db).display_no_db(ctx.completion.edition).to_smolstr(),
-                    );
-                }
+            if let Some(actm) = assoc_item
+                && let Some(trt) = actm.container_or_implemented_trait(db)
+            {
+                item.trait_name(trt.name(db).display_no_db(ctx.completion.edition).to_smolstr());
             }
         }
     }
@@ -378,15 +376,13 @@ fn params<'db>(
     ctx.config.callable.as_ref()?;
 
     // Don't add parentheses if the expected type is a function reference with the same signature.
-    if let Some(expected) = ctx.expected_type.as_ref().filter(|e| e.is_fn()) {
-        if let Some(expected) = expected.as_callable(ctx.db) {
-            if let Some(completed) = func.ty(ctx.db).as_callable(ctx.db) {
-                if expected.sig() == completed.sig() {
-                    cov_mark::hit!(no_call_parens_if_fn_ptr_needed);
-                    return None;
-                }
-            }
-        }
+    if let Some(expected) = ctx.expected_type.as_ref().filter(|e| e.is_fn())
+        && let Some(expected) = expected.as_callable(ctx.db)
+        && let Some(completed) = func.ty(ctx.db).as_callable(ctx.db)
+        && expected.sig() == completed.sig()
+    {
+        cov_mark::hit!(no_call_parens_if_fn_ptr_needed);
+        return None;
     }
 
     let self_param = if has_dot_receiver || matches!(func_kind, FuncKind::Method(_, Some(_))) {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
index d57feee4fa6..3fc0f369e5a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
@@ -51,10 +51,10 @@ fn render(
         .detail(detail)
         .set_relevance(ctx.completion_relevance());
 
-    if let Some(actm) = type_alias.as_assoc_item(db) {
-        if let Some(trt) = actm.container_or_implemented_trait(db) {
-            item.trait_name(trt.name(db).display_no_db(ctx.completion.edition).to_smolstr());
-        }
+    if let Some(actm) = type_alias.as_assoc_item(db)
+        && let Some(trt) = actm.container_or_implemented_trait(db)
+    {
+        item.trait_name(trt.name(db).display_no_db(ctx.completion.edition).to_smolstr());
     }
     item.insert_text(escaped_name);
 
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 a4a140ec57a..2a4fcf6a2e5 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
@@ -610,18 +610,16 @@ impl<'db> NameClass<'db> {
 
             let local = sema.to_def(&ident_pat)?;
             let pat_parent = ident_pat.syntax().parent();
-            if let Some(record_pat_field) = pat_parent.and_then(ast::RecordPatField::cast) {
-                if record_pat_field.name_ref().is_none() {
-                    if let Some((field, _, adt_subst)) =
-                        sema.resolve_record_pat_field_with_subst(&record_pat_field)
-                    {
-                        return Some(NameClass::PatFieldShorthand {
-                            local_def: local,
-                            field_ref: field,
-                            adt_subst,
-                        });
-                    }
-                }
+            if let Some(record_pat_field) = pat_parent.and_then(ast::RecordPatField::cast)
+                && record_pat_field.name_ref().is_none()
+                && let Some((field, _, adt_subst)) =
+                    sema.resolve_record_pat_field_with_subst(&record_pat_field)
+            {
+                return Some(NameClass::PatFieldShorthand {
+                    local_def: local,
+                    field_ref: field,
+                    adt_subst,
+                });
             }
             Some(NameClass::Definition(Definition::Local(local)))
         }
@@ -755,30 +753,27 @@ impl<'db> NameRefClass<'db> {
 
         let parent = name_ref.syntax().parent()?;
 
-        if let Some(record_field) = ast::RecordExprField::for_field_name(name_ref) {
-            if let Some((field, local, _, adt_subst)) =
+        if let Some(record_field) = ast::RecordExprField::for_field_name(name_ref)
+            && let Some((field, local, _, adt_subst)) =
                 sema.resolve_record_field_with_substitution(&record_field)
-            {
-                let res = match local {
-                    None => NameRefClass::Definition(Definition::Field(field), Some(adt_subst)),
-                    Some(local) => NameRefClass::FieldShorthand {
-                        field_ref: field,
-                        local_ref: local,
-                        adt_subst,
-                    },
-                };
-                return Some(res);
-            }
+        {
+            let res = match local {
+                None => NameRefClass::Definition(Definition::Field(field), Some(adt_subst)),
+                Some(local) => {
+                    NameRefClass::FieldShorthand { field_ref: field, local_ref: local, adt_subst }
+                }
+            };
+            return Some(res);
         }
 
         if let Some(path) = ast::PathSegment::cast(parent.clone()).map(|it| it.parent_path()) {
-            if path.parent_path().is_none() {
-                if let Some(macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) {
-                    // Only use this to resolve to macro calls for last segments as qualifiers resolve
-                    // to modules below.
-                    if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
-                        return Some(NameRefClass::Definition(Definition::Macro(macro_def), None));
-                    }
+            if path.parent_path().is_none()
+                && let Some(macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast)
+            {
+                // Only use this to resolve to macro calls for last segments as qualifiers resolve
+                // to modules below.
+                if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
+                    return Some(NameRefClass::Definition(Definition::Macro(macro_def), None));
                 }
             }
             return sema
@@ -820,8 +815,8 @@ impl<'db> NameRefClass<'db> {
                     //        ^^^^^
                     let containing_path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
                     let resolved = sema.resolve_path(&containing_path)?;
-                    if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved {
-                        if let Some(ty) = tr
+                    if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved
+                        && let Some(ty) = tr
                             .items_with_supertraits(sema.db)
                             .iter()
                             .filter_map(|&assoc| match assoc {
@@ -833,7 +828,6 @@ impl<'db> NameRefClass<'db> {
                             // No substitution, this can only occur in type position.
                             return Some(NameRefClass::Definition(Definition::TypeAlias(ty), None));
                         }
-                    }
                     None
                 },
                 ast::UseBoundGenericArgs(_) => {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
index 340429037e6..1e54058dd16 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
@@ -70,11 +70,11 @@ pub fn visit_file_defs(
     };
     let mut defs: VecDeque<_> = module.declarations(db).into();
     while let Some(def) = defs.pop_front() {
-        if let ModuleDef::Module(submodule) = def {
-            if submodule.is_inline(db) {
-                defs.extend(submodule.declarations(db));
-                submodule.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
-            }
+        if let ModuleDef::Module(submodule) = def
+            && submodule.is_inline(db)
+        {
+            defs.extend(submodule.declarations(db));
+            submodule.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
         }
         cb(def.into());
     }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs
index 813f38380f6..08cd8f28608 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs
@@ -97,12 +97,11 @@ impl ImportScope {
                     .map(ImportScopeKind::Module)
                     .map(|kind| ImportScope { kind, required_cfgs });
             } else if let Some(has_attrs) = ast::AnyHasAttrs::cast(syntax) {
-                if block.is_none() {
-                    if let Some(b) = ast::BlockExpr::cast(has_attrs.syntax().clone()) {
-                        if let Some(b) = sema.original_ast_node(b) {
-                            block = b.stmt_list();
-                        }
-                    }
+                if block.is_none()
+                    && let Some(b) = ast::BlockExpr::cast(has_attrs.syntax().clone())
+                    && let Some(b) = sema.original_ast_node(b)
+                {
+                    block = b.stmt_list();
                 }
                 if has_attrs
                     .attrs()
@@ -349,26 +348,24 @@ fn guess_granularity_from_scope(scope: &ImportScope) -> ImportGranularityGuess {
             seen_one_style_groups.push((curr_vis.clone(), curr_attrs.clone()));
         } else if eq_visibility(prev_vis, curr_vis.clone())
             && eq_attrs(prev_attrs, curr_attrs.clone())
+            && let Some((prev_path, curr_path)) = prev.path().zip(curr.path())
+            && let Some((prev_prefix, _)) = common_prefix(&prev_path, &curr_path)
         {
-            if let Some((prev_path, curr_path)) = prev.path().zip(curr.path()) {
-                if let Some((prev_prefix, _)) = common_prefix(&prev_path, &curr_path) {
-                    if prev.use_tree_list().is_none() && curr.use_tree_list().is_none() {
-                        let prefix_c = prev_prefix.qualifiers().count();
-                        let curr_c = curr_path.qualifiers().count() - prefix_c;
-                        let prev_c = prev_path.qualifiers().count() - prefix_c;
-                        if curr_c == 1 && prev_c == 1 {
-                            // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style.
-                            break ImportGranularityGuess::Item;
-                        } else {
-                            // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still.
-                            res = ImportGranularityGuess::ModuleOrItem;
-                        }
-                    } else {
-                        // Same prefix with item tree lists, has to be module style as it
-                        // can't be crate style since the trees wouldn't share a prefix then.
-                        break ImportGranularityGuess::Module;
-                    }
+            if prev.use_tree_list().is_none() && curr.use_tree_list().is_none() {
+                let prefix_c = prev_prefix.qualifiers().count();
+                let curr_c = curr_path.qualifiers().count() - prefix_c;
+                let prev_c = prev_path.qualifiers().count() - prefix_c;
+                if curr_c == 1 && prev_c == 1 {
+                    // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style.
+                    break ImportGranularityGuess::Item;
+                } else {
+                    // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still.
+                    res = ImportGranularityGuess::ModuleOrItem;
                 }
+            } else {
+                // Same prefix with item tree lists, has to be module style as it
+                // can't be crate style since the trees wouldn't share a prefix then.
+                break ImportGranularityGuess::Module;
             }
         }
         prev = curr;
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
index c94be7e164e..49f7f63a04a 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -244,7 +244,7 @@ pub trait LineIndexDatabase: base_db::RootQueryDb {
 
 fn line_index(db: &dyn LineIndexDatabase, file_id: FileId) -> Arc<LineIndex> {
     let text = db.file_text(file_id).text(db);
-    Arc::new(LineIndex::new(&text))
+    Arc::new(LineIndex::new(text))
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
index b7432d89c7b..5d88afec509 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
@@ -193,13 +193,12 @@ impl<'a> PathTransform<'a> {
                     }
                 }
                 (Either::Right(k), None) => {
-                    if let Some(default) = k.default(db) {
-                        if let Some(default) =
+                    if let Some(default) = k.default(db)
+                        && let Some(default) =
                             &default.display_source_code(db, source_module.into(), false).ok()
-                        {
-                            type_substs.insert(k, make::ty(default).clone_for_update());
-                            defaulted_params.push(Either::Left(k));
-                        }
+                    {
+                        type_substs.insert(k, make::ty(default).clone_for_update());
+                        defaulted_params.push(Either::Left(k));
                     }
                 }
                 (Either::Left(k), Some(TypeOrConst::Either(v))) => {
@@ -221,11 +220,10 @@ impl<'a> PathTransform<'a> {
                 (Either::Left(k), None) => {
                     if let Some(default) =
                         k.default(db, target_module.krate().to_display_target(db))
+                        && let Some(default) = default.expr()
                     {
-                        if let Some(default) = default.expr() {
-                            const_substs.insert(k, default.syntax().clone_for_update());
-                            defaulted_params.push(Either::Right(k));
-                        }
+                        const_substs.insert(k, default.syntax().clone_for_update());
+                        defaulted_params.push(Either::Right(k));
                     }
                 }
                 _ => (), // ignore mismatching params
@@ -427,14 +425,14 @@ impl Ctx<'_> {
                 }
             }
             hir::PathResolution::Def(def) if def.as_assoc_item(self.source_scope.db).is_none() => {
-                if let hir::ModuleDef::Trait(_) = def {
-                    if matches!(path.segment()?.kind()?, ast::PathSegmentKind::Type { .. }) {
-                        // `speculative_resolve` resolves segments like `<T as
-                        // Trait>` into `Trait`, but just the trait name should
-                        // not be used as the replacement of the original
-                        // segment.
-                        return None;
-                    }
+                if let hir::ModuleDef::Trait(_) = def
+                    && matches!(path.segment()?.kind()?, ast::PathSegmentKind::Type { .. })
+                {
+                    // `speculative_resolve` resolves segments like `<T as
+                    // Trait>` into `Trait`, but just the trait name should
+                    // not be used as the replacement of the original
+                    // segment.
+                    return None;
                 }
 
                 let cfg = ImportPathConfig {
@@ -446,19 +444,17 @@ impl Ctx<'_> {
                 let found_path = self.target_module.find_path(self.source_scope.db, def, cfg)?;
                 let res = mod_path_to_ast(&found_path, self.target_edition).clone_for_update();
                 let mut res_editor = SyntaxEditor::new(res.syntax().clone_subtree());
-                if let Some(args) = path.segment().and_then(|it| it.generic_arg_list()) {
-                    if let Some(segment) = res.segment() {
-                        if let Some(old) = segment.generic_arg_list() {
-                            res_editor.replace(
-                                old.syntax(),
-                                args.clone_subtree().syntax().clone_for_update(),
-                            )
-                        } else {
-                            res_editor.insert(
-                                syntax_editor::Position::last_child_of(segment.syntax()),
-                                args.clone_subtree().syntax().clone_for_update(),
-                            );
-                        }
+                if let Some(args) = path.segment().and_then(|it| it.generic_arg_list())
+                    && let Some(segment) = res.segment()
+                {
+                    if let Some(old) = segment.generic_arg_list() {
+                        res_editor
+                            .replace(old.syntax(), args.clone_subtree().syntax().clone_for_update())
+                    } else {
+                        res_editor.insert(
+                            syntax_editor::Position::last_child_of(segment.syntax()),
+                            args.clone_subtree().syntax().clone_for_update(),
+                        );
                     }
                 }
                 let res = res_editor.finish().new_root().clone();
@@ -485,27 +481,27 @@ impl Ctx<'_> {
                     .ok()?;
                 let ast_ty = make::ty(ty_str).clone_for_update();
 
-                if let Some(adt) = ty.as_adt() {
-                    if let ast::Type::PathType(path_ty) = &ast_ty {
-                        let cfg = ImportPathConfig {
-                            prefer_no_std: false,
-                            prefer_prelude: true,
-                            prefer_absolute: false,
-                            allow_unstable: true,
-                        };
-                        let found_path = self.target_module.find_path(
-                            self.source_scope.db,
-                            ModuleDef::from(adt),
-                            cfg,
-                        )?;
-
-                        if let Some(qual) =
-                            mod_path_to_ast(&found_path, self.target_edition).qualifier()
-                        {
-                            let res = make::path_concat(qual, path_ty.path()?).clone_for_update();
-                            editor.replace(path.syntax(), res.syntax());
-                            return Some(());
-                        }
+                if let Some(adt) = ty.as_adt()
+                    && let ast::Type::PathType(path_ty) = &ast_ty
+                {
+                    let cfg = ImportPathConfig {
+                        prefer_no_std: false,
+                        prefer_prelude: true,
+                        prefer_absolute: false,
+                        allow_unstable: true,
+                    };
+                    let found_path = self.target_module.find_path(
+                        self.source_scope.db,
+                        ModuleDef::from(adt),
+                        cfg,
+                    )?;
+
+                    if let Some(qual) =
+                        mod_path_to_ast(&found_path, self.target_edition).qualifier()
+                    {
+                        let res = make::path_concat(qual, path_ty.path()?).clone_for_update();
+                        editor.replace(path.syntax(), res.syntax());
+                        return Some(());
                     }
                 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
index 4e737e27f05..424b27a398b 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
@@ -442,17 +442,17 @@ fn source_edit_from_name(
     name: &ast::Name,
     new_name: &dyn Display,
 ) -> bool {
-    if ast::RecordPatField::for_field_name(name).is_some() {
-        if let Some(ident_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) {
-            cov_mark::hit!(rename_record_pat_field_name_split);
-            // Foo { ref mut field } -> Foo { new_name: ref mut field }
-            //      ^ insert `new_name: `
-
-            // FIXME: instead of splitting the shorthand, recursively trigger a rename of the
-            // other name https://github.com/rust-lang/rust-analyzer/issues/6547
-            edit.insert(ident_pat.syntax().text_range().start(), format!("{new_name}: "));
-            return true;
-        }
+    if ast::RecordPatField::for_field_name(name).is_some()
+        && let Some(ident_pat) = name.syntax().parent().and_then(ast::IdentPat::cast)
+    {
+        cov_mark::hit!(rename_record_pat_field_name_split);
+        // Foo { ref mut field } -> Foo { new_name: ref mut field }
+        //      ^ insert `new_name: `
+
+        // FIXME: instead of splitting the shorthand, recursively trigger a rename of the
+        // other name https://github.com/rust-lang/rust-analyzer/issues/6547
+        edit.insert(ident_pat.syntax().text_range().start(), format!("{new_name}: "));
+        return true;
     }
 
     false
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 9cf0bcf9190..abd4dc8300b 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -295,10 +295,10 @@ impl Definition {
         }
 
         // def is crate root
-        if let &Definition::Module(module) = self {
-            if module.is_crate_root() {
-                return SearchScope::reverse_dependencies(db, module.krate());
-            }
+        if let &Definition::Module(module) = self
+            && module.is_crate_root()
+        {
+            return SearchScope::reverse_dependencies(db, module.krate());
         }
 
         let module = match self.module(db) {
@@ -487,9 +487,9 @@ impl<'a> FindUsages<'a> {
         scope.entries.iter().map(|(&file_id, &search_range)| {
             let text = db.file_text(file_id.file_id(db)).text(db);
             let search_range =
-                search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&*text)));
+                search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&**text)));
 
-            (text, file_id, search_range)
+            (text.clone(), file_id, search_range)
         })
     }
 
@@ -683,51 +683,47 @@ impl<'a> FindUsages<'a> {
                                 }
                             } else if let Some(alias) =
                                 usage.ancestors().find_map(ast::TypeAlias::cast)
+                                && let Some(name) = alias.name()
+                                && seen
+                                    .insert(InFileWrapper::new(file_id, name.syntax().text_range()))
                             {
-                                if let Some(name) = alias.name() {
-                                    if seen.insert(InFileWrapper::new(
-                                        file_id,
-                                        name.syntax().text_range(),
-                                    )) {
-                                        if let Some(def) = is_alias(&alias) {
-                                            cov_mark::hit!(container_type_alias);
-                                            insert_type_alias(
-                                                sema.db,
-                                                &mut to_process,
-                                                name.text().as_str(),
-                                                def.into(),
-                                            );
-                                        } else {
-                                            cov_mark::hit!(same_name_different_def_type_alias);
-                                        }
-                                    }
+                                if let Some(def) = is_alias(&alias) {
+                                    cov_mark::hit!(container_type_alias);
+                                    insert_type_alias(
+                                        sema.db,
+                                        &mut to_process,
+                                        name.text().as_str(),
+                                        def.into(),
+                                    );
+                                } else {
+                                    cov_mark::hit!(same_name_different_def_type_alias);
                                 }
                             }
 
                             // We need to account for `Self`. It can only refer to our type inside an impl.
                             let impl_ = 'impl_: {
                                 for ancestor in usage.ancestors() {
-                                    if let Some(parent) = ancestor.parent() {
-                                        if let Some(parent) = ast::Impl::cast(parent) {
-                                            // Only if the GENERIC_PARAM_LIST is directly under impl, otherwise it may be in the self ty.
-                                            if matches!(
-                                                ancestor.kind(),
-                                                SyntaxKind::ASSOC_ITEM_LIST
-                                                    | SyntaxKind::WHERE_CLAUSE
-                                                    | SyntaxKind::GENERIC_PARAM_LIST
-                                            ) {
-                                                break;
-                                            }
-                                            if parent
-                                                .trait_()
-                                                .is_some_and(|trait_| *trait_.syntax() == ancestor)
-                                            {
-                                                break;
-                                            }
-
-                                            // Otherwise, found an impl where its self ty may be our type.
-                                            break 'impl_ Some(parent);
+                                    if let Some(parent) = ancestor.parent()
+                                        && let Some(parent) = ast::Impl::cast(parent)
+                                    {
+                                        // Only if the GENERIC_PARAM_LIST is directly under impl, otherwise it may be in the self ty.
+                                        if matches!(
+                                            ancestor.kind(),
+                                            SyntaxKind::ASSOC_ITEM_LIST
+                                                | SyntaxKind::WHERE_CLAUSE
+                                                | SyntaxKind::GENERIC_PARAM_LIST
+                                        ) {
+                                            break;
+                                        }
+                                        if parent
+                                            .trait_()
+                                            .is_some_and(|trait_| *trait_.syntax() == ancestor)
+                                        {
+                                            break;
                                         }
+
+                                        // Otherwise, found an impl where its self ty may be our type.
+                                        break 'impl_ Some(parent);
                                     }
                                 }
                                 None
@@ -858,14 +854,7 @@ impl<'a> FindUsages<'a> {
                 &finder,
                 name,
                 is_possibly_self.into_iter().map(|position| {
-                    (
-                        self.sema
-                            .db
-                            .file_text(position.file_id.file_id(self.sema.db))
-                            .text(self.sema.db),
-                        position.file_id,
-                        position.range,
-                    )
+                    (position.file_text(self.sema.db).clone(), position.file_id, position.range)
                 }),
                 |path, name_position| {
                     let has_self = path
@@ -1071,12 +1060,12 @@ impl<'a> FindUsages<'a> {
                 let file_text = sema.db.file_text(file_id.file_id(self.sema.db));
                 let text = file_text.text(sema.db);
                 let search_range =
-                    search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&*text)));
+                    search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&**text)));
 
                 let tree = LazyCell::new(|| sema.parse(file_id).syntax().clone());
                 let finder = &Finder::new("self");
 
-                for offset in Self::match_indices(&text, finder, search_range) {
+                for offset in Self::match_indices(text, finder, search_range) {
                     for name_ref in Self::find_nodes(sema, "self", file_id, &tree, offset)
                         .filter_map(ast::NameRef::cast)
                     {
@@ -1356,11 +1345,10 @@ impl ReferenceCategory {
                         if matches!(expr.op_kind()?, ast::BinaryOp::Assignment { .. }) {
                             // If the variable or field ends on the LHS's end then it's a Write
                             // (covers fields and locals). FIXME: This is not terribly accurate.
-                            if let Some(lhs) = expr.lhs() {
-                                if lhs.syntax().text_range().end() == r.syntax().text_range().end() {
+                            if let Some(lhs) = expr.lhs()
+                                && lhs.syntax().text_range().end() == r.syntax().text_range().end() {
                                     return Some(ReferenceCategory::WRITE)
                                 }
-                            }
                         }
                         Some(ReferenceCategory::READ)
                     },
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 c15cade84a5..9c4e6f5cbf8 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
@@ -252,10 +252,10 @@ impl SymbolIndex {
         let mut last_batch_start = 0;
 
         for idx in 0..symbols.len() {
-            if let Some(next_symbol) = symbols.get(idx + 1) {
-                if cmp(&symbols[last_batch_start], next_symbol) == Ordering::Equal {
-                    continue;
-                }
+            if let Some(next_symbol) = symbols.get(idx + 1)
+                && cmp(&symbols[last_batch_start], next_symbol) == Ordering::Equal
+            {
+                continue;
             }
 
             let start = last_batch_start;
@@ -371,10 +371,10 @@ impl Query {
                     if self.exclude_imports && symbol.is_import {
                         continue;
                     }
-                    if self.mode.check(&self.query, self.case_sensitive, symbol_name) {
-                        if let Some(b) = cb(symbol).break_value() {
-                            return Some(b);
-                        }
+                    if self.mode.check(&self.query, self.case_sensitive, symbol_name)
+                        && let Some(b) = cb(symbol).break_value()
+                    {
+                        return Some(b);
                     }
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs
index 7e8c921d9ed..1d4d8decf54 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs
@@ -230,11 +230,11 @@ pub fn lex_format_specifiers(
                 skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback);
             }
             continue;
-        } else if let '}' = first_char {
-            if let Some((_, '}')) = chars.peek() {
-                // Escaped format specifier, `}}`
-                read_escaped_format_specifier(&mut chars, &mut callback);
-            }
+        } else if let '}' = first_char
+            && let Some((_, '}')) = chars.peek()
+        {
+            // Escaped format specifier, `}}`
+            read_escaped_format_specifier(&mut chars, &mut callback);
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
index bdff64dd081..cefd8fd4967 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
@@ -79,14 +79,13 @@ pub fn preorder_expr_with_ctx_checker(
                 continue;
             }
         };
-        if let Some(let_stmt) = node.parent().and_then(ast::LetStmt::cast) {
-            if let_stmt.initializer().map(|it| it.syntax() != &node).unwrap_or(true)
-                && let_stmt.let_else().map(|it| it.syntax() != &node).unwrap_or(true)
-            {
-                // skipping potential const pat expressions in  let statements
-                preorder.skip_subtree();
-                continue;
-            }
+        if let Some(let_stmt) = node.parent().and_then(ast::LetStmt::cast)
+            && let_stmt.initializer().map(|it| it.syntax() != &node).unwrap_or(true)
+            && let_stmt.let_else().map(|it| it.syntax() != &node).unwrap_or(true)
+        {
+            // skipping potential const pat expressions in  let statements
+            preorder.skip_subtree();
+            continue;
         }
 
         match ast::Stmt::cast(node.clone()) {
@@ -306,10 +305,10 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
                 Some(ast::BlockModifier::AsyncGen(_)) => (),
                 None => (),
             }
-            if let Some(stmt_list) = b.stmt_list() {
-                if let Some(e) = stmt_list.tail_expr() {
-                    for_each_tail_expr(&e, cb);
-                }
+            if let Some(stmt_list) = b.stmt_list()
+                && let Some(e) = stmt_list.tail_expr()
+            {
+                for_each_tail_expr(&e, cb);
             }
         }
         ast::Expr::IfExpr(if_) => {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
index f63cd92694b..a91d436afcf 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
@@ -16,17 +16,17 @@ pub fn use_trivial_constructor(
 ) -> Option<Expr> {
     match ty.as_adt() {
         Some(hir::Adt::Enum(x)) => {
-            if let &[variant] = &*x.variants(db) {
-                if variant.kind(db) == hir::StructKind::Unit {
-                    let path = make::path_qualified(
-                        path,
-                        make::path_segment(make::name_ref(
-                            &variant.name(db).display_no_db(edition).to_smolstr(),
-                        )),
-                    );
+            if let &[variant] = &*x.variants(db)
+                && variant.kind(db) == hir::StructKind::Unit
+            {
+                let path = make::path_qualified(
+                    path,
+                    make::path_segment(make::name_ref(
+                        &variant.name(db).display_no_db(edition).to_smolstr(),
+                    )),
+                );
 
-                    return Some(make::expr_path(path));
-                }
+                return Some(make::expr_path(path));
             }
         }
         Some(hir::Adt::Struct(x)) if x.kind(db) == StructKind::Unit => {
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
index bf7dddacd8c..742d614bc56 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -148,37 +148,27 @@ pub(crate) fn json_in_items(
                             allow_unstable: true,
                         };
 
-                        if !scope_has("Serialize") {
-                            if let Some(PathResolution::Def(it)) = serialize_resolved {
-                                if let Some(it) = current_module.find_use_path(
-                                    sema.db,
-                                    it,
-                                    config.insert_use.prefix_kind,
-                                    cfg,
-                                ) {
-                                    insert_use(
-                                        &scope,
-                                        mod_path_to_ast(&it, edition),
-                                        &config.insert_use,
-                                    );
-                                }
-                            }
+                        if !scope_has("Serialize")
+                            && let Some(PathResolution::Def(it)) = serialize_resolved
+                            && let Some(it) = current_module.find_use_path(
+                                sema.db,
+                                it,
+                                config.insert_use.prefix_kind,
+                                cfg,
+                            )
+                        {
+                            insert_use(&scope, mod_path_to_ast(&it, edition), &config.insert_use);
                         }
-                        if !scope_has("Deserialize") {
-                            if let Some(PathResolution::Def(it)) = deserialize_resolved {
-                                if let Some(it) = current_module.find_use_path(
-                                    sema.db,
-                                    it,
-                                    config.insert_use.prefix_kind,
-                                    cfg,
-                                ) {
-                                    insert_use(
-                                        &scope,
-                                        mod_path_to_ast(&it, edition),
-                                        &config.insert_use,
-                                    );
-                                }
-                            }
+                        if !scope_has("Deserialize")
+                            && let Some(PathResolution::Def(it)) = deserialize_resolved
+                            && let Some(it) = current_module.find_use_path(
+                                sema.db,
+                                it,
+                                config.insert_use.prefix_kind,
+                                cfg,
+                            )
+                        {
+                            insert_use(&scope, mod_path_to_ast(&it, edition), &config.insert_use);
                         }
                         let mut sc = scb.finish();
                         sc.insert_source_edit(vfs_file_id, edit.finish());
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
index 7da799e0d49..893bfca6a12 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
@@ -227,12 +227,11 @@ fn get_default_constructor(
     // Look for a ::new() associated function
     let has_new_func = ty
         .iterate_assoc_items(ctx.sema.db, krate, |assoc_item| {
-            if let AssocItem::Function(func) = assoc_item {
-                if func.name(ctx.sema.db) == sym::new
-                    && func.assoc_fn_params(ctx.sema.db).is_empty()
-                {
-                    return Some(());
-                }
+            if let AssocItem::Function(func) = assoc_item
+                && func.name(ctx.sema.db) == sym::new
+                && func.assoc_fn_params(ctx.sema.db).is_empty()
+            {
+                return Some(());
             }
 
             None
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 8831efa3117..6e30bf92dba 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
@@ -12,14 +12,14 @@ pub(crate) fn need_mut(ctx: &DiagnosticsContext<'_>, d: &hir::NeedMut) -> Option
     let root = ctx.sema.db.parse_or_expand(d.span.file_id);
     let node = d.span.value.to_node(&root);
     let mut span = d.span;
-    if let Some(parent) = node.parent() {
-        if ast::BinExpr::can_cast(parent.kind()) {
-            // In case of an assignment, the diagnostic is provided on the variable name.
-            // We want to expand it to include the whole assignment, but only when this
-            // is an ordinary assignment, not a destructuring assignment. So, the direct
-            // parent is an assignment expression.
-            span = d.span.with_value(SyntaxNodePtr::new(&parent));
-        }
+    if let Some(parent) = node.parent()
+        && ast::BinExpr::can_cast(parent.kind())
+    {
+        // In case of an assignment, the diagnostic is provided on the variable name.
+        // We want to expand it to include the whole assignment, but only when this
+        // is an ordinary assignment, not a destructuring assignment. So, the direct
+        // parent is an assignment expression.
+        span = d.span.with_value(SyntaxNodePtr::new(&parent));
     };
 
     let fixes = (|| {
@@ -73,10 +73,10 @@ pub(crate) fn unused_mut(ctx: &DiagnosticsContext<'_>, d: &hir::UnusedMut) -> Op
             let ast = source.syntax();
             let Some(mut_token) = token(ast, T![mut]) else { continue };
             edit_builder.delete(mut_token.text_range());
-            if let Some(token) = mut_token.next_token() {
-                if token.kind() == SyntaxKind::WHITESPACE {
-                    edit_builder.delete(token.text_range());
-                }
+            if let Some(token) = mut_token.next_token()
+                && token.kind() == SyntaxKind::WHITESPACE
+            {
+                edit_builder.delete(token.text_range());
             }
         }
         let edit = edit_builder.finish();
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs
index d96c658d7b0..3a6e480f55e 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs
@@ -231,13 +231,13 @@ fn make_fixes(
     // If there's an existing `mod m;` statement matching the new one, don't emit a fix (it's
     // probably `#[cfg]`d out).
     for item in items.clone() {
-        if let ast::Item::Module(m) = item {
-            if let Some(name) = m.name() {
-                if m.item_list().is_none() && name.to_string() == new_mod_name {
-                    cov_mark::hit!(unlinked_file_skip_fix_when_mod_already_exists);
-                    return None;
-                }
-            }
+        if let ast::Item::Module(m) = item
+            && let Some(name) = m.name()
+            && m.item_list().is_none()
+            && name.to_string() == new_mod_name
+        {
+            cov_mark::hit!(unlinked_file_skip_fix_when_mod_already_exists);
+            return None;
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
index 72bd66d1c8b..a1db92641f5 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -568,10 +568,10 @@ fn handle_diag_from_macros(
         diag.fixes = None;
 
         // All Clippy lints report in macros, see https://github.com/rust-lang/rust-clippy/blob/903293b199364/declare_clippy_lint/src/lib.rs#L172.
-        if let DiagnosticCode::RustcLint(lint) = diag.code {
-            if !LINTS_TO_REPORT_IN_EXTERNAL_MACROS.contains(lint) {
-                return false;
-            }
+        if let DiagnosticCode::RustcLint(lint) = diag.code
+            && !LINTS_TO_REPORT_IN_EXTERNAL_MACROS.contains(lint)
+        {
+            return false;
         };
     }
     true
@@ -760,35 +760,35 @@ fn cfg_attr_lint_attrs(
     }
 
     while let Some(value) = iter.next() {
-        if let Some(token) = value.as_token() {
-            if token.kind() == SyntaxKind::IDENT {
-                let severity = match token.text() {
-                    "allow" | "expect" => Some(Severity::Allow),
-                    "warn" => Some(Severity::Warning),
-                    "forbid" | "deny" => Some(Severity::Error),
-                    "cfg_attr" => {
-                        if let Some(NodeOrToken::Node(value)) = iter.next() {
-                            cfg_attr_lint_attrs(sema, &value, lint_attrs);
-                        }
-                        None
-                    }
-                    _ => None,
-                };
-                if let Some(severity) = severity {
-                    let lints = iter.next();
-                    if let Some(NodeOrToken::Node(lints)) = lints {
-                        lint_attrs.push((severity, lints));
+        if let Some(token) = value.as_token()
+            && token.kind() == SyntaxKind::IDENT
+        {
+            let severity = match token.text() {
+                "allow" | "expect" => Some(Severity::Allow),
+                "warn" => Some(Severity::Warning),
+                "forbid" | "deny" => Some(Severity::Error),
+                "cfg_attr" => {
+                    if let Some(NodeOrToken::Node(value)) = iter.next() {
+                        cfg_attr_lint_attrs(sema, &value, lint_attrs);
                     }
+                    None
+                }
+                _ => None,
+            };
+            if let Some(severity) = severity {
+                let lints = iter.next();
+                if let Some(NodeOrToken::Node(lints)) = lints {
+                    lint_attrs.push((severity, lints));
                 }
             }
         }
     }
 
-    if prev_len != lint_attrs.len() {
-        if let Some(false) | None = sema.check_cfg_attr(value) {
-            // Discard the attributes when the condition is false.
-            lint_attrs.truncate(prev_len);
-        }
+    if prev_len != lint_attrs.len()
+        && let Some(false) | None = sema.check_cfg_attr(value)
+    {
+        // Discard the attributes when the condition is false.
+        lint_attrs.truncate(prev_len);
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
index 4e4bd47e1c2..181993154e5 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
@@ -229,7 +229,7 @@ pub(crate) fn check_diagnostics_with_config(
         let line_index = db.line_index(file_id);
 
         let mut actual = annotations.remove(&file_id).unwrap_or_default();
-        let mut expected = extract_annotations(&db.file_text(file_id).text(&db));
+        let mut expected = extract_annotations(db.file_text(file_id).text(&db));
         expected.sort_by_key(|(range, s)| (range.start(), s.clone()));
         actual.sort_by_key(|(range, s)| (range.start(), s.clone()));
         // FIXME: We should panic on duplicates instead, but includes currently cause us to report
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 e4b20f3f1aa..43ad12c1f69 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
@@ -186,7 +186,7 @@ impl<'db> MatchFinder<'db> {
                     replacing::matches_to_edit(
                         self.sema.db,
                         &matches,
-                        &self.sema.db.file_text(file_id).text(self.sema.db),
+                        self.sema.db.file_text(file_id).text(self.sema.db),
                         &self.rules,
                     ),
                 )
@@ -228,7 +228,7 @@ impl<'db> MatchFinder<'db> {
         let file = self.sema.parse(file_id);
         let mut res = Vec::new();
         let file_text = self.sema.db.file_text(file_id.file_id(self.sema.db)).text(self.sema.db);
-        let mut remaining_text = &*file_text;
+        let mut remaining_text = &**file_text;
         let mut base = 0;
         let len = snippet.len() as u32;
         while let Some(offset) = remaining_text.find(snippet) {
@@ -283,17 +283,16 @@ impl<'db> MatchFinder<'db> {
                         node: node.clone(),
                     });
                 }
-            } else if let Some(macro_call) = ast::MacroCall::cast(node.clone()) {
-                if let Some(expanded) = self.sema.expand_macro_call(&macro_call) {
-                    if let Some(tt) = macro_call.token_tree() {
-                        self.output_debug_for_nodes_at_range(
-                            &expanded.value,
-                            range,
-                            &Some(self.sema.original_range(tt.syntax())),
-                            out,
-                        );
-                    }
-                }
+            } else if let Some(macro_call) = ast::MacroCall::cast(node.clone())
+                && let Some(expanded) = self.sema.expand_macro_call(&macro_call)
+                && let Some(tt) = macro_call.token_tree()
+            {
+                self.output_debug_for_nodes_at_range(
+                    &expanded.value,
+                    range,
+                    &Some(self.sema.original_range(tt.syntax())),
+                    out,
+                );
             }
             self.output_debug_for_nodes_at_range(&node, range, restrict_range, out);
         }
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
index b350315ba54..f21132c297e 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
@@ -156,12 +156,11 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
     /// processing a macro expansion and we want to fail the match if we're working with a node that
     /// didn't originate from the token tree of the macro call.
     fn validate_range(&self, range: &FileRange) -> Result<(), MatchFailed> {
-        if let Some(restrict_range) = &self.restrict_range {
-            if restrict_range.file_id != range.file_id
-                || !restrict_range.range.contains_range(range.range)
-            {
-                fail_match!("Node originated from a macro");
-            }
+        if let Some(restrict_range) = &self.restrict_range
+            && (restrict_range.file_id != range.file_id
+                || !restrict_range.range.contains_range(range.range))
+        {
+            fail_match!("Node originated from a macro");
         }
         Ok(())
     }
@@ -404,30 +403,27 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
         // Build a map keyed by field name.
         let mut fields_by_name: FxHashMap<SmolStr, SyntaxNode> = FxHashMap::default();
         for child in code.children() {
-            if let Some(record) = ast::RecordExprField::cast(child.clone()) {
-                if let Some(name) = record.field_name() {
-                    fields_by_name.insert(name.text().into(), child.clone());
-                }
+            if let Some(record) = ast::RecordExprField::cast(child.clone())
+                && let Some(name) = record.field_name()
+            {
+                fields_by_name.insert(name.text().into(), child.clone());
             }
         }
         for p in pattern.children_with_tokens() {
-            if let SyntaxElement::Node(p) = p {
-                if let Some(name_element) = p.first_child_or_token() {
-                    if self.get_placeholder(&name_element).is_some() {
-                        // If the pattern is using placeholders for field names then order
-                        // independence doesn't make sense. Fall back to regular ordered
-                        // matching.
-                        return self.attempt_match_node_children(phase, pattern, code);
-                    }
-                    if let Some(ident) = only_ident(name_element) {
-                        let code_record = fields_by_name.remove(ident.text()).ok_or_else(|| {
-                            match_error!(
-                                "Placeholder has record field '{}', but code doesn't",
-                                ident
-                            )
-                        })?;
-                        self.attempt_match_node(phase, &p, &code_record)?;
-                    }
+            if let SyntaxElement::Node(p) = p
+                && let Some(name_element) = p.first_child_or_token()
+            {
+                if self.get_placeholder(&name_element).is_some() {
+                    // If the pattern is using placeholders for field names then order
+                    // independence doesn't make sense. Fall back to regular ordered
+                    // matching.
+                    return self.attempt_match_node_children(phase, pattern, code);
+                }
+                if let Some(ident) = only_ident(name_element) {
+                    let code_record = fields_by_name.remove(ident.text()).ok_or_else(|| {
+                        match_error!("Placeholder has record field '{}', but code doesn't", ident)
+                    })?;
+                    self.attempt_match_node(phase, &p, &code_record)?;
                 }
             }
         }
@@ -476,14 +472,13 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
                             }
                         }
                         SyntaxElement::Node(n) => {
-                            if let Some(first_token) = n.first_token() {
-                                if Some(first_token.text()) == next_pattern_token.as_deref() {
-                                    if let Some(SyntaxElement::Node(p)) = pattern.next() {
-                                        // We have a subtree that starts with the next token in our pattern.
-                                        self.attempt_match_token_tree(phase, &p, n)?;
-                                        break;
-                                    }
-                                }
+                            if let Some(first_token) = n.first_token()
+                                && Some(first_token.text()) == next_pattern_token.as_deref()
+                                && let Some(SyntaxElement::Node(p)) = pattern.next()
+                            {
+                                // We have a subtree that starts with the next token in our pattern.
+                                self.attempt_match_token_tree(phase, &p, n)?;
+                                break;
                             }
                         }
                     };
@@ -562,23 +557,22 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
                 let deref_count = self.check_expr_type(pattern_type, expr)?;
                 let pattern_receiver = pattern_args.next();
                 self.attempt_match_opt(phase, pattern_receiver.clone(), code.receiver())?;
-                if let Phase::Second(match_out) = phase {
-                    if let Some(placeholder_value) = pattern_receiver
+                if let Phase::Second(match_out) = phase
+                    && let Some(placeholder_value) = pattern_receiver
                         .and_then(|n| self.get_placeholder_for_node(n.syntax()))
                         .and_then(|placeholder| {
                             match_out.placeholder_values.get_mut(&placeholder.ident)
                         })
-                    {
-                        placeholder_value.autoderef_count = deref_count;
-                        placeholder_value.autoref_kind = self
-                            .sema
-                            .resolve_method_call_as_callable(code)
-                            .and_then(|callable| {
-                                let (self_param, _) = callable.receiver_param(self.sema.db)?;
-                                Some(self.sema.source(self_param)?.value.kind())
-                            })
-                            .unwrap_or(ast::SelfParamKind::Owned);
-                    }
+                {
+                    placeholder_value.autoderef_count = deref_count;
+                    placeholder_value.autoref_kind = self
+                        .sema
+                        .resolve_method_call_as_callable(code)
+                        .and_then(|callable| {
+                            let (self_param, _) = callable.receiver_param(self.sema.db)?;
+                            Some(self.sema.source(self_param)?.value.kind())
+                        })
+                        .unwrap_or(ast::SelfParamKind::Owned);
                 }
             }
         } else {
@@ -698,12 +692,11 @@ impl Phase<'_> {
     }
 
     fn record_ignored_comments(&mut self, token: &SyntaxToken) {
-        if token.kind() == SyntaxKind::COMMENT {
-            if let Phase::Second(match_out) = self {
-                if let Some(comment) = ast::Comment::cast(token.clone()) {
-                    match_out.ignored_comments.push(comment);
-                }
-            }
+        if token.kind() == SyntaxKind::COMMENT
+            && let Phase::Second(match_out) = self
+            && let Some(comment) = ast::Comment::cast(token.clone())
+        {
+            match_out.ignored_comments.push(comment);
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs
index 752edd6535a..16287a439c3 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/replacing.rs
@@ -112,12 +112,12 @@ impl<'db> ReplacementRenderer<'_, 'db> {
             self.out.push_str(&mod_path.display(self.db, self.edition).to_string());
             // Emit everything except for the segment's name-ref, since we already effectively
             // emitted that as part of `mod_path`.
-            if let Some(path) = ast::Path::cast(node.clone()) {
-                if let Some(segment) = path.segment() {
-                    for node_or_token in segment.syntax().children_with_tokens() {
-                        if node_or_token.kind() != SyntaxKind::NAME_REF {
-                            self.render_node_or_token(&node_or_token);
-                        }
+            if let Some(path) = ast::Path::cast(node.clone())
+                && let Some(segment) = path.segment()
+            {
+                for node_or_token in segment.syntax().children_with_tokens() {
+                    if node_or_token.kind() != SyntaxKind::NAME_REF {
+                        self.render_node_or_token(&node_or_token);
                     }
                 }
             }
@@ -242,15 +242,15 @@ fn token_is_method_call_receiver(token: &SyntaxToken) -> bool {
 }
 
 fn parse_as_kind(code: &str, kind: SyntaxKind) -> Option<SyntaxNode> {
-    if ast::Expr::can_cast(kind) {
-        if let Ok(expr) = fragments::expr(code) {
-            return Some(expr);
-        }
+    if ast::Expr::can_cast(kind)
+        && let Ok(expr) = fragments::expr(code)
+    {
+        return Some(expr);
     }
-    if ast::Item::can_cast(kind) {
-        if let Ok(item) = fragments::item(code) {
-            return Some(item);
-        }
+    if ast::Item::can_cast(kind)
+        && let Ok(item) = fragments::item(code)
+    {
+        return Some(item);
     }
     None
 }
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs
index 8f28a1cd3a6..a4e2cfbaee2 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs
@@ -83,21 +83,17 @@ impl<'db> Resolver<'_, 'db> {
         let ufcs_function_calls = resolved_paths
             .iter()
             .filter_map(|(path_node, resolved)| {
-                if let Some(grandparent) = path_node.parent().and_then(|parent| parent.parent()) {
-                    if let Some(call_expr) = ast::CallExpr::cast(grandparent.clone()) {
-                        if let hir::PathResolution::Def(hir::ModuleDef::Function(function)) =
-                            resolved.resolution
-                        {
-                            if function.as_assoc_item(self.resolution_scope.scope.db).is_some() {
-                                let qualifier_type =
-                                    self.resolution_scope.qualifier_type(path_node);
-                                return Some((
-                                    grandparent,
-                                    UfcsCallInfo { call_expr, function, qualifier_type },
-                                ));
-                            }
-                        }
-                    }
+                if let Some(grandparent) = path_node.parent().and_then(|parent| parent.parent())
+                    && let Some(call_expr) = ast::CallExpr::cast(grandparent.clone())
+                    && let hir::PathResolution::Def(hir::ModuleDef::Function(function)) =
+                        resolved.resolution
+                    && function.as_assoc_item(self.resolution_scope.scope.db).is_some()
+                {
+                    let qualifier_type = self.resolution_scope.qualifier_type(path_node);
+                    return Some((
+                        grandparent,
+                        UfcsCallInfo { call_expr, function, qualifier_type },
+                    ));
                 }
                 None
             })
@@ -153,12 +149,11 @@ impl<'db> Resolver<'_, 'db> {
     /// Returns whether `path` contains a placeholder, but ignores any placeholders within type
     /// arguments.
     fn path_contains_placeholder(&self, path: &ast::Path) -> bool {
-        if let Some(segment) = path.segment() {
-            if let Some(name_ref) = segment.name_ref() {
-                if self.placeholders_by_stand_in.contains_key(name_ref.text().as_str()) {
-                    return true;
-                }
-            }
+        if let Some(segment) = path.segment()
+            && let Some(name_ref) = segment.name_ref()
+            && self.placeholders_by_stand_in.contains_key(name_ref.text().as_str())
+        {
+            return true;
         }
         if let Some(qualifier) = path.qualifier() {
             return self.path_contains_placeholder(&qualifier);
@@ -252,14 +247,12 @@ impl<'db> ResolutionScope<'db> {
 
     fn qualifier_type(&self, path: &SyntaxNode) -> Option<hir::Type<'db>> {
         use syntax::ast::AstNode;
-        if let Some(path) = ast::Path::cast(path.clone()) {
-            if let Some(qualifier) = path.qualifier() {
-                if let Some(hir::PathResolution::Def(hir::ModuleDef::Adt(adt))) =
-                    self.resolve_path(&qualifier)
-                {
-                    return Some(adt.ty(self.scope.db));
-                }
-            }
+        if let Some(path) = ast::Path::cast(path.clone())
+            && let Some(qualifier) = path.qualifier()
+            && let Some(hir::PathResolution::Def(hir::ModuleDef::Adt(adt))) =
+                self.resolve_path(&qualifier)
+        {
+            return Some(adt.ty(self.scope.db));
         }
         None
     }
@@ -299,11 +292,11 @@ fn pick_node_for_resolution(node: SyntaxNode) -> SyntaxNode {
 /// Returns whether `path` or any of its qualifiers contains type arguments.
 fn path_contains_type_arguments(path: Option<ast::Path>) -> bool {
     if let Some(path) = path {
-        if let Some(segment) = path.segment() {
-            if segment.generic_arg_list().is_some() {
-                cov_mark::hit!(type_arguments_within_path);
-                return true;
-            }
+        if let Some(segment) = path.segment()
+            && segment.generic_arg_list().is_some()
+        {
+            cov_mark::hit!(type_arguments_within_path);
+            return true;
         }
         return path_contains_type_arguments(path.qualifier());
     }
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs
index 99a98fb2a71..72f857ceda9 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs
@@ -187,16 +187,15 @@ impl<'db> MatchFinder<'db> {
         self.try_add_match(rule, code, restrict_range, matches_out);
         // If we've got a macro call, we already tried matching it pre-expansion, which is the only
         // way to match the whole macro, now try expanding it and matching the expansion.
-        if let Some(macro_call) = ast::MacroCall::cast(code.clone()) {
-            if let Some(expanded) = self.sema.expand_macro_call(&macro_call) {
-                if let Some(tt) = macro_call.token_tree() {
-                    // When matching within a macro expansion, we only want to allow matches of
-                    // nodes that originated entirely from within the token tree of the macro call.
-                    // i.e. we don't want to match something that came from the macro itself.
-                    if let Some(range) = self.sema.original_range_opt(tt.syntax()) {
-                        self.slow_scan_node(&expanded.value, rule, &Some(range), matches_out);
-                    }
-                }
+        if let Some(macro_call) = ast::MacroCall::cast(code.clone())
+            && let Some(expanded) = self.sema.expand_macro_call(&macro_call)
+            && let Some(tt) = macro_call.token_tree()
+        {
+            // When matching within a macro expansion, we only want to allow matches of
+            // nodes that originated entirely from within the token tree of the macro call.
+            // i.e. we don't want to match something that came from the macro itself.
+            if let Some(range) = self.sema.original_range_opt(tt.syntax()) {
+                self.slow_scan_node(&expanded.value, rule, &Some(range), matches_out);
             }
         }
         for child in code.children() {
@@ -241,10 +240,10 @@ impl<'db> MatchFinder<'db> {
 
 /// Returns whether we support matching within `node` and all of its ancestors.
 fn is_search_permitted_ancestors(node: &SyntaxNode) -> bool {
-    if let Some(parent) = node.parent() {
-        if !is_search_permitted_ancestors(&parent) {
-            return false;
-        }
+    if let Some(parent) = node.parent()
+        && !is_search_permitted_ancestors(&parent)
+    {
+        return false;
     }
     is_search_permitted(node)
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
index 05196ac98c0..dec1889926d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
@@ -159,10 +159,10 @@ pub(crate) fn annotations(
                     node.value.syntax().text_range(),
                     Some(name),
                 );
-                if res.call_site.0.file_id == source_file_id {
-                    if let Some(name_range) = res.call_site.1 {
-                        return Some((res.call_site.0.range, Some(name_range)));
-                    }
+                if res.call_site.0.file_id == source_file_id
+                    && let Some(name_range) = res.call_site.1
+                {
+                    return Some((res.call_site.0.range, Some(name_range)));
                 }
             };
             // otherwise try upmapping the entire node out of attributes
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 f31886b9697..ad84eacfb3e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -96,14 +96,14 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
     let (name, expanded, kind) = loop {
         let node = anc.next()?;
 
-        if let Some(item) = ast::Item::cast(node.clone()) {
-            if let Some(def) = sema.resolve_attr_macro_call(&item) {
-                break (
-                    def.name(db).display(db, file_id.edition(db)).to_string(),
-                    expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
-                    SyntaxKind::MACRO_ITEMS,
-                );
-            }
+        if let Some(item) = ast::Item::cast(node.clone())
+            && let Some(def) = sema.resolve_attr_macro_call(&item)
+        {
+            break (
+                def.name(db).display(db, file_id.edition(db)).to_string(),
+                expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
+                SyntaxKind::MACRO_ITEMS,
+            );
         }
         if let Some(mac) = ast::MacroCall::cast(node) {
             let mut name = mac.path()?.segment()?.name_ref()?.to_string();
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 a374f9752fc..2926384c407 100644
--- a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
@@ -81,10 +81,10 @@ fn try_extend_selection(
             if token.text_range() != range {
                 return Some(token.text_range());
             }
-            if let Some(comment) = ast::Comment::cast(token.clone()) {
-                if let Some(range) = extend_comments(comment) {
-                    return Some(range);
-                }
+            if let Some(comment) = ast::Comment::cast(token.clone())
+                && let Some(range) = extend_comments(comment)
+            {
+                return Some(range);
             }
             token.parent()?
         }
@@ -92,12 +92,11 @@ fn try_extend_selection(
     };
 
     // if we are in single token_tree, we maybe live in macro or attr
-    if node.kind() == TOKEN_TREE {
-        if let Some(macro_call) = node.ancestors().find_map(ast::MacroCall::cast) {
-            if let Some(range) = extend_tokens_from_range(sema, macro_call, range) {
-                return Some(range);
-            }
-        }
+    if node.kind() == TOKEN_TREE
+        && let Some(macro_call) = node.ancestors().find_map(ast::MacroCall::cast)
+        && let Some(range) = extend_tokens_from_range(sema, macro_call, range)
+    {
+        return Some(range);
     }
 
     if node.text_range() != range {
@@ -106,10 +105,10 @@ fn try_extend_selection(
 
     let node = shallowest_node(&node);
 
-    if node.parent().is_some_and(|n| list_kinds.contains(&n.kind())) {
-        if let Some(range) = extend_list_item(&node) {
-            return Some(range);
-        }
+    if node.parent().is_some_and(|n| list_kinds.contains(&n.kind()))
+        && let Some(range) = extend_list_item(&node)
+    {
+        return Some(range);
     }
 
     node.parent().map(|it| it.text_range())
@@ -221,19 +220,20 @@ fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextSize) -> TextRange
     let prefix = TextRange::new(ws.text_range().start(), offset) - ws.text_range().start();
     let ws_suffix = &ws_text[suffix];
     let ws_prefix = &ws_text[prefix];
-    if ws_text.contains('\n') && !ws_suffix.contains('\n') {
-        if let Some(node) = ws.next_sibling_or_token() {
-            let start = match ws_prefix.rfind('\n') {
-                Some(idx) => ws.text_range().start() + TextSize::from((idx + 1) as u32),
-                None => node.text_range().start(),
-            };
-            let end = if root.text().char_at(node.text_range().end()) == Some('\n') {
-                node.text_range().end() + TextSize::of('\n')
-            } else {
-                node.text_range().end()
-            };
-            return TextRange::new(start, end);
-        }
+    if ws_text.contains('\n')
+        && !ws_suffix.contains('\n')
+        && let Some(node) = ws.next_sibling_or_token()
+    {
+        let start = match ws_prefix.rfind('\n') {
+            Some(idx) => ws.text_range().start() + TextSize::from((idx + 1) as u32),
+            None => node.text_range().start(),
+        };
+        let end = if root.text().char_at(node.text_range().end()) == Some('\n') {
+            node.text_range().end() + TextSize::of('\n')
+        } else {
+            node.text_range().end()
+        };
+        return TextRange::new(start, end);
     }
     ws.text_range()
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
index 1901bcc797e..ac64413effe 100755
--- a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
@@ -61,30 +61,29 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
             };
             if is_multiline {
                 // for the func with multiline param list
-                if matches!(element.kind(), FN) {
-                    if let NodeOrToken::Node(node) = &element {
-                        if let Some(fn_node) = ast::Fn::cast(node.clone()) {
-                            if !fn_node
-                                .param_list()
-                                .map(|param_list| param_list.syntax().text().contains_char('\n'))
-                                .unwrap_or(false)
-                            {
-                                continue;
-                            }
+                if matches!(element.kind(), FN)
+                    && let NodeOrToken::Node(node) = &element
+                    && let Some(fn_node) = ast::Fn::cast(node.clone())
+                {
+                    if !fn_node
+                        .param_list()
+                        .map(|param_list| param_list.syntax().text().contains_char('\n'))
+                        .unwrap_or(false)
+                    {
+                        continue;
+                    }
 
-                            if fn_node.body().is_some() {
-                                // Get the actual start of the function (excluding doc comments)
-                                let fn_start = fn_node
-                                    .fn_token()
-                                    .map(|token| token.text_range().start())
-                                    .unwrap_or(node.text_range().start());
-                                res.push(Fold {
-                                    range: TextRange::new(fn_start, node.text_range().end()),
-                                    kind: FoldKind::Function,
-                                });
-                                continue;
-                            }
-                        }
+                    if fn_node.body().is_some() {
+                        // Get the actual start of the function (excluding doc comments)
+                        let fn_start = fn_node
+                            .fn_token()
+                            .map(|token| token.text_range().start())
+                            .unwrap_or(node.text_range().start());
+                        res.push(Fold {
+                            range: TextRange::new(fn_start, node.text_range().end()),
+                            kind: FoldKind::Function,
+                        });
+                        continue;
                     }
                 }
                 res.push(Fold { range: element.text_range(), kind });
@@ -120,14 +119,13 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
                 match_ast! {
                     match node {
                         ast::Module(module) => {
-                            if module.item_list().is_none() {
-                                if let Some(range) = contiguous_range_for_item_group(
+                            if module.item_list().is_none()
+                                && let Some(range) = contiguous_range_for_item_group(
                                     module,
                                     &mut visited_nodes,
                                 ) {
                                     res.push(Fold { range, kind: FoldKind::Modules })
                                 }
-                            }
                         },
                         ast::Use(use_) => {
                             if let Some(range) = contiguous_range_for_item_group(use_, &mut visited_nodes) {
@@ -212,11 +210,11 @@ where
     for element in first.syntax().siblings_with_tokens(Direction::Next) {
         let node = match element {
             NodeOrToken::Token(token) => {
-                if let Some(ws) = ast::Whitespace::cast(token) {
-                    if !ws.spans_multiple_lines() {
-                        // Ignore whitespace without blank lines
-                        continue;
-                    }
+                if let Some(ws) = ast::Whitespace::cast(token)
+                    && !ws.spans_multiple_lines()
+                {
+                    // Ignore whitespace without blank lines
+                    continue;
                 }
                 // There is a blank line or another token, which means that the
                 // group ends here
@@ -270,21 +268,21 @@ fn contiguous_range_for_comment(
     for element in first.syntax().siblings_with_tokens(Direction::Next) {
         match element {
             NodeOrToken::Token(token) => {
-                if let Some(ws) = ast::Whitespace::cast(token.clone()) {
-                    if !ws.spans_multiple_lines() {
-                        // Ignore whitespace without blank lines
-                        continue;
-                    }
+                if let Some(ws) = ast::Whitespace::cast(token.clone())
+                    && !ws.spans_multiple_lines()
+                {
+                    // Ignore whitespace without blank lines
+                    continue;
                 }
-                if let Some(c) = ast::Comment::cast(token) {
-                    if c.kind() == group_kind {
-                        let text = c.text().trim_start();
-                        // regions are not real comments
-                        if !(text.starts_with(REGION_START) || text.starts_with(REGION_END)) {
-                            visited.insert(c.clone());
-                            last = c;
-                            continue;
-                        }
+                if let Some(c) = ast::Comment::cast(token)
+                    && c.kind() == group_kind
+                {
+                    let text = c.text().trim_start();
+                    // regions are not real comments
+                    if !(text.starts_with(REGION_START) || text.starts_with(REGION_END)) {
+                        visited.insert(c.clone());
+                        last = c;
+                        continue;
                     }
                 }
                 // The comment group ends because either:
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 29fc68bb50f..84e41277390 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -94,18 +94,17 @@ pub(crate) fn goto_definition(
             let parent = token.value.parent()?;
 
             let token_file_id = token.file_id;
-            if let Some(token) = ast::String::cast(token.value.clone()) {
-                if let Some(x) =
+            if let Some(token) = ast::String::cast(token.value.clone())
+                && let Some(x) =
                     try_lookup_include_path(sema, InFile::new(token_file_id, token), file_id)
-                {
-                    return Some(vec![x]);
-                }
+            {
+                return Some(vec![x]);
             }
 
-            if ast::TokenTree::can_cast(parent.kind()) {
-                if let Some(x) = try_lookup_macro_def_in_macro_use(sema, token.value) {
-                    return Some(vec![x]);
-                }
+            if ast::TokenTree::can_cast(parent.kind())
+                && let Some(x) = try_lookup_macro_def_in_macro_use(sema, token.value)
+            {
+                return Some(vec![x]);
             }
 
             Some(
@@ -245,12 +244,11 @@ fn try_lookup_macro_def_in_macro_use(
     let krate = extern_crate.resolved_crate(sema.db)?;
 
     for mod_def in krate.root_module().declarations(sema.db) {
-        if let ModuleDef::Macro(mac) = mod_def {
-            if mac.name(sema.db).as_str() == token.text() {
-                if let Some(nav) = mac.try_to_nav(sema.db) {
-                    return Some(nav.call_site);
-                }
-            }
+        if let ModuleDef::Macro(mac) = mod_def
+            && mac.name(sema.db).as_str() == token.text()
+            && let Some(nav) = mac.try_to_nav(sema.db)
+        {
+            return Some(nav.call_site);
         }
     }
 
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 356bd69aa44..9960e79a538 100644
--- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
@@ -722,20 +722,19 @@ impl<'a> WalkExpandedExprCtx<'a> {
                         self.depth += 1;
                     }
 
-                    if let ast::Expr::MacroExpr(expr) = expr {
-                        if let Some(expanded) =
+                    if let ast::Expr::MacroExpr(expr) = expr
+                        && let Some(expanded) =
                             expr.macro_call().and_then(|call| self.sema.expand_macro_call(&call))
-                        {
-                            match_ast! {
-                                match (expanded.value) {
-                                    ast::MacroStmts(it) => {
-                                        self.handle_expanded(it, cb);
-                                    },
-                                    ast::Expr(it) => {
-                                        self.walk(&it, cb);
-                                    },
-                                    _ => {}
-                                }
+                    {
+                        match_ast! {
+                            match (expanded.value) {
+                                ast::MacroStmts(it) => {
+                                    self.handle_expanded(it, cb);
+                                },
+                                ast::Expr(it) => {
+                                    self.walk(&it, cb);
+                                },
+                                _ => {}
                             }
                         }
                     }
@@ -755,10 +754,10 @@ impl<'a> WalkExpandedExprCtx<'a> {
         }
 
         for stmt in expanded.statements() {
-            if let ast::Stmt::ExprStmt(stmt) = stmt {
-                if let Some(expr) = stmt.expr() {
-                    self.walk(&expr, cb);
-                }
+            if let ast::Stmt::ExprStmt(stmt) = stmt
+                && let Some(expr) = stmt.expr()
+            {
+                self.walk(&expr, cb);
             }
         }
     }
@@ -806,12 +805,12 @@ pub(crate) fn highlight_unsafe_points(
         push_to_highlights(unsafe_token_file_id, Some(unsafe_token.text_range()));
 
         // highlight unsafe operations
-        if let Some(block) = block_expr {
-            if let Some(body) = sema.body_for(InFile::new(unsafe_token_file_id, block.syntax())) {
-                let unsafe_ops = sema.get_unsafe_ops(body);
-                for unsafe_op in unsafe_ops {
-                    push_to_highlights(unsafe_op.file_id, Some(unsafe_op.value.text_range()));
-                }
+        if let Some(block) = block_expr
+            && let Some(body) = sema.body_for(InFile::new(unsafe_token_file_id, block.syntax()))
+        {
+            let unsafe_ops = sema.get_unsafe_ops(body);
+            for unsafe_op in unsafe_ops {
+                push_to_highlights(unsafe_op.file_id, Some(unsafe_op.value.text_range()));
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index e4d6279759e..44c98a43f69 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -244,17 +244,15 @@ fn hover_offset(
                     let node = token.parent()?;
 
                     // special case macro calls, we wanna render the invoked arm index
-                    if let Some(name) = ast::NameRef::cast(node.clone()) {
-                        if let Some(path_seg) =
+                    if let Some(name) = ast::NameRef::cast(node.clone())
+                        && let Some(path_seg) =
                             name.syntax().parent().and_then(ast::PathSegment::cast)
-                        {
-                            if let Some(macro_call) = path_seg
+                            && let Some(macro_call) = path_seg
                                 .parent_path()
                                 .syntax()
                                 .parent()
                                 .and_then(ast::MacroCall::cast)
-                            {
-                                if let Some(macro_) = sema.resolve_macro_call(&macro_call) {
+                                && let Some(macro_) = sema.resolve_macro_call(&macro_call) {
                                     break 'a vec![(
                                         (Definition::Macro(macro_), None),
                                         sema.resolve_macro_call_arm(&macro_call),
@@ -262,9 +260,6 @@ fn hover_offset(
                                         node,
                                     )];
                                 }
-                            }
-                        }
-                    }
 
                     match IdentClass::classify_node(sema, &node)? {
                         // It's better for us to fall back to the keyword hover here,
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 670210d4998..51b5900e815 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -95,23 +95,25 @@ pub(super) fn try_expr(
     if let Some((hir::Adt::Enum(inner), hir::Adt::Enum(body))) = adts {
         let famous_defs = FamousDefs(sema, sema.scope(try_expr.syntax())?.krate());
         // special case for two options, there is no value in showing them
-        if let Some(option_enum) = famous_defs.core_option_Option() {
-            if inner == option_enum && body == option_enum {
-                cov_mark::hit!(hover_try_expr_opt_opt);
-                return None;
-            }
+        if let Some(option_enum) = famous_defs.core_option_Option()
+            && inner == option_enum
+            && body == option_enum
+        {
+            cov_mark::hit!(hover_try_expr_opt_opt);
+            return None;
         }
 
         // special case two results to show the error variants only
-        if let Some(result_enum) = famous_defs.core_result_Result() {
-            if inner == result_enum && body == result_enum {
-                let error_type_args =
-                    inner_ty.type_arguments().nth(1).zip(body_ty.type_arguments().nth(1));
-                if let Some((inner, body)) = error_type_args {
-                    inner_ty = inner;
-                    body_ty = body;
-                    "Try Error".clone_into(&mut s);
-                }
+        if let Some(result_enum) = famous_defs.core_result_Result()
+            && inner == result_enum
+            && body == result_enum
+        {
+            let error_type_args =
+                inner_ty.type_arguments().nth(1).zip(body_ty.type_arguments().nth(1));
+            if let Some((inner, body)) = error_type_args {
+                inner_ty = inner;
+                body_ty = body;
+                "Try Error".clone_into(&mut s);
             }
         }
     }
@@ -1132,10 +1134,10 @@ fn markup(
 ) -> (Markup, Option<DocsRangeMap>) {
     let mut buf = String::new();
 
-    if let Some(mod_path) = mod_path {
-        if !mod_path.is_empty() {
-            format_to!(buf, "```rust\n{}\n```\n\n", mod_path);
-        }
+    if let Some(mod_path) = mod_path
+        && !mod_path.is_empty()
+    {
+        format_to!(buf, "```rust\n{}\n```\n\n", mod_path);
     }
     format_to!(buf, "```rust\n{}\n```", rust);
 
@@ -1217,55 +1219,55 @@ fn render_memory_layout(
         format_to!(label, ", ");
     }
 
-    if let Some(render) = config.offset {
-        if let Some(offset) = offset(&layout) {
-            format_to!(label, "offset = ");
-            match render {
-                MemoryLayoutHoverRenderKind::Decimal => format_to!(label, "{offset}"),
-                MemoryLayoutHoverRenderKind::Hexadecimal => format_to!(label, "{offset:#X}"),
-                MemoryLayoutHoverRenderKind::Both if offset >= 10 => {
-                    format_to!(label, "{offset} ({offset:#X})")
-                }
-                MemoryLayoutHoverRenderKind::Both => {
-                    format_to!(label, "{offset}")
-                }
+    if let Some(render) = config.offset
+        && let Some(offset) = offset(&layout)
+    {
+        format_to!(label, "offset = ");
+        match render {
+            MemoryLayoutHoverRenderKind::Decimal => format_to!(label, "{offset}"),
+            MemoryLayoutHoverRenderKind::Hexadecimal => format_to!(label, "{offset:#X}"),
+            MemoryLayoutHoverRenderKind::Both if offset >= 10 => {
+                format_to!(label, "{offset} ({offset:#X})")
+            }
+            MemoryLayoutHoverRenderKind::Both => {
+                format_to!(label, "{offset}")
             }
-            format_to!(label, ", ");
         }
+        format_to!(label, ", ");
     }
 
-    if let Some(render) = config.padding {
-        if let Some((padding_name, padding)) = padding(&layout) {
-            format_to!(label, "{padding_name} = ");
-            match render {
-                MemoryLayoutHoverRenderKind::Decimal => format_to!(label, "{padding}"),
-                MemoryLayoutHoverRenderKind::Hexadecimal => format_to!(label, "{padding:#X}"),
-                MemoryLayoutHoverRenderKind::Both if padding >= 10 => {
-                    format_to!(label, "{padding} ({padding:#X})")
-                }
-                MemoryLayoutHoverRenderKind::Both => {
-                    format_to!(label, "{padding}")
-                }
+    if let Some(render) = config.padding
+        && let Some((padding_name, padding)) = padding(&layout)
+    {
+        format_to!(label, "{padding_name} = ");
+        match render {
+            MemoryLayoutHoverRenderKind::Decimal => format_to!(label, "{padding}"),
+            MemoryLayoutHoverRenderKind::Hexadecimal => format_to!(label, "{padding:#X}"),
+            MemoryLayoutHoverRenderKind::Both if padding >= 10 => {
+                format_to!(label, "{padding} ({padding:#X})")
+            }
+            MemoryLayoutHoverRenderKind::Both => {
+                format_to!(label, "{padding}")
             }
-            format_to!(label, ", ");
         }
+        format_to!(label, ", ");
     }
 
-    if config.niches {
-        if let Some(niches) = layout.niches() {
-            if niches > 1024 {
-                if niches.is_power_of_two() {
-                    format_to!(label, "niches = 2{}, ", pwr2_to_exponent(niches));
-                } else if is_pwr2plus1(niches) {
-                    format_to!(label, "niches = 2{} + 1, ", pwr2_to_exponent(niches - 1));
-                } else if is_pwr2minus1(niches) {
-                    format_to!(label, "niches = 2{} - 1, ", pwr2_to_exponent(niches + 1));
-                } else {
-                    format_to!(label, "niches = a lot, ");
-                }
+    if config.niches
+        && let Some(niches) = layout.niches()
+    {
+        if niches > 1024 {
+            if niches.is_power_of_two() {
+                format_to!(label, "niches = 2{}, ", pwr2_to_exponent(niches));
+            } else if is_pwr2plus1(niches) {
+                format_to!(label, "niches = 2{} + 1, ", pwr2_to_exponent(niches - 1));
+            } else if is_pwr2minus1(niches) {
+                format_to!(label, "niches = 2{} - 1, ", pwr2_to_exponent(niches + 1));
             } else {
-                format_to!(label, "niches = {niches}, ");
+                format_to!(label, "niches = a lot, ");
             }
+        } else {
+            format_to!(label, "niches = {niches}, ");
         }
     }
     label.pop(); // ' '
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 19e5509681a..7a8514c47af 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -576,13 +576,13 @@ impl InlayHintLabel {
     }
 
     pub fn append_part(&mut self, part: InlayHintLabelPart) {
-        if part.linked_location.is_none() && part.tooltip.is_none() {
-            if let Some(InlayHintLabelPart { text, linked_location: None, tooltip: None }) =
+        if part.linked_location.is_none()
+            && part.tooltip.is_none()
+            && let Some(InlayHintLabelPart { text, linked_location: None, tooltip: None }) =
                 self.parts.last_mut()
-            {
-                text.push_str(&part.text);
-                return;
-            }
+        {
+            text.push_str(&part.text);
+            return;
         }
         self.parts.push(part);
     }
@@ -1065,4 +1065,34 @@ fn bar() {
 "#,
         );
     }
+
+    #[test]
+    fn regression_20239() {
+        check_with_config(
+            InlayHintsConfig { parameter_hints: true, type_hints: true, ..DISABLED_CONFIG },
+            r#"
+//- minicore: fn
+trait Iterator {
+    type Item;
+    fn map<B, F: FnMut(Self::Item) -> B>(self, f: F);
+}
+trait ToString {
+    fn to_string(&self);
+}
+
+fn check_tostr_eq<L, R>(left: L, right: R)
+where
+    L: Iterator,
+    L::Item: ToString,
+    R: Iterator,
+    R::Item: ToString,
+{
+    left.map(|s| s.to_string());
+           // ^ impl ToString
+    right.map(|s| s.to_string());
+            // ^ impl ToString
+}
+        "#,
+        );
+    }
 }
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 49b43fc37f2..4d020bac3aa 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
@@ -39,10 +39,10 @@ pub(super) fn hints(
     if let ast::Expr::ParenExpr(_) = expr {
         return None;
     }
-    if let ast::Expr::BlockExpr(b) = expr {
-        if !b.is_standalone() {
-            return None;
-        }
+    if let ast::Expr::BlockExpr(b) = expr
+        && !b.is_standalone()
+    {
+        return None;
     }
 
     let descended = sema.descend_node_into_attributes(expr.clone()).pop();
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 729349365e6..922e9598aa0 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
@@ -41,13 +41,11 @@ pub(super) fn hints(
                 Some(it.colon_token())
             },
             ast::LetStmt(it) => {
-                if config.hide_closure_initialization_hints {
-                    if let Some(ast::Expr::ClosureExpr(closure)) = it.initializer() {
-                        if closure_has_block_body(&closure) {
+                if config.hide_closure_initialization_hints
+                    && let Some(ast::Expr::ClosureExpr(closure)) = it.initializer()
+                        && closure_has_block_body(&closure) {
                             return None;
                         }
-                    }
-                }
                 if it.ty().is_some() {
                     return None;
                 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
index ff157fa171b..a8bb652fda2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
@@ -51,12 +51,11 @@ pub(super) fn hints(
             if ty.is_unknown() {
                 return None;
             }
-            if matches!(expr, ast::Expr::PathExpr(_)) {
-                if let Some(hir::Adt::Struct(st)) = ty.as_adt() {
-                    if st.fields(sema.db).is_empty() {
-                        return None;
-                    }
-                }
+            if matches!(expr, ast::Expr::PathExpr(_))
+                && let Some(hir::Adt::Struct(st)) = ty.as_adt()
+                && st.fields(sema.db).is_empty()
+            {
+                return None;
             }
             let label = label_of_ty(famous_defs, config, &ty, display_target)?;
             acc.push(InlayHint {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
index 05253b67948..e80c9dc9d47 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
@@ -120,11 +120,11 @@ pub(super) fn hints(
     };
 
     if let Some(mut next) = closing_token.next_token() {
-        if next.kind() == T![;] {
-            if let Some(tok) = next.next_token() {
-                closing_token = next;
-                next = tok;
-            }
+        if next.kind() == T![;]
+            && let Some(tok) = next.next_token()
+        {
+            closing_token = next;
+            next = tok;
         }
         if !(next.kind() == SyntaxKind::WHITESPACE && next.text().contains('\n')) {
             // Only display the hint if the `}` is the last token on the line
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
index 9e600b5455b..fef1cb83c11 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
@@ -55,11 +55,9 @@ pub(super) fn hints(
 
     // Insert braces if necessary
     let insert_braces = |builder: &mut TextEditBuilder| {
-        if !has_block_body {
-            if let Some(range) = closure.body().map(|b| b.syntax().text_range()) {
-                builder.insert(range.start(), "{ ".to_owned());
-                builder.insert(range.end(), " }".to_owned());
-            }
+        if !has_block_body && let Some(range) = closure.body().map(|b| b.syntax().text_range()) {
+            builder.insert(range.start(), "{ ".to_owned());
+            builder.insert(range.end(), " }".to_owned());
         }
     };
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
index 88152bf3e38..491018a4dda 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
@@ -81,10 +81,10 @@ fn item_hint(
         text_edit: Some(config.lazy_text_edit(|| {
             let mut builder = TextEdit::builder();
             builder.insert(token.text_range().start(), "unsafe ".to_owned());
-            if extern_block.unsafe_token().is_none() {
-                if let Some(abi) = extern_block.abi() {
-                    builder.insert(abi.syntax().text_range().start(), "unsafe ".to_owned());
-                }
+            if extern_block.unsafe_token().is_none()
+                && let Some(abi) = extern_block.abi()
+            {
+                builder.insert(abi.syntax().text_range().start(), "unsafe ".to_owned());
             }
             builder.finish()
         })),
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs
index 6e1b3bdbdf0..1fddb6fbe01 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs
@@ -33,10 +33,10 @@ pub(crate) fn hints(
     let mut args = generic_arg_list.generic_args().peekable();
     let start_with_lifetime = matches!(args.peek()?, ast::GenericArg::LifetimeArg(_));
     let params = generic_def.params(sema.db).into_iter().filter(|p| {
-        if let hir::GenericParam::TypeParam(it) = p {
-            if it.is_implicit(sema.db) {
-                return false;
-            }
+        if let hir::GenericParam::TypeParam(it) = p
+            && it.is_implicit(sema.db)
+        {
+            return false;
         }
         if !start_with_lifetime {
             return !matches!(p, hir::GenericParam::LifetimeParam(_));
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
index 7212efd954e..bddce904dfd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
@@ -22,30 +22,31 @@ pub(super) fn hints(
         return None;
     }
 
-    if let Either::Right(it) = &statik_or_const {
-        if ast::AssocItemList::can_cast(
+    if let Either::Right(it) = &statik_or_const
+        && ast::AssocItemList::can_cast(
             it.syntax().parent().map_or(SyntaxKind::EOF, |it| it.kind()),
-        ) {
-            return None;
-        }
+        )
+    {
+        return None;
     }
 
-    if let Some(ast::Type::RefType(ty)) = statik_or_const.either(|it| it.ty(), |it| it.ty()) {
-        if ty.lifetime().is_none() {
-            let t = ty.amp_token()?;
-            acc.push(InlayHint {
-                range: t.text_range(),
-                kind: InlayKind::Lifetime,
-                label: "'static".into(),
-                text_edit: Some(config.lazy_text_edit(|| {
-                    TextEdit::insert(t.text_range().start(), "'static ".into())
-                })),
-                position: InlayHintPosition::After,
-                pad_left: false,
-                pad_right: true,
-                resolve_parent: None,
-            });
-        }
+    if let Some(ast::Type::RefType(ty)) = statik_or_const.either(|it| it.ty(), |it| it.ty())
+        && ty.lifetime().is_none()
+    {
+        let t = ty.amp_token()?;
+        acc.push(InlayHint {
+            range: t.text_range(),
+            kind: InlayKind::Lifetime,
+            label: "'static".into(),
+            text_edit: Some(
+                config
+                    .lazy_text_edit(|| TextEdit::insert(t.text_range().start(), "'static ".into())),
+            ),
+            position: InlayHintPosition::After,
+            pad_left: false,
+            pad_right: true,
+            resolve_parent: None,
+        });
     }
 
     Some(())
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
index 49fec0a793c..a89c53e00b3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
@@ -324,35 +324,35 @@ fn hints_(
 
     // apply hints
     // apply output if required
-    if let (Some(output_lt), Some(r)) = (&output, ret_type) {
-        if let Some(ty) = r.ty() {
-            walk_ty(&ty, &mut |ty| match ty {
-                ast::Type::RefType(ty) if ty.lifetime().is_none() => {
-                    if let Some(amp) = ty.amp_token() {
-                        is_trivial = false;
-                        acc.push(mk_lt_hint(amp, output_lt.to_string()));
-                    }
-                    false
+    if let (Some(output_lt), Some(r)) = (&output, ret_type)
+        && let Some(ty) = r.ty()
+    {
+        walk_ty(&ty, &mut |ty| match ty {
+            ast::Type::RefType(ty) if ty.lifetime().is_none() => {
+                if let Some(amp) = ty.amp_token() {
+                    is_trivial = false;
+                    acc.push(mk_lt_hint(amp, output_lt.to_string()));
                 }
-                ast::Type::FnPtrType(_) => {
+                false
+            }
+            ast::Type::FnPtrType(_) => {
+                is_trivial = false;
+                true
+            }
+            ast::Type::PathType(t) => {
+                if t.path()
+                    .and_then(|it| it.segment())
+                    .and_then(|it| it.parenthesized_arg_list())
+                    .is_some()
+                {
                     is_trivial = false;
                     true
+                } else {
+                    false
                 }
-                ast::Type::PathType(t) => {
-                    if t.path()
-                        .and_then(|it| it.segment())
-                        .and_then(|it| it.parenthesized_arg_list())
-                        .is_some()
-                    {
-                        is_trivial = false;
-                        true
-                    } else {
-                        false
-                    }
-                }
-                _ => false,
-            })
-        }
+            }
+            _ => false,
+        })
     }
 
     if config.lifetime_elision_hints == LifetimeElisionHints::SkipTrivial && is_trivial {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
index 5174228466c..ec0a4c46c7f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
@@ -135,10 +135,10 @@ fn should_hide_param_name_hint(
     }
 
     if unary_function {
-        if let Some(function_name) = function_name {
-            if is_param_name_suffix_of_fn_name(param_name, function_name) {
-                return true;
-            }
+        if let Some(function_name) = function_name
+            && is_param_name_suffix_of_fn_name(param_name, function_name)
+        {
+            return true;
         }
         if is_obvious_param(param_name) {
             return true;
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 0188c105faa..a946559c354 100644
--- a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
@@ -144,15 +144,15 @@ fn remove_newline(
         }
     }
 
-    if config.join_else_if {
-        if let (Some(prev), Some(_next)) = (as_if_expr(&prev), as_if_expr(&next)) {
-            match prev.else_token() {
-                Some(_) => cov_mark::hit!(join_two_ifs_with_existing_else),
-                None => {
-                    cov_mark::hit!(join_two_ifs);
-                    edit.replace(token.text_range(), " else ".to_owned());
-                    return;
-                }
+    if config.join_else_if
+        && let (Some(prev), Some(_next)) = (as_if_expr(&prev), as_if_expr(&next))
+    {
+        match prev.else_token() {
+            Some(_) => cov_mark::hit!(join_two_ifs_with_existing_else),
+            None => {
+                cov_mark::hit!(join_two_ifs);
+                edit.replace(token.text_range(), " else ".to_owned());
+                return;
             }
         }
     }
@@ -213,10 +213,10 @@ fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Op
     let mut buf = expr.syntax().text().to_string();
 
     // Match block needs to have a comma after the block
-    if let Some(match_arm) = block_expr.syntax().parent().and_then(ast::MatchArm::cast) {
-        if match_arm.comma_token().is_none() {
-            buf.push(',');
-        }
+    if let Some(match_arm) = block_expr.syntax().parent().and_then(ast::MatchArm::cast)
+        && match_arm.comma_token().is_none()
+    {
+        buf.push(',');
     }
 
     edit.replace(block_range, buf);
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index b3b8deb61fc..98877482ed8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -299,7 +299,7 @@ impl Analysis {
 
     /// Gets the text of the source file.
     pub fn file_text(&self, file_id: FileId) -> Cancellable<Arc<str>> {
-        self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db))
+        self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db).clone())
     }
 
     /// Gets the syntax tree of the file.
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 50219cee57d..96d829d1260 100644
--- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
@@ -29,14 +29,13 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
     let mut module = find_node_at_offset::<ast::Module>(source_file.syntax(), position.offset);
 
     // If cursor is literally on `mod foo`, go to the grandpa.
-    if let Some(m) = &module {
-        if !m
+    if let Some(m) = &module
+        && !m
             .item_list()
             .is_some_and(|it| it.syntax().text_range().contains_inclusive(position.offset))
-        {
-            cov_mark::hit!(test_resolve_parent_module_on_module_decl);
-            module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast);
-        }
+    {
+        cov_mark::hit!(test_resolve_parent_module_on_module_decl);
+        module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast);
     }
 
     match module {
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index a07c647c2cb..aea4ae0fd97 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -13,8 +13,11 @@ use ide_db::{
 };
 use itertools::Itertools;
 use std::fmt::Write;
-use stdx::{always, never};
-use syntax::{AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize, ast};
+use stdx::{always, format_to, never};
+use syntax::{
+    AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize,
+    ast::{self, HasArgList, prec::ExprPrecedence},
+};
 
 use ide_db::text_edit::TextEdit;
 
@@ -35,13 +38,8 @@ pub(crate) fn prepare_rename(
     let syntax = source_file.syntax();
 
     let res = find_definitions(&sema, syntax, position, &Name::new_symbol_root(sym::underscore))?
-        .map(|(frange, kind, def, _, _)| {
-            // ensure all ranges are valid
-
-            if def.range_for_rename(&sema).is_none() {
-                bail!("No references found at position")
-            }
-
+        .filter(|(_, _, def, _, _)| def.range_for_rename(&sema).is_some())
+        .map(|(frange, kind, _, _, _)| {
             always!(
                 frange.range.contains_inclusive(position.offset)
                     && frange.file_id == position.file_id
@@ -336,6 +334,85 @@ fn find_definitions(
     }
 }
 
+fn transform_assoc_fn_into_method_call(
+    sema: &Semantics<'_, RootDatabase>,
+    source_change: &mut SourceChange,
+    f: hir::Function,
+) {
+    let calls = Definition::Function(f).usages(sema).all();
+    for (file_id, calls) in calls {
+        for call in calls {
+            let Some(fn_name) = call.name.as_name_ref() else { continue };
+            let Some(path) = fn_name.syntax().parent().and_then(ast::PathSegment::cast) else {
+                continue;
+            };
+            let path = path.parent_path();
+            // The `PathExpr` is the direct parent, above it is the `CallExpr`.
+            let Some(call) =
+                path.syntax().parent().and_then(|it| ast::CallExpr::cast(it.parent()?))
+            else {
+                continue;
+            };
+
+            let Some(arg_list) = call.arg_list() else { continue };
+            let mut args = arg_list.args();
+            let Some(mut self_arg) = args.next() else { continue };
+            let second_arg = args.next();
+
+            // Strip (de)references, as they will be taken automatically by auto(de)ref.
+            loop {
+                let self_ = match &self_arg {
+                    ast::Expr::RefExpr(self_) => self_.expr(),
+                    ast::Expr::ParenExpr(self_) => self_.expr(),
+                    ast::Expr::PrefixExpr(self_)
+                        if self_.op_kind() == Some(ast::UnaryOp::Deref) =>
+                    {
+                        self_.expr()
+                    }
+                    _ => break,
+                };
+                self_arg = match self_ {
+                    Some(it) => it,
+                    None => break,
+                };
+            }
+
+            let self_needs_parens =
+                self_arg.precedence().needs_parentheses_in(ExprPrecedence::Postfix);
+
+            let replace_start = path.syntax().text_range().start();
+            let replace_end = match second_arg {
+                Some(second_arg) => second_arg.syntax().text_range().start(),
+                None => arg_list
+                    .r_paren_token()
+                    .map(|it| it.text_range().start())
+                    .unwrap_or_else(|| arg_list.syntax().text_range().end()),
+            };
+            let replace_range = TextRange::new(replace_start, replace_end);
+
+            let Some(macro_mapped_self) = sema.original_range_opt(self_arg.syntax()) else {
+                continue;
+            };
+            let mut replacement = String::new();
+            if self_needs_parens {
+                replacement.push('(');
+            }
+            replacement.push_str(macro_mapped_self.text(sema.db));
+            if self_needs_parens {
+                replacement.push(')');
+            }
+            replacement.push('.');
+            format_to!(replacement, "{fn_name}");
+            replacement.push('(');
+
+            source_change.insert_source_edit(
+                file_id.file_id(sema.db),
+                TextEdit::replace(replace_range, replacement),
+            );
+        }
+    }
+}
+
 fn rename_to_self(
     sema: &Semantics<'_, RootDatabase>,
     local: hir::Local,
@@ -413,6 +490,7 @@ fn rename_to_self(
         file_id.original_file(sema.db).file_id(sema.db),
         TextEdit::replace(param_source.syntax().text_range(), String::from(self_param)),
     );
+    transform_assoc_fn_into_method_call(sema, &mut source_change, fn_def);
     Ok(source_change)
 }
 
@@ -499,10 +577,10 @@ mod tests {
     ) {
         let ra_fixture_after = &trim_indent(ra_fixture_after);
         let (analysis, position) = fixture::position(ra_fixture_before);
-        if !ra_fixture_after.starts_with("error: ") {
-            if let Err(err) = analysis.prepare_rename(position).unwrap() {
-                panic!("Prepare rename to '{new_name}' was failed: {err}")
-            }
+        if !ra_fixture_after.starts_with("error: ")
+            && let Err(err) = analysis.prepare_rename(position).unwrap()
+        {
+            panic!("Prepare rename to '{new_name}' was failed: {err}")
         }
         let rename_result = analysis
             .rename(position, new_name)
@@ -3417,4 +3495,78 @@ fn other_place() { Quux::Bar$0; }
 "#,
         );
     }
+
+    #[test]
+    fn rename_to_self_callers() {
+        check(
+            "self",
+            r#"
+//- minicore: add
+struct Foo;
+impl core::ops::Add for Foo {
+    type Target = Foo;
+    fn add(self, _: Self) -> Foo { Foo }
+}
+
+impl Foo {
+    fn foo(th$0is: &Self) {}
+}
+
+fn bar(v: &Foo) {
+    Foo::foo(v);
+}
+
+fn baz() {
+    Foo::foo(&Foo);
+    Foo::foo(Foo + Foo);
+}
+        "#,
+            r#"
+struct Foo;
+impl core::ops::Add for Foo {
+    type Target = Foo;
+    fn add(self, _: Self) -> Foo { Foo }
+}
+
+impl Foo {
+    fn foo(&self) {}
+}
+
+fn bar(v: &Foo) {
+    v.foo();
+}
+
+fn baz() {
+    Foo.foo();
+    (Foo + Foo).foo();
+}
+        "#,
+        );
+        // Multiple arguments:
+        check(
+            "self",
+            r#"
+struct Foo;
+
+impl Foo {
+    fn foo(th$0is: &Self, v: i32) {}
+}
+
+fn bar(v: Foo) {
+    Foo::foo(&v, 123);
+}
+        "#,
+            r#"
+struct Foo;
+
+impl Foo {
+    fn foo(&self, v: i32) {}
+}
+
+fn bar(v: Foo) {
+    v.foo(123);
+}
+        "#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
index 9d1a5bae96f..83e5c5ab1df 100644
--- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -514,20 +514,19 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
             .flat_map(|it| it.name(db))
             .for_each(|name| format_to!(path, "{}::", name.display(db, edition)));
         // This probably belongs to canonical_path?
-        if let Some(assoc_item) = def.as_assoc_item(db) {
-            if let Some(ty) = assoc_item.implementing_ty(db) {
-                if let Some(adt) = ty.as_adt() {
-                    let name = adt.name(db);
-                    let mut ty_args = ty.generic_parameters(db, display_target).peekable();
-                    format_to!(path, "{}", name.display(db, edition));
-                    if ty_args.peek().is_some() {
-                        format_to!(path, "<{}>", ty_args.format_with(",", |ty, cb| cb(&ty)));
-                    }
-                    format_to!(path, "::{}", def_name.display(db, edition));
-                    path.retain(|c| c != ' ');
-                    return Some(path);
-                }
+        if let Some(assoc_item) = def.as_assoc_item(db)
+            && let Some(ty) = assoc_item.implementing_ty(db)
+            && let Some(adt) = ty.as_adt()
+        {
+            let name = adt.name(db);
+            let mut ty_args = ty.generic_parameters(db, display_target).peekable();
+            format_to!(path, "{}", name.display(db, edition));
+            if ty_args.peek().is_some() {
+                format_to!(path, "<{}>", ty_args.format_with(",", |ty, cb| cb(&ty)));
             }
+            format_to!(path, "::{}", def_name.display(db, edition));
+            path.retain(|c| c != ' ');
+            return Some(path);
         }
         format_to!(path, "{}", def_name.display(db, edition));
         Some(path)
@@ -697,14 +696,13 @@ impl UpdateTest {
                     continue;
                 };
                 for item in items {
-                    if let hir::ItemInNs::Macros(makro) = item {
-                        if Definition::Macro(makro)
+                    if let hir::ItemInNs::Macros(makro) = item
+                        && Definition::Macro(makro)
                             .usages(sema)
                             .in_scope(&search_scope)
                             .at_least_one()
-                        {
-                            return true;
-                        }
+                    {
+                        return true;
                     }
                 }
             }
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 e30a3ebefb9..382573b6801 100644
--- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
@@ -146,12 +146,11 @@ pub(crate) fn signature_help(
 
         // Stop at multi-line expressions, since the signature of the outer call is not very
         // helpful inside them.
-        if let Some(expr) = ast::Expr::cast(node.clone()) {
-            if !matches!(expr, ast::Expr::RecordExpr(..))
-                && expr.syntax().text().contains_char('\n')
-            {
-                break;
-            }
+        if let Some(expr) = ast::Expr::cast(node.clone())
+            && !matches!(expr, ast::Expr::RecordExpr(..))
+            && expr.syntax().text().contains_char('\n')
+        {
+            break;
         }
     }
 
@@ -366,10 +365,10 @@ fn signature_help_for_generics(
     res.signature.push('<');
     let mut buf = String::new();
     for param in params {
-        if let hir::GenericParam::TypeParam(ty) = param {
-            if ty.is_implicit(db) {
-                continue;
-            }
+        if let hir::GenericParam::TypeParam(ty) = param
+            && ty.is_implicit(db)
+        {
+            continue;
         }
 
         buf.clear();
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 efee39c13db..694ac22e199 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -133,10 +133,10 @@ fn get_definitions(
 ) -> Option<ArrayVec<Definition, 2>> {
     for token in sema.descend_into_macros_exact(token) {
         let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops);
-        if let Some(defs) = def {
-            if !defs.is_empty() {
-                return Some(defs);
-            }
+        if let Some(defs) = def
+            && !defs.is_empty()
+        {
+            return Some(defs);
         }
     }
     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 87db0cd7dc5..8bde8fd9700 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
@@ -306,12 +306,12 @@ fn highlight_name_ref(
     };
     let mut h = match name_class {
         NameRefClass::Definition(def, _) => {
-            if let Definition::Local(local) = &def {
-                if let Some(bindings_shadow_count) = bindings_shadow_count {
-                    let name = local.name(sema.db);
-                    let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
-                    *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
-                }
+            if let Definition::Local(local) = &def
+                && let Some(bindings_shadow_count) = bindings_shadow_count
+            {
+                let name = local.name(sema.db);
+                let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
+                *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
             };
 
             let mut h = highlight_def(sema, krate, def, edition, true);
@@ -437,21 +437,21 @@ fn highlight_name(
     edition: Edition,
 ) -> Highlight {
     let name_kind = NameClass::classify(sema, &name);
-    if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind {
-        if let Some(bindings_shadow_count) = bindings_shadow_count {
-            let name = local.name(sema.db);
-            let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
-            *shadow_count += 1;
-            *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
-        }
+    if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind
+        && let Some(bindings_shadow_count) = bindings_shadow_count
+    {
+        let name = local.name(sema.db);
+        let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
+        *shadow_count += 1;
+        *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
     };
     match name_kind {
         Some(NameClass::Definition(def)) => {
             let mut h = highlight_def(sema, krate, def, edition, false) | HlMod::Definition;
-            if let Definition::Trait(trait_) = &def {
-                if trait_.is_unsafe(sema.db) {
-                    h |= HlMod::Unsafe;
-                }
+            if let Definition::Trait(trait_) = &def
+                && trait_.is_unsafe(sema.db)
+            {
+                h |= HlMod::Unsafe;
             }
             h
         }
@@ -743,10 +743,9 @@ fn highlight_method_call(
             hir::Access::Owned => {
                 if let Some(receiver_ty) =
                     method_call.receiver().and_then(|it| sema.type_of_expr(&it))
+                    && !receiver_ty.adjusted().is_copy(sema.db)
                 {
-                    if !receiver_ty.adjusted().is_copy(sema.db) {
-                        h |= HlMod::Consuming
-                    }
+                    h |= HlMod::Consuming
                 }
             }
         }
diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
index 26ee698af08..ad838a6550e 100644
--- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
@@ -475,10 +475,10 @@ fn load_crate_graph_into_db(
     }
     let changes = vfs.take_changes();
     for (_, file) in changes {
-        if let vfs::Change::Create(v, _) | vfs::Change::Modify(v, _) = file.change {
-            if let Ok(text) = String::from_utf8(v) {
-                analysis_change.change_file(file.file_id, Some(text))
-            }
+        if let vfs::Change::Create(v, _) | vfs::Change::Modify(v, _) = file.change
+            && let Ok(text) = String::from_utf8(v)
+        {
+            analysis_change.change_file(file.file_id, Some(text))
         }
     }
     let source_roots = source_root_config.partition(vfs);
@@ -533,7 +533,7 @@ impl ProcMacroExpander for Expander {
             current_dir,
         ) {
             Ok(Ok(subtree)) => Ok(subtree),
-            Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err.0)),
+            Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err)),
             Err(err) => Err(ProcMacroExpansionError::System(err.to_string())),
         }
     }
diff --git a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs
index 04ac85ad43d..b185556b5c7 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs
@@ -185,24 +185,22 @@ fn invocation_fixtures(
                     for it in tokens.iter() {
                         collect_from_op(it, builder, seed);
                     }
-                    if i + 1 != cnt {
-                        if let Some(sep) = separator {
-                            match &**sep {
-                                Separator::Literal(it) => {
-                                    builder.push(tt::Leaf::Literal(it.clone()))
+                    if i + 1 != cnt
+                        && let Some(sep) = separator
+                    {
+                        match &**sep {
+                            Separator::Literal(it) => builder.push(tt::Leaf::Literal(it.clone())),
+                            Separator::Ident(it) => builder.push(tt::Leaf::Ident(it.clone())),
+                            Separator::Puncts(puncts) => {
+                                for it in puncts {
+                                    builder.push(tt::Leaf::Punct(*it))
                                 }
-                                Separator::Ident(it) => builder.push(tt::Leaf::Ident(it.clone())),
-                                Separator::Puncts(puncts) => {
-                                    for it in puncts {
-                                        builder.push(tt::Leaf::Punct(*it))
-                                    }
-                                }
-                                Separator::Lifetime(punct, ident) => {
-                                    builder.push(tt::Leaf::Punct(*punct));
-                                    builder.push(tt::Leaf::Ident(ident.clone()));
-                                }
-                            };
-                        }
+                            }
+                            Separator::Lifetime(punct, ident) => {
+                                builder.push(tt::Leaf::Punct(*punct));
+                                builder.push(tt::Leaf::Ident(ident.clone()));
+                            }
+                        };
                     }
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs
index a8d5965d480..189efcd15c2 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs
@@ -475,12 +475,12 @@ fn match_loop_inner<'t>(
                 })
             }
             OpDelimited::Op(Op::Subtree { tokens, delimiter }) => {
-                if let Ok((subtree, _)) = src.clone().expect_subtree() {
-                    if subtree.delimiter.kind == delimiter.kind {
-                        item.stack.push(item.dot);
-                        item.dot = tokens.iter_delimited_with(*delimiter);
-                        cur_items.push(item);
-                    }
+                if let Ok((subtree, _)) = src.clone().expect_subtree()
+                    && subtree.delimiter.kind == delimiter.kind
+                {
+                    item.stack.push(item.dot);
+                    item.dot = tokens.iter_delimited_with(*delimiter);
+                    cur_items.push(item);
                 }
             }
             OpDelimited::Op(Op::Var { kind, name, .. }) => {
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 2b4151e3b75..41fd72d8d5a 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
@@ -77,38 +77,38 @@ pub(super) fn stmt(p: &mut Parser<'_>, semicolon: Semicolon) {
         return;
     }
 
-    if let Some((cm, blocklike)) = expr_stmt(p, Some(m)) {
-        if !(p.at(T!['}']) || (semicolon != Semicolon::Required && p.at(EOF))) {
-            // test no_semi_after_block
-            // fn foo() {
-            //     if true {}
-            //     loop {}
-            //     match () {}
-            //     while true {}
-            //     for _ in () {}
-            //     {}
-            //     {}
-            //     macro_rules! test {
-            //          () => {}
-            //     }
-            //     test!{}
-            // }
-            let m = cm.precede(p);
-            match semicolon {
-                Semicolon::Required => {
-                    if blocklike.is_block() {
-                        p.eat(T![;]);
-                    } else {
-                        p.expect(T![;]);
-                    }
-                }
-                Semicolon::Optional => {
+    if let Some((cm, blocklike)) = expr_stmt(p, Some(m))
+        && !(p.at(T!['}']) || (semicolon != Semicolon::Required && p.at(EOF)))
+    {
+        // test no_semi_after_block
+        // fn foo() {
+        //     if true {}
+        //     loop {}
+        //     match () {}
+        //     while true {}
+        //     for _ in () {}
+        //     {}
+        //     {}
+        //     macro_rules! test {
+        //          () => {}
+        //     }
+        //     test!{}
+        // }
+        let m = cm.precede(p);
+        match semicolon {
+            Semicolon::Required => {
+                if blocklike.is_block() {
                     p.eat(T![;]);
+                } else {
+                    p.expect(T![;]);
                 }
-                Semicolon::Forbidden => (),
             }
-            m.complete(p, EXPR_STMT);
+            Semicolon::Optional => {
+                p.eat(T![;]);
+            }
+            Semicolon::Forbidden => (),
         }
+        m.complete(p, EXPR_STMT);
     }
 }
 
@@ -134,14 +134,11 @@ pub(super) fn let_stmt(p: &mut Parser<'_>, with_semi: Semicolon) {
     if p.at(T![else]) {
         // test_err let_else_right_curly_brace
         // fn func() { let Some(_) = {Some(1)} else { panic!("h") };}
-        if let Some(expr) = expr_after_eq {
-            if let Some(token) = expr.last_token(p) {
-                if token == T!['}'] {
-                    p.error(
-                        "right curly brace `}` before `else` in a `let...else` statement not allowed"
-                    )
-                }
-            }
+        if let Some(expr) = expr_after_eq
+            && let Some(token) = expr.last_token(p)
+            && token == T!['}']
+        {
+            p.error("right curly brace `}` before `else` in a `let...else` statement not allowed")
         }
 
         // test let_else
diff --git a/src/tools/rust-analyzer/crates/parser/src/input.rs b/src/tools/rust-analyzer/crates/parser/src/input.rs
index 4490956f970..331bc58dd05 100644
--- a/src/tools/rust-analyzer/crates/parser/src/input.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/input.rs
@@ -61,7 +61,7 @@ impl Input {
     #[inline]
     fn push_impl(&mut self, kind: SyntaxKind, contextual_kind: SyntaxKind) {
         let idx = self.len();
-        if idx % (bits::BITS as usize) == 0 {
+        if idx.is_multiple_of(bits::BITS as usize) {
             self.joint.push(0);
         }
         self.kind.push(kind);
diff --git a/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs b/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
index e2baec890c3..d5e513933f7 100644
--- a/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
@@ -252,10 +252,10 @@ fn n_attached_trivias<'a>(
                     WHITESPACE if text.contains("\n\n") => {
                         // we check whether the next token is a doc-comment
                         // and skip the whitespace in this case
-                        if let Some((COMMENT, peek_text)) = trivias.peek().map(|(_, pair)| pair) {
-                            if is_outer(peek_text) {
-                                continue;
-                            }
+                        if let Some((COMMENT, peek_text)) = trivias.peek().map(|(_, pair)| pair)
+                            && is_outer(peek_text)
+                        {
+                            continue;
                         }
                         break;
                     }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs
new file mode 100644
index 00000000000..ee96b899fe5
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs
@@ -0,0 +1,172 @@
+//! The initial proc-macro-srv protocol, soon to be deprecated.
+
+pub mod json;
+pub mod msg;
+
+use std::{
+    io::{BufRead, Write},
+    sync::Arc,
+};
+
+use paths::AbsPath;
+use span::Span;
+
+use crate::{
+    ProcMacro, ProcMacroKind, ServerError,
+    legacy_protocol::{
+        json::{read_json, write_json},
+        msg::{
+            ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, Message, Request, Response,
+            ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map,
+            flat::serialize_span_data_index_map,
+        },
+    },
+    process::ProcMacroServerProcess,
+    version,
+};
+
+pub(crate) use crate::legacy_protocol::msg::SpanMode;
+
+/// Legacy span type, only defined here as it is still used by the proc-macro server.
+/// While rust-analyzer doesn't use this anymore at all, RustRover relies on the legacy type for
+/// proc-macro expansion.
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub struct SpanId(pub u32);
+
+impl std::fmt::Debug for SpanId {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result<u32, ServerError> {
+    let request = Request::ApiVersionCheck {};
+    let response = send_task(srv, request)?;
+
+    match response {
+        Response::ApiVersionCheck(version) => Ok(version),
+        _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
+    }
+}
+
+/// Enable support for rust-analyzer span mode if the server supports it.
+pub(crate) fn enable_rust_analyzer_spans(
+    srv: &ProcMacroServerProcess,
+) -> Result<SpanMode, ServerError> {
+    let request = Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer });
+    let response = send_task(srv, request)?;
+
+    match response {
+        Response::SetConfig(ServerConfig { span_mode }) => Ok(span_mode),
+        _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
+    }
+}
+
+/// Finds proc-macros in a given dynamic library.
+pub(crate) fn find_proc_macros(
+    srv: &ProcMacroServerProcess,
+    dylib_path: &AbsPath,
+) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> {
+    let request = Request::ListMacros { dylib_path: dylib_path.to_path_buf().into() };
+
+    let response = send_task(srv, request)?;
+
+    match response {
+        Response::ListMacros(it) => Ok(it),
+        _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
+    }
+}
+
+pub(crate) fn expand(
+    proc_macro: &ProcMacro,
+    subtree: tt::SubtreeView<'_, Span>,
+    attr: Option<tt::SubtreeView<'_, Span>>,
+    env: Vec<(String, String)>,
+    def_site: Span,
+    call_site: Span,
+    mixed_site: Span,
+    current_dir: String,
+) -> Result<Result<tt::TopSubtree<span::SpanData<span::SyntaxContext>>, String>, crate::ServerError>
+{
+    let version = proc_macro.process.version();
+    let mut span_data_table = SpanDataIndexMap::default();
+    let def_site = span_data_table.insert_full(def_site).0;
+    let call_site = span_data_table.insert_full(call_site).0;
+    let mixed_site = span_data_table.insert_full(mixed_site).0;
+    let task = ExpandMacro {
+        data: ExpandMacroData {
+            macro_body: FlatTree::new(subtree, version, &mut span_data_table),
+            macro_name: proc_macro.name.to_string(),
+            attributes: attr.map(|subtree| FlatTree::new(subtree, version, &mut span_data_table)),
+            has_global_spans: ExpnGlobals {
+                serialize: version >= version::HAS_GLOBAL_SPANS,
+                def_site,
+                call_site,
+                mixed_site,
+            },
+            span_data_table: if proc_macro.process.rust_analyzer_spans() {
+                serialize_span_data_index_map(&span_data_table)
+            } else {
+                Vec::new()
+            },
+        },
+        lib: proc_macro.dylib_path.to_path_buf().into(),
+        env,
+        current_dir: Some(current_dir),
+    };
+
+    let response = send_task(&proc_macro.process, Request::ExpandMacro(Box::new(task)))?;
+
+    match response {
+        Response::ExpandMacro(it) => Ok(it
+            .map(|tree| {
+                let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table);
+                if proc_macro.needs_fixup_change() {
+                    proc_macro.change_fixup_to_match_old_server(&mut expanded);
+                }
+                expanded
+            })
+            .map_err(|msg| msg.0)),
+        Response::ExpandMacroExtended(it) => Ok(it
+            .map(|resp| {
+                let mut expanded = FlatTree::to_subtree_resolved(
+                    resp.tree,
+                    version,
+                    &deserialize_span_data_index_map(&resp.span_data_table),
+                );
+                if proc_macro.needs_fixup_change() {
+                    proc_macro.change_fixup_to_match_old_server(&mut expanded);
+                }
+                expanded
+            })
+            .map_err(|msg| msg.0)),
+        _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
+    }
+}
+
+/// Sends a request to the proc-macro server and waits for a response.
+fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result<Response, ServerError> {
+    if let Some(server_error) = srv.exited() {
+        return Err(server_error.clone());
+    }
+
+    srv.send_task(send_request, req)
+}
+
+/// Sends a request to the server and reads the response.
+fn send_request(
+    mut writer: &mut dyn Write,
+    mut reader: &mut dyn BufRead,
+    req: Request,
+    buf: &mut String,
+) -> Result<Option<Response>, ServerError> {
+    req.write(write_json, &mut writer).map_err(|err| ServerError {
+        message: "failed to write request".into(),
+        io: Some(Arc::new(err)),
+    })?;
+    let res = Response::read(read_json, &mut reader, buf).map_err(|err| ServerError {
+        message: "failed to read response".into(),
+        io: Some(Arc::new(err)),
+    })?;
+    Ok(res)
+}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs
index 165936269d3..b795c455895 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs
@@ -1,5 +1,6 @@
 //! Defines messages for cross-process message passing based on `ndjson` wire protocol
 pub(crate) mod flat;
+pub use self::flat::*;
 
 use std::io::{self, BufRead, Write};
 
@@ -9,24 +10,6 @@ use serde_derive::{Deserialize, Serialize};
 
 use crate::ProcMacroKind;
 
-pub use self::flat::{
-    FlatTree, SpanDataIndexMap, deserialize_span_data_index_map, serialize_span_data_index_map,
-};
-pub use span::TokenId;
-
-// The versions of the server protocol
-pub const NO_VERSION_CHECK_VERSION: u32 = 0;
-pub const VERSION_CHECK_VERSION: u32 = 1;
-pub const ENCODE_CLOSE_SPAN_VERSION: u32 = 2;
-pub const HAS_GLOBAL_SPANS: u32 = 3;
-pub const RUST_ANALYZER_SPAN_SUPPORT: u32 = 4;
-/// Whether literals encode their kind as an additional u32 field and idents their rawness as a u32 field.
-pub const EXTENDED_LEAF_DATA: u32 = 5;
-pub const HASHED_AST_ID: u32 = 6;
-
-/// Current API version of the proc-macro protocol.
-pub const CURRENT_API_VERSION: u32 = HASHED_AST_ID;
-
 /// Represents requests sent from the client to the proc-macro-srv.
 #[derive(Debug, Serialize, Deserialize)]
 pub enum Request {
@@ -48,7 +31,7 @@ pub enum Request {
 }
 
 /// Defines the mode used for handling span data.
-#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)]
+#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq)]
 pub enum SpanMode {
     /// Default mode, where spans are identified by an ID.
     #[default]
@@ -210,6 +193,8 @@ mod tests {
         TopSubtreeBuilder,
     };
 
+    use crate::version;
+
     use super::*;
 
     fn fixture_token_tree() -> TopSubtree<Span> {
@@ -308,7 +293,7 @@ mod tests {
     #[test]
     fn test_proc_macro_rpc_works() {
         let tt = fixture_token_tree();
-        for v in RUST_ANALYZER_SPAN_SUPPORT..=CURRENT_API_VERSION {
+        for v in version::RUST_ANALYZER_SPAN_SUPPORT..=version::CURRENT_API_VERSION {
             let mut span_data_table = Default::default();
             let task = ExpandMacro {
                 data: ExpandMacroData {
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs
index 597ffa05d20..fb3542d24f4 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs
@@ -40,9 +40,12 @@ use std::collections::VecDeque;
 use intern::Symbol;
 use rustc_hash::FxHashMap;
 use serde_derive::{Deserialize, Serialize};
-use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContext, TextRange, TokenId};
+use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContext, TextRange};
 
-use crate::legacy_protocol::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA};
+use crate::{
+    legacy_protocol::SpanId,
+    version::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA},
+};
 
 pub type SpanDataIndexMap =
     indexmap::IndexSet<Span, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
@@ -62,7 +65,7 @@ pub fn serialize_span_data_index_map(map: &SpanDataIndexMap) -> Vec<u32> {
 }
 
 pub fn deserialize_span_data_index_map(map: &[u32]) -> SpanDataIndexMap {
-    debug_assert!(map.len() % 5 == 0);
+    debug_assert!(map.len().is_multiple_of(5));
     map.chunks_exact(5)
         .map(|span| {
             let &[file_id, ast_id, start, end, e] = span else { unreachable!() };
@@ -91,27 +94,27 @@ pub struct FlatTree {
 }
 
 struct SubtreeRepr {
-    open: TokenId,
-    close: TokenId,
+    open: SpanId,
+    close: SpanId,
     kind: tt::DelimiterKind,
     tt: [u32; 2],
 }
 
 struct LiteralRepr {
-    id: TokenId,
+    id: SpanId,
     text: u32,
     suffix: u32,
     kind: u16,
 }
 
 struct PunctRepr {
-    id: TokenId,
+    id: SpanId,
     char: char,
     spacing: tt::Spacing,
 }
 
 struct IdentRepr {
-    id: TokenId,
+    id: SpanId,
     text: u32,
     is_raw: bool,
 }
@@ -122,7 +125,7 @@ impl FlatTree {
         version: u32,
         span_data_table: &mut SpanDataIndexMap,
     ) -> FlatTree {
-        let mut w = Writer {
+        let mut w = Writer::<Span> {
             string_table: FxHashMap::default(),
             work: VecDeque::new(),
             span_data_table,
@@ -159,8 +162,11 @@ impl FlatTree {
         }
     }
 
-    pub fn new_raw(subtree: tt::SubtreeView<'_, TokenId>, version: u32) -> FlatTree {
-        let mut w = Writer {
+    pub fn new_raw<T: SpanTransformer<Table = ()>>(
+        subtree: tt::SubtreeView<'_, T::Span>,
+        version: u32,
+    ) -> FlatTree {
+        let mut w = Writer::<T> {
             string_table: FxHashMap::default(),
             work: VecDeque::new(),
             span_data_table: &mut (),
@@ -202,7 +208,7 @@ impl FlatTree {
         version: u32,
         span_data_table: &SpanDataIndexMap,
     ) -> tt::TopSubtree<Span> {
-        Reader {
+        Reader::<Span> {
             subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
                 read_vec(self.subtree, SubtreeRepr::read_with_close_span)
             } else {
@@ -227,8 +233,11 @@ impl FlatTree {
         .read()
     }
 
-    pub fn to_subtree_unresolved(self, version: u32) -> tt::TopSubtree<TokenId> {
-        Reader {
+    pub fn to_subtree_unresolved<T: SpanTransformer<Table = ()>>(
+        self,
+        version: u32,
+    ) -> tt::TopSubtree<T::Span> {
+        Reader::<T> {
             subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
                 read_vec(self.subtree, SubtreeRepr::read_with_close_span)
             } else {
@@ -283,7 +292,7 @@ impl SubtreeRepr {
             3 => tt::DelimiterKind::Bracket,
             other => panic!("bad kind {other}"),
         };
-        SubtreeRepr { open: TokenId(open), close: TokenId(!0), kind, tt: [lo, len] }
+        SubtreeRepr { open: SpanId(open), close: SpanId(!0), kind, tt: [lo, len] }
     }
     fn write_with_close_span(self) -> [u32; 5] {
         let kind = match self.kind {
@@ -302,7 +311,7 @@ impl SubtreeRepr {
             3 => tt::DelimiterKind::Bracket,
             other => panic!("bad kind {other}"),
         };
-        SubtreeRepr { open: TokenId(open), close: TokenId(close), kind, tt: [lo, len] }
+        SubtreeRepr { open: SpanId(open), close: SpanId(close), kind, tt: [lo, len] }
     }
 }
 
@@ -311,13 +320,13 @@ impl LiteralRepr {
         [self.id.0, self.text]
     }
     fn read([id, text]: [u32; 2]) -> LiteralRepr {
-        LiteralRepr { id: TokenId(id), text, kind: 0, suffix: !0 }
+        LiteralRepr { id: SpanId(id), text, kind: 0, suffix: !0 }
     }
     fn write_with_kind(self) -> [u32; 4] {
         [self.id.0, self.text, self.kind as u32, self.suffix]
     }
     fn read_with_kind([id, text, kind, suffix]: [u32; 4]) -> LiteralRepr {
-        LiteralRepr { id: TokenId(id), text, kind: kind as u16, suffix }
+        LiteralRepr { id: SpanId(id), text, kind: kind as u16, suffix }
     }
 }
 
@@ -335,7 +344,7 @@ impl PunctRepr {
             1 => tt::Spacing::Joint,
             other => panic!("bad spacing {other}"),
         };
-        PunctRepr { id: TokenId(id), char: char.try_into().unwrap(), spacing }
+        PunctRepr { id: SpanId(id), char: char.try_into().unwrap(), spacing }
     }
 }
 
@@ -344,44 +353,46 @@ impl IdentRepr {
         [self.id.0, self.text]
     }
     fn read(data: [u32; 2]) -> IdentRepr {
-        IdentRepr { id: TokenId(data[0]), text: data[1], is_raw: false }
+        IdentRepr { id: SpanId(data[0]), text: data[1], is_raw: false }
     }
     fn write_with_rawness(self) -> [u32; 3] {
         [self.id.0, self.text, self.is_raw as u32]
     }
     fn read_with_rawness([id, text, is_raw]: [u32; 3]) -> IdentRepr {
-        IdentRepr { id: TokenId(id), text, is_raw: is_raw == 1 }
+        IdentRepr { id: SpanId(id), text, is_raw: is_raw == 1 }
     }
 }
 
-trait InternableSpan: Copy {
+pub trait SpanTransformer {
     type Table;
-    fn token_id_of(table: &mut Self::Table, s: Self) -> TokenId;
-    fn span_for_token_id(table: &Self::Table, id: TokenId) -> Self;
+    type Span: Copy;
+    fn token_id_of(table: &mut Self::Table, s: Self::Span) -> SpanId;
+    fn span_for_token_id(table: &Self::Table, id: SpanId) -> Self::Span;
 }
-
-impl InternableSpan for TokenId {
+impl SpanTransformer for SpanId {
     type Table = ();
-    fn token_id_of((): &mut Self::Table, token_id: Self) -> TokenId {
+    type Span = Self;
+    fn token_id_of((): &mut Self::Table, token_id: Self::Span) -> SpanId {
         token_id
     }
 
-    fn span_for_token_id((): &Self::Table, id: TokenId) -> Self {
+    fn span_for_token_id((): &Self::Table, id: SpanId) -> Self::Span {
         id
     }
 }
-impl InternableSpan for Span {
+impl SpanTransformer for Span {
     type Table = SpanDataIndexMap;
-    fn token_id_of(table: &mut Self::Table, span: Self) -> TokenId {
-        TokenId(table.insert_full(span).0 as u32)
+    type Span = Self;
+    fn token_id_of(table: &mut Self::Table, span: Self::Span) -> SpanId {
+        SpanId(table.insert_full(span).0 as u32)
     }
-    fn span_for_token_id(table: &Self::Table, id: TokenId) -> Self {
+    fn span_for_token_id(table: &Self::Table, id: SpanId) -> Self::Span {
         *table.get_index(id.0 as usize).unwrap_or_else(|| &table[0])
     }
 }
 
-struct Writer<'a, 'span, S: InternableSpan> {
-    work: VecDeque<(usize, tt::iter::TtIter<'a, S>)>,
+struct Writer<'a, 'span, S: SpanTransformer> {
+    work: VecDeque<(usize, tt::iter::TtIter<'a, S::Span>)>,
     string_table: FxHashMap<std::borrow::Cow<'a, str>, u32>,
     span_data_table: &'span mut S::Table,
     version: u32,
@@ -394,8 +405,8 @@ struct Writer<'a, 'span, S: InternableSpan> {
     text: Vec<String>,
 }
 
-impl<'a, S: InternableSpan> Writer<'a, '_, S> {
-    fn write(&mut self, root: tt::SubtreeView<'a, S>) {
+impl<'a, T: SpanTransformer> Writer<'a, '_, T> {
+    fn write(&mut self, root: tt::SubtreeView<'a, T::Span>) {
         let subtree = root.top_subtree();
         self.enqueue(subtree, root.iter());
         while let Some((idx, subtree)) = self.work.pop_front() {
@@ -403,11 +414,11 @@ impl<'a, S: InternableSpan> Writer<'a, '_, S> {
         }
     }
 
-    fn token_id_of(&mut self, span: S) -> TokenId {
-        S::token_id_of(self.span_data_table, span)
+    fn token_id_of(&mut self, span: T::Span) -> SpanId {
+        T::token_id_of(self.span_data_table, span)
     }
 
-    fn subtree(&mut self, idx: usize, subtree: tt::iter::TtIter<'a, S>) {
+    fn subtree(&mut self, idx: usize, subtree: tt::iter::TtIter<'a, T::Span>) {
         let mut first_tt = self.token_tree.len();
         let n_tt = subtree.clone().count(); // FIXME: `count()` walks over the entire iterator.
         self.token_tree.resize(first_tt + n_tt, !0);
@@ -478,7 +489,11 @@ impl<'a, S: InternableSpan> Writer<'a, '_, S> {
         }
     }
 
-    fn enqueue(&mut self, subtree: &'a tt::Subtree<S>, contents: tt::iter::TtIter<'a, S>) -> u32 {
+    fn enqueue(
+        &mut self,
+        subtree: &'a tt::Subtree<T::Span>,
+        contents: tt::iter::TtIter<'a, T::Span>,
+    ) -> u32 {
         let idx = self.subtree.len();
         let open = self.token_id_of(subtree.delimiter.open);
         let close = self.token_id_of(subtree.delimiter.close);
@@ -507,7 +522,7 @@ impl<'a, S: InternableSpan> Writer<'a, '_, S> {
     }
 }
 
-struct Reader<'span, S: InternableSpan> {
+struct Reader<'span, S: SpanTransformer> {
     version: u32,
     subtree: Vec<SubtreeRepr>,
     literal: Vec<LiteralRepr>,
@@ -518,11 +533,11 @@ struct Reader<'span, S: InternableSpan> {
     span_data_table: &'span S::Table,
 }
 
-impl<S: InternableSpan> Reader<'_, S> {
-    pub(crate) fn read(self) -> tt::TopSubtree<S> {
-        let mut res: Vec<Option<(tt::Delimiter<S>, Vec<tt::TokenTree<S>>)>> =
+impl<T: SpanTransformer> Reader<'_, T> {
+    pub(crate) fn read(self) -> tt::TopSubtree<T::Span> {
+        let mut res: Vec<Option<(tt::Delimiter<T::Span>, Vec<tt::TokenTree<T::Span>>)>> =
             vec![None; self.subtree.len()];
-        let read_span = |id| S::span_for_token_id(self.span_data_table, id);
+        let read_span = |id| T::span_for_token_id(self.span_data_table, id);
         for i in (0..self.subtree.len()).rev() {
             let repr = &self.subtree[i];
             let token_trees = &self.token_tree[repr.tt[0] as usize..repr.tt[1] as usize];
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
index 516c7418bde..97919b85b51 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
@@ -5,24 +5,29 @@
 //! is used to provide basic infrastructure for communication between two
 //! processes: Client (RA itself), Server (the external program)
 
-pub mod legacy_protocol {
-    pub mod json;
-    pub mod msg;
-}
+pub mod legacy_protocol;
 mod process;
 
 use paths::{AbsPath, AbsPathBuf};
 use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
 use std::{fmt, io, sync::Arc, time::SystemTime};
 
-use crate::{
-    legacy_protocol::msg::{
-        ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, HAS_GLOBAL_SPANS, HASHED_AST_ID,
-        PanicMessage, RUST_ANALYZER_SPAN_SUPPORT, Request, Response, SpanDataIndexMap,
-        deserialize_span_data_index_map, flat::serialize_span_data_index_map,
-    },
-    process::ProcMacroServerProcess,
-};
+use crate::process::ProcMacroServerProcess;
+
+/// The versions of the server protocol
+pub mod version {
+    pub const NO_VERSION_CHECK_VERSION: u32 = 0;
+    pub const VERSION_CHECK_VERSION: u32 = 1;
+    pub const ENCODE_CLOSE_SPAN_VERSION: u32 = 2;
+    pub const HAS_GLOBAL_SPANS: u32 = 3;
+    pub const RUST_ANALYZER_SPAN_SUPPORT: u32 = 4;
+    /// Whether literals encode their kind as an additional u32 field and idents their rawness as a u32 field.
+    pub const EXTENDED_LEAF_DATA: u32 = 5;
+    pub const HASHED_AST_ID: u32 = 6;
+
+    /// Current API version of the proc-macro protocol.
+    pub const CURRENT_API_VERSION: u32 = HASHED_AST_ID;
+}
 
 /// Represents different kinds of procedural macros that can be expanded by the external server.
 #[derive(Copy, Clone, Eq, PartialEq, Debug, serde_derive::Serialize, serde_derive::Deserialize)]
@@ -163,7 +168,7 @@ impl ProcMacro {
 
     fn needs_fixup_change(&self) -> bool {
         let version = self.process.version();
-        (RUST_ANALYZER_SPAN_SUPPORT..HASHED_AST_ID).contains(&version)
+        (version::RUST_ANALYZER_SPAN_SUPPORT..version::HASHED_AST_ID).contains(&version)
     }
 
     /// On some server versions, the fixup ast id is different than ours. So change it to match.
@@ -204,7 +209,7 @@ impl ProcMacro {
         call_site: Span,
         mixed_site: Span,
         current_dir: String,
-    ) -> Result<Result<tt::TopSubtree<Span>, PanicMessage>, ServerError> {
+    ) -> Result<Result<tt::TopSubtree<Span>, String>, ServerError> {
         let (mut subtree, mut attr) = (subtree, attr);
         let (mut subtree_changed, mut attr_changed);
         if self.needs_fixup_change() {
@@ -219,57 +224,15 @@ impl ProcMacro {
             }
         }
 
-        let version = self.process.version();
-
-        let mut span_data_table = SpanDataIndexMap::default();
-        let def_site = span_data_table.insert_full(def_site).0;
-        let call_site = span_data_table.insert_full(call_site).0;
-        let mixed_site = span_data_table.insert_full(mixed_site).0;
-        let task = ExpandMacro {
-            data: ExpandMacroData {
-                macro_body: FlatTree::new(subtree, version, &mut span_data_table),
-                macro_name: self.name.to_string(),
-                attributes: attr
-                    .map(|subtree| FlatTree::new(subtree, version, &mut span_data_table)),
-                has_global_spans: ExpnGlobals {
-                    serialize: version >= HAS_GLOBAL_SPANS,
-                    def_site,
-                    call_site,
-                    mixed_site,
-                },
-                span_data_table: if version >= RUST_ANALYZER_SPAN_SUPPORT {
-                    serialize_span_data_index_map(&span_data_table)
-                } else {
-                    Vec::new()
-                },
-            },
-            lib: self.dylib_path.to_path_buf().into(),
+        legacy_protocol::expand(
+            self,
+            subtree,
+            attr,
             env,
-            current_dir: Some(current_dir),
-        };
-
-        let response = self.process.send_task(Request::ExpandMacro(Box::new(task)))?;
-
-        match response {
-            Response::ExpandMacro(it) => Ok(it.map(|tree| {
-                let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table);
-                if self.needs_fixup_change() {
-                    self.change_fixup_to_match_old_server(&mut expanded);
-                }
-                expanded
-            })),
-            Response::ExpandMacroExtended(it) => Ok(it.map(|resp| {
-                let mut expanded = FlatTree::to_subtree_resolved(
-                    resp.tree,
-                    version,
-                    &deserialize_span_data_index_map(&resp.span_data_table),
-                );
-                if self.needs_fixup_change() {
-                    self.change_fixup_to_match_old_server(&mut expanded);
-                }
-                expanded
-            })),
-            _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
-        }
+            def_site,
+            call_site,
+            mixed_site,
+            current_dir,
+        )
     }
 }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
index fcea75ef672..fe274a027a8 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
@@ -12,13 +12,8 @@ use stdx::JodChild;
 
 use crate::{
     ProcMacroKind, ServerError,
-    legacy_protocol::{
-        json::{read_json, write_json},
-        msg::{
-            CURRENT_API_VERSION, Message, RUST_ANALYZER_SPAN_SUPPORT, Request, Response,
-            ServerConfig, SpanMode,
-        },
-    },
+    legacy_protocol::{self, SpanMode},
+    version,
 };
 
 /// Represents a process handling proc-macro communication.
@@ -28,11 +23,16 @@ pub(crate) struct ProcMacroServerProcess {
     /// hence the lock on the state.
     state: Mutex<ProcessSrvState>,
     version: u32,
-    mode: SpanMode,
+    protocol: Protocol,
     /// Populated when the server exits.
     exited: OnceLock<AssertUnwindSafe<ServerError>>,
 }
 
+#[derive(Debug)]
+enum Protocol {
+    LegacyJson { mode: SpanMode },
+}
+
 /// Maintains the state of the proc-macro server process.
 #[derive(Debug)]
 struct ProcessSrvState {
@@ -56,34 +56,40 @@ impl ProcMacroServerProcess {
             io::Result::Ok(ProcMacroServerProcess {
                 state: Mutex::new(ProcessSrvState { process, stdin, stdout }),
                 version: 0,
-                mode: SpanMode::Id,
+                protocol: Protocol::LegacyJson { mode: SpanMode::Id },
                 exited: OnceLock::new(),
             })
         };
         let mut srv = create_srv()?;
         tracing::info!("sending proc-macro server version check");
         match srv.version_check() {
-            Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::other(
-                format!( "The version of the proc-macro server ({v}) in your Rust toolchain is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}).
-            This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain."
-                ),
-            )),
+            Ok(v) if v > version::CURRENT_API_VERSION => {
+                #[allow(clippy::disallowed_methods)]
+                let process_version = Command::new(process_path)
+                    .arg("--version")
+                    .output()
+                    .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())
+                    .unwrap_or_else(|_| "unknown version".to_owned());
+                Err(io::Error::other(format!(
+                    "Your installed proc-macro server is too new for your rust-analyzer. API version: {}, server version: {process_version}. \
+                        This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain.",
+                    version::CURRENT_API_VERSION
+                )))
+            }
             Ok(v) => {
                 tracing::info!("Proc-macro server version: {v}");
                 srv.version = v;
-                if srv.version >= RUST_ANALYZER_SPAN_SUPPORT {
-                    if let Ok(mode) = srv.enable_rust_analyzer_spans() {
-                        srv.mode = mode;
-                    }
+                if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT
+                    && let Ok(mode) = srv.enable_rust_analyzer_spans()
+                {
+                    srv.protocol = Protocol::LegacyJson { mode };
                 }
-                tracing::info!("Proc-macro server span mode: {:?}", srv.mode);
+                tracing::info!("Proc-macro server protocol: {:?}", srv.protocol);
                 Ok(srv)
             }
             Err(e) => {
                 tracing::info!(%e, "proc-macro version check failed");
-                Err(
-                    io::Error::other(format!("proc-macro server version check failed: {e}")),
-                )
+                Err(io::Error::other(format!("proc-macro server version check failed: {e}")))
             }
         }
     }
@@ -98,25 +104,24 @@ impl ProcMacroServerProcess {
         self.version
     }
 
+    /// Enable support for rust-analyzer span mode if the server supports it.
+    pub(crate) fn rust_analyzer_spans(&self) -> bool {
+        match self.protocol {
+            Protocol::LegacyJson { mode } => mode == SpanMode::RustAnalyzer,
+        }
+    }
+
     /// Checks the API version of the running proc-macro server.
     fn version_check(&self) -> Result<u32, ServerError> {
-        let request = Request::ApiVersionCheck {};
-        let response = self.send_task(request)?;
-
-        match response {
-            Response::ApiVersionCheck(version) => Ok(version),
-            _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
+        match self.protocol {
+            Protocol::LegacyJson { .. } => legacy_protocol::version_check(self),
         }
     }
 
     /// Enable support for rust-analyzer span mode if the server supports it.
     fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> {
-        let request = Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer });
-        let response = self.send_task(request)?;
-
-        match response {
-            Response::SetConfig(ServerConfig { span_mode }) => Ok(span_mode),
-            _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
+        match self.protocol {
+            Protocol::LegacyJson { .. } => legacy_protocol::enable_rust_analyzer_spans(self),
         }
     }
 
@@ -125,25 +130,24 @@ impl ProcMacroServerProcess {
         &self,
         dylib_path: &AbsPath,
     ) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> {
-        let request = Request::ListMacros { dylib_path: dylib_path.to_path_buf().into() };
-
-        let response = self.send_task(request)?;
-
-        match response {
-            Response::ListMacros(it) => Ok(it),
-            _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
+        match self.protocol {
+            Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path),
         }
     }
 
-    /// Sends a request to the proc-macro server and waits for a response.
-    pub(crate) fn send_task(&self, req: Request) -> Result<Response, ServerError> {
-        if let Some(server_error) = self.exited.get() {
-            return Err(server_error.0.clone());
-        }
-
+    pub(crate) fn send_task<Request, Response>(
+        &self,
+        serialize_req: impl FnOnce(
+            &mut dyn Write,
+            &mut dyn BufRead,
+            Request,
+            &mut String,
+        ) -> Result<Option<Response>, ServerError>,
+        req: Request,
+    ) -> Result<Response, ServerError> {
         let state = &mut *self.state.lock().unwrap();
         let mut buf = String::new();
-        send_request(&mut state.stdin, &mut state.stdout, req, &mut buf)
+        serialize_req(&mut state.stdin, &mut state.stdout, req, &mut buf)
             .and_then(|res| {
                 res.ok_or_else(|| {
                     let message = "proc-macro server did not respond with data".to_owned();
@@ -162,10 +166,10 @@ impl ProcMacroServerProcess {
                         Ok(None) | Err(_) => e,
                         Ok(Some(status)) => {
                             let mut msg = String::new();
-                            if !status.success() {
-                                if let Some(stderr) = state.process.child.stderr.as_mut() {
-                                    _ = stderr.read_to_string(&mut msg);
-                                }
+                            if !status.success()
+                                && let Some(stderr) = state.process.child.stderr.as_mut()
+                            {
+                                _ = stderr.read_to_string(&mut msg);
                             }
                             let server_error = ServerError {
                                 message: format!(
@@ -242,21 +246,3 @@ fn mk_child<'a>(
     }
     cmd.spawn()
 }
-
-/// Sends a request to the server and reads the response.
-fn send_request(
-    mut writer: &mut impl Write,
-    mut reader: &mut impl BufRead,
-    req: Request,
-    buf: &mut String,
-) -> Result<Option<Response>, ServerError> {
-    req.write(write_json, &mut writer).map_err(|err| ServerError {
-        message: "failed to write request".into(),
-        io: Some(Arc::new(err)),
-    })?;
-    let res = Response::read(read_json, &mut reader, buf).map_err(|err| ServerError {
-        message: "failed to read response".into(),
-        io: Some(Arc::new(err)),
-    })?;
-    Ok(res)
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml
index ab421021b8b..91e9e62b084 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml
@@ -14,10 +14,14 @@ publish = false
 proc-macro-srv.workspace = true
 proc-macro-api.workspace = true
 tt.workspace = true
+clap = {version = "4.5.42", default-features = false, features = ["std"]}
+postcard = { version = "1.1.3", optional = true }
 
 [features]
+default = ["postcard"]
 sysroot-abi = ["proc-macro-srv/sysroot-abi"]
 in-rust-tree = ["proc-macro-srv/in-rust-tree", "sysroot-abi"]
+postcard = ["dep:postcard"]
 
 
 [[bin]]
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/build.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/build.rs
index 07f914fece0..12e7c8b05ba 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/build.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/build.rs
@@ -1,5 +1,49 @@
-//! This teaches cargo about our cfg(rust_analyzer)
+//! Construct version in the `commit-hash date channel` format
+
+use std::{env, path::PathBuf, process::Command};
 
 fn main() {
-    println!("cargo:rustc-check-cfg=cfg(rust_analyzer)");
+    set_rerun();
+    set_commit_info();
+    println!("cargo::rustc-check-cfg=cfg(rust_analyzer)");
+}
+
+fn set_rerun() {
+    println!("cargo:rerun-if-env-changed=CFG_RELEASE");
+
+    let mut manifest_dir = PathBuf::from(
+        env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` is always set by cargo."),
+    );
+
+    while manifest_dir.parent().is_some() {
+        let head_ref = manifest_dir.join(".git/HEAD");
+        if head_ref.exists() {
+            println!("cargo:rerun-if-changed={}", head_ref.display());
+            return;
+        }
+
+        manifest_dir.pop();
+    }
+
+    println!("cargo:warning=Could not find `.git/HEAD` from manifest dir!");
+}
+
+fn set_commit_info() {
+    #[allow(clippy::disallowed_methods)]
+    let output = match Command::new("git")
+        .arg("log")
+        .arg("-1")
+        .arg("--date=short")
+        .arg("--format=%H %h %cd")
+        .output()
+    {
+        Ok(output) if output.status.success() => output,
+        _ => return,
+    };
+    let stdout = String::from_utf8(output.stdout).unwrap();
+    let mut parts = stdout.split_whitespace();
+    let mut next = || parts.next().unwrap();
+    println!("cargo:rustc-env=RA_COMMIT_HASH={}", next());
+    println!("cargo:rustc-env=RA_COMMIT_SHORT_HASH={}", next());
+    println!("cargo:rustc-env=RA_COMMIT_DATE={}", next())
 }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs
index c47ed053254..662d34865ef 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs
@@ -2,13 +2,16 @@
 //! Driver for proc macro server
 #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
 #![cfg_attr(not(feature = "sysroot-abi"), allow(unused_crate_dependencies))]
-#![allow(clippy::print_stderr)]
+#![allow(clippy::print_stdout, clippy::print_stderr)]
 
 #[cfg(feature = "in-rust-tree")]
 extern crate rustc_driver as _;
 
+mod version;
+
 #[cfg(any(feature = "sysroot-abi", rust_analyzer))]
 mod main_loop;
+use clap::{Command, ValueEnum};
 #[cfg(any(feature = "sysroot-abi", rust_analyzer))]
 use main_loop::run;
 
@@ -23,12 +26,59 @@ fn main() -> std::io::Result<()> {
         );
         std::process::exit(122);
     }
+    let matches = Command::new("proc-macro-srv")
+        .args(&[
+            clap::Arg::new("format")
+                .long("format")
+                .action(clap::ArgAction::Set)
+                .default_value("json")
+                .value_parser(clap::builder::EnumValueParser::<ProtocolFormat>::new()),
+            clap::Arg::new("version")
+                .long("version")
+                .action(clap::ArgAction::SetTrue)
+                .help("Prints the version of the proc-macro-srv"),
+        ])
+        .get_matches();
+    if matches.get_flag("version") {
+        println!("rust-analyzer-proc-macro-srv {}", version::version());
+        return Ok(());
+    }
+    let &format =
+        matches.get_one::<ProtocolFormat>("format").expect("format value should always be present");
+    run(format)
+}
+
+#[derive(Copy, Clone)]
+enum ProtocolFormat {
+    Json,
+    #[cfg(feature = "postcard")]
+    Postcard,
+}
 
-    run()
+impl ValueEnum for ProtocolFormat {
+    fn value_variants<'a>() -> &'a [Self] {
+        &[ProtocolFormat::Json]
+    }
+
+    fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
+        match self {
+            ProtocolFormat::Json => Some(clap::builder::PossibleValue::new("json")),
+            #[cfg(feature = "postcard")]
+            ProtocolFormat::Postcard => Some(clap::builder::PossibleValue::new("postcard")),
+        }
+    }
+    fn from_str(input: &str, _ignore_case: bool) -> Result<Self, String> {
+        match input {
+            "json" => Ok(ProtocolFormat::Json),
+            #[cfg(feature = "postcard")]
+            "postcard" => Ok(ProtocolFormat::Postcard),
+            _ => Err(format!("unknown protocol format: {input}")),
+        }
+    }
 }
 
 #[cfg(not(any(feature = "sysroot-abi", rust_analyzer)))]
-fn run() -> std::io::Result<()> {
+fn run(_: ProtocolFormat) -> std::io::Result<()> {
     Err(std::io::Error::new(
         std::io::ErrorKind::Unsupported,
         "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function"
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 f54dff1f2d8..703bc965db2 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
@@ -1,16 +1,48 @@
 //! The main loop of the proc-macro server.
 use std::io;
 
-use proc_macro_api::legacy_protocol::{
-    json::{read_json, write_json},
-    msg::{
-        self, CURRENT_API_VERSION, ExpandMacroData, ExpnGlobals, Message, SpanMode, TokenId,
-        deserialize_span_data_index_map, serialize_span_data_index_map,
+use proc_macro_api::{
+    legacy_protocol::{
+        json::{read_json, write_json},
+        msg::{
+            self, ExpandMacroData, ExpnGlobals, Message, SpanMode, SpanTransformer,
+            deserialize_span_data_index_map, serialize_span_data_index_map,
+        },
     },
+    version::CURRENT_API_VERSION,
 };
-use proc_macro_srv::EnvSnapshot;
+use proc_macro_srv::{EnvSnapshot, SpanId};
 
-pub(crate) fn run() -> io::Result<()> {
+use crate::ProtocolFormat;
+
+struct SpanTrans;
+
+impl SpanTransformer for SpanTrans {
+    type Table = ();
+    type Span = SpanId;
+    fn token_id_of(
+        _: &mut Self::Table,
+        span: Self::Span,
+    ) -> proc_macro_api::legacy_protocol::SpanId {
+        proc_macro_api::legacy_protocol::SpanId(span.0)
+    }
+    fn span_for_token_id(
+        _: &Self::Table,
+        id: proc_macro_api::legacy_protocol::SpanId,
+    ) -> Self::Span {
+        SpanId(id.0)
+    }
+}
+
+pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> {
+    match format {
+        ProtocolFormat::Json => run_json(),
+        #[cfg(feature = "postcard")]
+        ProtocolFormat::Postcard => unimplemented!(),
+    }
+}
+
+fn run_json() -> io::Result<()> {
     fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind {
         match kind {
             proc_macro_srv::ProcMacroKind::CustomDerive => {
@@ -54,19 +86,20 @@ pub(crate) fn run() -> io::Result<()> {
                 } = *task;
                 match span_mode {
                     SpanMode::Id => msg::Response::ExpandMacro({
-                        let def_site = TokenId(def_site as u32);
-                        let call_site = TokenId(call_site as u32);
-                        let mixed_site = TokenId(mixed_site as u32);
+                        let def_site = SpanId(def_site as u32);
+                        let call_site = SpanId(call_site as u32);
+                        let mixed_site = SpanId(mixed_site as u32);
 
-                        let macro_body = macro_body.to_subtree_unresolved(CURRENT_API_VERSION);
-                        let attributes =
-                            attributes.map(|it| it.to_subtree_unresolved(CURRENT_API_VERSION));
+                        let macro_body =
+                            macro_body.to_subtree_unresolved::<SpanTrans>(CURRENT_API_VERSION);
+                        let attributes = attributes
+                            .map(|it| it.to_subtree_unresolved::<SpanTrans>(CURRENT_API_VERSION));
 
                         srv.expand(
                             lib,
-                            env,
+                            &env,
                             current_dir,
-                            macro_name,
+                            &macro_name,
                             macro_body,
                             attributes,
                             def_site,
@@ -74,8 +107,12 @@ pub(crate) fn run() -> io::Result<()> {
                             mixed_site,
                         )
                         .map(|it| {
-                            msg::FlatTree::new_raw(tt::SubtreeView::new(&it), CURRENT_API_VERSION)
+                            msg::FlatTree::new_raw::<SpanTrans>(
+                                tt::SubtreeView::new(&it),
+                                CURRENT_API_VERSION,
+                            )
                         })
+                        .map_err(|e| e.into_string().unwrap_or_default())
                         .map_err(msg::PanicMessage)
                     }),
                     SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({
@@ -92,9 +129,9 @@ pub(crate) fn run() -> io::Result<()> {
                         });
                         srv.expand(
                             lib,
-                            env,
+                            &env,
                             current_dir,
-                            macro_name,
+                            &macro_name,
                             macro_body,
                             attributes,
                             def_site,
@@ -115,6 +152,7 @@ pub(crate) fn run() -> io::Result<()> {
                             tree,
                             span_data_table,
                         })
+                        .map_err(|e| e.into_string().unwrap_or_default())
                         .map_err(msg::PanicMessage)
                     }),
                 }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/version.rs
new file mode 100644
index 00000000000..32499d055d1
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/version.rs
@@ -0,0 +1,58 @@
+//! Code for representing rust-analyzer's release version number.
+#![expect(dead_code)]
+
+use std::fmt;
+
+/// Information about the git repository where rust-analyzer was built from.
+pub(crate) struct CommitInfo {
+    pub(crate) short_commit_hash: &'static str,
+    pub(crate) commit_hash: &'static str,
+    pub(crate) commit_date: &'static str,
+}
+
+/// Cargo's version.
+pub(crate) struct VersionInfo {
+    /// rust-analyzer's version, such as "1.57.0", "1.58.0-beta.1", "1.59.0-nightly", etc.
+    pub(crate) version: &'static str,
+    /// The release channel we were built for (stable/beta/nightly/dev).
+    ///
+    /// `None` if not built via bootstrap.
+    pub(crate) release_channel: Option<&'static str>,
+    /// Information about the Git repository we may have been built from.
+    ///
+    /// `None` if not built from a git repo.
+    pub(crate) commit_info: Option<CommitInfo>,
+}
+
+impl fmt::Display for VersionInfo {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.version)?;
+
+        if let Some(ci) = &self.commit_info {
+            write!(f, " ({} {})", ci.short_commit_hash, ci.commit_date)?;
+        };
+        Ok(())
+    }
+}
+
+/// Returns information about cargo's version.
+pub(crate) const fn version() -> VersionInfo {
+    let version = match option_env!("CFG_RELEASE") {
+        Some(x) => x,
+        None => "0.0.0",
+    };
+
+    let release_channel = option_env!("CFG_RELEASE_CHANNEL");
+    let commit_info = match (
+        option_env!("RA_COMMIT_SHORT_HASH"),
+        option_env!("RA_COMMIT_HASH"),
+        option_env!("RA_COMMIT_DATE"),
+    ) {
+        (Some(short_commit_hash), Some(commit_hash), Some(commit_date)) => {
+            Some(CommitInfo { short_commit_hash, commit_hash, commit_date })
+        }
+        _ => None,
+    };
+
+    VersionInfo { version, release_channel, commit_info }
+}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
index 4034f244393..d037e715e70 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
@@ -16,6 +16,7 @@ doctest = false
 object.workspace = true
 libloading.workspace = true
 memmap2.workspace = true
+temp-dir.workspace = true
 
 tt.workspace = true
 syntax-bridge.workspace = true
@@ -26,6 +27,7 @@ intern.workspace = true
 
 ra-ap-rustc_lexer.workspace = true
 
+
 [target.'cfg(unix)'.dependencies]
 libc.workspace = true
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
index c49159df991..c8513a10675 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
@@ -1,65 +1,66 @@
 //! Handles dynamic library loading for proc macro
 
+mod proc_macros;
 mod version;
 
 use proc_macro::bridge;
 use std::{fmt, fs, io, time::SystemTime};
+use temp_dir::TempDir;
 
 use libloading::Library;
 use object::Object;
 use paths::{Utf8Path, Utf8PathBuf};
 
-use crate::{ProcMacroKind, ProcMacroSrvSpan, proc_macros::ProcMacros, server_impl::TopSubtree};
+use crate::{
+    PanicMessage, ProcMacroKind, ProcMacroSrvSpan, dylib::proc_macros::ProcMacros,
+    server_impl::TopSubtree,
+};
 
-/// Loads dynamic library in platform dependent manner.
-///
-/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
-/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
-/// and [here](https://github.com/rust-lang/rust/issues/60593).
-///
-/// Usage of RTLD_DEEPBIND
-/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
-///
-/// It seems that on Windows that behaviour is default, so we do nothing in that case.
-///
-/// # Safety
-///
-/// The caller is responsible for ensuring that the path is valid proc-macro library
-#[cfg(windows)]
-unsafe fn load_library(file: &Utf8Path) -> Result<Library, libloading::Error> {
-    // SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
-    unsafe { Library::new(file) }
+pub(crate) struct Expander {
+    inner: ProcMacroLibrary,
+    modified_time: SystemTime,
 }
 
-/// Loads dynamic library in platform dependent manner.
-///
-/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
-/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
-/// and [here](https://github.com/rust-lang/rust/issues/60593).
-///
-/// Usage of RTLD_DEEPBIND
-/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
-///
-/// It seems that on Windows that behaviour is default, so we do nothing in that case.
-///
-/// # Safety
-///
-/// The caller is responsible for ensuring that the path is valid proc-macro library
-#[cfg(unix)]
-unsafe fn load_library(file: &Utf8Path) -> Result<Library, libloading::Error> {
-    // not defined by POSIX, different values on mips vs other targets
-    #[cfg(target_env = "gnu")]
-    use libc::RTLD_DEEPBIND;
-    use libloading::os::unix::Library as UnixLibrary;
-    // defined by POSIX
-    use libloading::os::unix::RTLD_NOW;
+impl Expander {
+    pub(crate) fn new(
+        temp_dir: &TempDir,
+        lib: &Utf8Path,
+    ) -> Result<Expander, LoadProcMacroDylibError> {
+        // Some libraries for dynamic loading require canonicalized path even when it is
+        // already absolute
+        let lib = lib.canonicalize_utf8()?;
+        let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?;
 
-    // MUSL and bionic don't have it..
-    #[cfg(not(target_env = "gnu"))]
-    const RTLD_DEEPBIND: std::os::raw::c_int = 0x0;
+        let path = ensure_file_with_lock_free_access(temp_dir, &lib)?;
+        let library = ProcMacroLibrary::open(path.as_ref())?;
 
-    // SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
-    unsafe { UnixLibrary::open(Some(file), RTLD_NOW | RTLD_DEEPBIND).map(|lib| lib.into()) }
+        Ok(Expander { inner: library, modified_time })
+    }
+
+    pub(crate) fn expand<S: ProcMacroSrvSpan>(
+        &self,
+        macro_name: &str,
+        macro_body: TopSubtree<S>,
+        attributes: Option<TopSubtree<S>>,
+        def_site: S,
+        call_site: S,
+        mixed_site: S,
+    ) -> Result<TopSubtree<S>, PanicMessage>
+    where
+        <S::Server as bridge::server::Types>::TokenStream: Default,
+    {
+        self.inner
+            .proc_macros
+            .expand(macro_name, macro_body, attributes, def_site, call_site, mixed_site)
+    }
+
+    pub(crate) fn list_macros(&self) -> impl Iterator<Item = (&str, ProcMacroKind)> {
+        self.inner.proc_macros.list_macros()
+    }
+
+    pub(crate) fn modified_time(&self) -> SystemTime {
+        self.modified_time
+    }
 }
 
 #[derive(Debug)]
@@ -133,54 +134,6 @@ impl ProcMacroLibrary {
     }
 }
 
-// Drop order matters as we can't remove the dylib before the library is unloaded
-pub(crate) struct Expander {
-    inner: ProcMacroLibrary,
-    _remove_on_drop: RemoveFileOnDrop,
-    modified_time: SystemTime,
-}
-
-impl Expander {
-    pub(crate) fn new(lib: &Utf8Path) -> Result<Expander, LoadProcMacroDylibError> {
-        // Some libraries for dynamic loading require canonicalized path even when it is
-        // already absolute
-        let lib = lib.canonicalize_utf8()?;
-        let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?;
-
-        let path = ensure_file_with_lock_free_access(&lib)?;
-        let library = ProcMacroLibrary::open(path.as_ref())?;
-
-        Ok(Expander { inner: library, _remove_on_drop: RemoveFileOnDrop(path), modified_time })
-    }
-
-    pub(crate) fn expand<S: ProcMacroSrvSpan>(
-        &self,
-        macro_name: &str,
-        macro_body: TopSubtree<S>,
-        attributes: Option<TopSubtree<S>>,
-        def_site: S,
-        call_site: S,
-        mixed_site: S,
-    ) -> Result<TopSubtree<S>, String>
-    where
-        <S::Server as bridge::server::Types>::TokenStream: Default,
-    {
-        let result = self
-            .inner
-            .proc_macros
-            .expand(macro_name, macro_body, attributes, def_site, call_site, mixed_site);
-        result.map_err(|e| e.into_string().unwrap_or_default())
-    }
-
-    pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
-        self.inner.proc_macros.list_macros()
-    }
-
-    pub(crate) fn modified_time(&self) -> SystemTime {
-        self.modified_time
-    }
-}
-
 fn invalid_data_err(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
     io::Error::new(io::ErrorKind::InvalidData, e)
 }
@@ -210,18 +163,12 @@ fn find_registrar_symbol(obj: &object::File<'_>) -> object::Result<Option<String
         }))
 }
 
-struct RemoveFileOnDrop(Utf8PathBuf);
-impl Drop for RemoveFileOnDrop {
-    fn drop(&mut self) {
-        #[cfg(windows)]
-        std::fs::remove_file(&self.0).unwrap();
-        _ = self.0;
-    }
-}
-
 /// Copy the dylib to temp directory to prevent locking in Windows
 #[cfg(windows)]
-fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result<Utf8PathBuf> {
+fn ensure_file_with_lock_free_access(
+    temp_dir: &TempDir,
+    path: &Utf8Path,
+) -> io::Result<Utf8PathBuf> {
     use std::collections::hash_map::RandomState;
     use std::hash::{BuildHasher, Hasher};
 
@@ -229,9 +176,7 @@ fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result<Utf8PathBuf>
         return Ok(path.to_path_buf());
     }
 
-    let mut to = Utf8PathBuf::from_path_buf(std::env::temp_dir()).unwrap();
-    to.push("rust-analyzer-proc-macros");
-    _ = fs::create_dir(&to);
+    let mut to = Utf8Path::from_path(temp_dir.path()).unwrap().to_owned();
 
     let file_name = path.file_stem().ok_or_else(|| {
         io::Error::new(io::ErrorKind::InvalidInput, format!("File path is invalid: {path}"))
@@ -248,6 +193,60 @@ fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result<Utf8PathBuf>
 }
 
 #[cfg(unix)]
-fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result<Utf8PathBuf> {
+fn ensure_file_with_lock_free_access(
+    _temp_dir: &TempDir,
+    path: &Utf8Path,
+) -> io::Result<Utf8PathBuf> {
     Ok(path.to_owned())
 }
+
+/// Loads dynamic library in platform dependent manner.
+///
+/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
+/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
+/// and [here](https://github.com/rust-lang/rust/issues/60593).
+///
+/// Usage of RTLD_DEEPBIND
+/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
+///
+/// It seems that on Windows that behaviour is default, so we do nothing in that case.
+///
+/// # Safety
+///
+/// The caller is responsible for ensuring that the path is valid proc-macro library
+#[cfg(windows)]
+unsafe fn load_library(file: &Utf8Path) -> Result<Library, libloading::Error> {
+    // SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
+    unsafe { Library::new(file) }
+}
+
+/// Loads dynamic library in platform dependent manner.
+///
+/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
+/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
+/// and [here](https://github.com/rust-lang/rust/issues/60593).
+///
+/// Usage of RTLD_DEEPBIND
+/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
+///
+/// It seems that on Windows that behaviour is default, so we do nothing in that case.
+///
+/// # Safety
+///
+/// The caller is responsible for ensuring that the path is valid proc-macro library
+#[cfg(unix)]
+unsafe fn load_library(file: &Utf8Path) -> Result<Library, libloading::Error> {
+    // not defined by POSIX, different values on mips vs other targets
+    #[cfg(target_env = "gnu")]
+    use libc::RTLD_DEEPBIND;
+    use libloading::os::unix::Library as UnixLibrary;
+    // defined by POSIX
+    use libloading::os::unix::RTLD_NOW;
+
+    // MUSL and bionic don't have it..
+    #[cfg(not(target_env = "gnu"))]
+    const RTLD_DEEPBIND: std::os::raw::c_int = 0x0;
+
+    // SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
+    unsafe { UnixLibrary::open(Some(file), RTLD_NOW | RTLD_DEEPBIND).map(|lib| lib.into()) }
+}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs
index 18532706c4a..9b5721e370a 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs
@@ -75,20 +75,13 @@ impl ProcMacros {
         Err(bridge::PanicMessage::String(format!("proc-macro `{macro_name}` is missing")).into())
     }
 
-    pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
-        self.0
-            .iter()
-            .map(|proc_macro| match proc_macro {
-                bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
-                    (trait_name.to_string(), ProcMacroKind::CustomDerive)
-                }
-                bridge::client::ProcMacro::Bang { name, .. } => {
-                    (name.to_string(), ProcMacroKind::Bang)
-                }
-                bridge::client::ProcMacro::Attr { name, .. } => {
-                    (name.to_string(), ProcMacroKind::Attr)
-                }
-            })
-            .collect()
+    pub(crate) fn list_macros(&self) -> impl Iterator<Item = (&str, ProcMacroKind)> {
+        self.0.iter().map(|proc_macro| match *proc_macro {
+            bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
+                (trait_name, ProcMacroKind::CustomDerive)
+            }
+            bridge::client::ProcMacro::Bang { name, .. } => (name, ProcMacroKind::Bang),
+            bridge::client::ProcMacro::Attr { name, .. } => (name, ProcMacroKind::Attr),
+        })
     }
 }
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 223c5a54b70..cb97882c585 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
@@ -27,7 +27,6 @@ extern crate ra_ap_rustc_lexer as rustc_lexer;
 extern crate rustc_lexer;
 
 mod dylib;
-mod proc_macros;
 mod server_impl;
 
 use std::{
@@ -41,10 +40,13 @@ use std::{
 };
 
 use paths::{Utf8Path, Utf8PathBuf};
-use span::{Span, TokenId};
+use span::Span;
+use temp_dir::TempDir;
 
 use crate::server_impl::TokenStream;
 
+pub use crate::server_impl::token_id::SpanId;
+
 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
 pub enum ProcMacroKind {
     CustomDerive,
@@ -57,11 +59,16 @@ pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION");
 pub struct ProcMacroSrv<'env> {
     expanders: Mutex<HashMap<Utf8PathBuf, Arc<dylib::Expander>>>,
     env: &'env EnvSnapshot,
+    temp_dir: TempDir,
 }
 
 impl<'env> ProcMacroSrv<'env> {
     pub fn new(env: &'env EnvSnapshot) -> Self {
-        Self { expanders: Default::default(), env }
+        Self {
+            expanders: Default::default(),
+            env,
+            temp_dir: TempDir::with_prefix("proc-macro-srv").unwrap(),
+        }
     }
 }
 
@@ -71,18 +78,19 @@ impl ProcMacroSrv<'_> {
     pub fn expand<S: ProcMacroSrvSpan>(
         &self,
         lib: impl AsRef<Utf8Path>,
-        env: Vec<(String, String)>,
+        env: &[(String, String)],
         current_dir: Option<impl AsRef<Path>>,
-        macro_name: String,
+        macro_name: &str,
         macro_body: tt::TopSubtree<S>,
         attribute: Option<tt::TopSubtree<S>>,
         def_site: S,
         call_site: S,
         mixed_site: S,
-    ) -> Result<Vec<tt::TokenTree<S>>, String> {
+    ) -> Result<Vec<tt::TokenTree<S>>, PanicMessage> {
         let snapped_env = self.env;
-        let expander =
-            self.expander(lib.as_ref()).map_err(|err| format!("failed to load macro: {err}"))?;
+        let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage {
+            message: Some(format!("failed to load macro: {err}")),
+        })?;
 
         let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref));
 
@@ -91,11 +99,11 @@ impl ProcMacroSrv<'_> {
         let result = thread::scope(|s| {
             let thread = thread::Builder::new()
                 .stack_size(EXPANDER_STACK_SIZE)
-                .name(macro_name.clone())
+                .name(macro_name.to_owned())
                 .spawn_scoped(s, move || {
                     expander
                         .expand(
-                            &macro_name,
+                            macro_name,
                             server_impl::TopSubtree(macro_body.0.into_vec()),
                             attribute.map(|it| server_impl::TopSubtree(it.0.into_vec())),
                             def_site,
@@ -104,12 +112,7 @@ impl ProcMacroSrv<'_> {
                         )
                         .map(|tt| tt.0)
                 });
-            let res = match thread {
-                Ok(handle) => handle.join(),
-                Err(e) => return Err(e.to_string()),
-            };
-
-            match res {
+            match thread.unwrap().join() {
                 Ok(res) => res,
                 Err(e) => std::panic::resume_unwind(e),
             }
@@ -124,12 +127,12 @@ impl ProcMacroSrv<'_> {
         dylib_path: &Utf8Path,
     ) -> Result<Vec<(String, ProcMacroKind)>, String> {
         let expander = self.expander(dylib_path)?;
-        Ok(expander.list_macros())
+        Ok(expander.list_macros().map(|(k, v)| (k.to_owned(), v)).collect())
     }
 
     fn expander(&self, path: &Utf8Path) -> Result<Arc<dylib::Expander>, String> {
         let expander = || {
-            let expander = dylib::Expander::new(path)
+            let expander = dylib::Expander::new(&self.temp_dir, path)
                 .map_err(|err| format!("Cannot create expander for {path}: {err}",));
             expander.map(Arc::new)
         };
@@ -159,8 +162,8 @@ pub trait ProcMacroSrvSpan: Copy + Send {
     fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server;
 }
 
-impl ProcMacroSrvSpan for TokenId {
-    type Server = server_impl::token_id::TokenIdServer;
+impl ProcMacroSrvSpan for SpanId {
+    type Server = server_impl::token_id::SpanIdServer;
 
     fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server {
         Self::Server { call_site, def_site, mixed_site }
@@ -178,6 +181,8 @@ impl ProcMacroSrvSpan for Span {
         }
     }
 }
+
+#[derive(Debug, Clone)]
 pub struct PanicMessage {
     message: Option<String>,
 }
@@ -201,7 +206,7 @@ impl Default for EnvSnapshot {
 static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
 
 struct EnvChange<'snap> {
-    changed_vars: Vec<String>,
+    changed_vars: Vec<&'snap str>,
     prev_working_dir: Option<PathBuf>,
     snap: &'snap EnvSnapshot,
     _guard: std::sync::MutexGuard<'snap, ()>,
@@ -210,7 +215,7 @@ struct EnvChange<'snap> {
 impl<'snap> EnvChange<'snap> {
     fn apply(
         snap: &'snap EnvSnapshot,
-        new_vars: Vec<(String, String)>,
+        new_vars: &'snap [(String, String)],
         current_dir: Option<&Path>,
     ) -> EnvChange<'snap> {
         let guard = ENV_LOCK.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
@@ -230,11 +235,11 @@ impl<'snap> EnvChange<'snap> {
         EnvChange {
             snap,
             changed_vars: new_vars
-                .into_iter()
+                .iter()
                 .map(|(k, v)| {
                     // SAFETY: We have acquired the environment lock
-                    unsafe { env::set_var(&k, v) };
-                    k
+                    unsafe { env::set_var(k, v) };
+                    &**k
                 })
                 .collect(),
             prev_working_dir,
@@ -257,14 +262,14 @@ impl Drop for EnvChange<'_> {
             }
         }
 
-        if let Some(dir) = &self.prev_working_dir {
-            if let Err(err) = std::env::set_current_dir(dir) {
-                eprintln!(
-                    "Failed to set the current working dir to {}. Error: {:?}",
-                    dir.display(),
-                    err
-                )
-            }
+        if let Some(dir) = &self.prev_working_dir
+            && let Err(err) = std::env::set_current_dir(dir)
+        {
+            eprintln!(
+                "Failed to set the current working dir to {}. Error: {:?}",
+                dir.display(),
+                err
+            )
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
index 662f6257642..32ad32731ba 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
@@ -209,7 +209,7 @@ pub(super) fn from_token_tree<Span: Copy>(
                 token_trees.push(tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
                     spacing: tt::Spacing::Alone,
                     span: literal.span,
-                    char: '-' as char,
+                    char: '-',
                 })));
                 symbol = Symbol::intern(&symbol.as_str()[1..]);
             }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
index b493b325e83..91e70ea243a 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
@@ -1,4 +1,4 @@
-//! proc-macro server backend based on [`proc_macro_api::msg::TokenId`] as the backing span.
+//! proc-macro server backend based on [`proc_macro_api::msg::SpanId`] as the backing span.
 //! This backend is rather inflexible, used by RustRover and older rust-analyzer versions.
 use std::ops::{Bound, Range};
 
@@ -7,25 +7,34 @@ use proc_macro::bridge::{self, server};
 
 use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder};
 
-type Span = span::TokenId;
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub struct SpanId(pub u32);
+
+impl std::fmt::Debug for SpanId {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+type Span = SpanId;
 type TokenStream = crate::server_impl::TokenStream<Span>;
 
 pub struct FreeFunctions;
 
-pub struct TokenIdServer {
+pub struct SpanIdServer {
     pub call_site: Span,
     pub def_site: Span,
     pub mixed_site: Span,
 }
 
-impl server::Types for TokenIdServer {
+impl server::Types for SpanIdServer {
     type FreeFunctions = FreeFunctions;
     type TokenStream = TokenStream;
     type Span = Span;
     type Symbol = Symbol;
 }
 
-impl server::FreeFunctions for TokenIdServer {
+impl server::FreeFunctions for SpanIdServer {
     fn injected_env_var(&mut self, _: &str) -> Option<std::string::String> {
         None
     }
@@ -41,7 +50,7 @@ impl server::FreeFunctions for TokenIdServer {
     fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {}
 }
 
-impl server::TokenStream for TokenIdServer {
+impl server::TokenStream for SpanIdServer {
     fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
         stream.is_empty()
     }
@@ -102,12 +111,12 @@ impl server::TokenStream for TokenIdServer {
         &mut self,
         stream: Self::TokenStream,
     ) -> Vec<bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>> {
-        // Can't join with `TokenId`.
+        // Can't join with `SpanId`.
         stream.into_bridge(&mut |first, _second| first)
     }
 }
 
-impl server::Span for TokenIdServer {
+impl server::Span for SpanIdServer {
     fn debug(&mut self, span: Self::Span) -> String {
         format!("{:?}", span.0)
     }
@@ -174,14 +183,14 @@ impl server::Span for TokenIdServer {
     }
 }
 
-impl server::Symbol for TokenIdServer {
+impl server::Symbol for SpanIdServer {
     fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
         // FIXME: nfc-normalize and validate idents
         Ok(<Self as server::Server>::intern_symbol(string))
     }
 }
 
-impl server::Server for TokenIdServer {
+impl server::Server for SpanIdServer {
     fn globals(&mut self) -> bridge::ExpnGlobals<Self::Span> {
         bridge::ExpnGlobals {
             def_site: self.def_site,
@@ -201,8 +210,6 @@ impl server::Server for TokenIdServer {
 
 #[cfg(test)]
 mod tests {
-    use span::TokenId;
-
     use super::*;
 
     #[test]
@@ -211,18 +218,18 @@ mod tests {
             token_trees: vec![
                 tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("struct"),
-                    span: TokenId(0),
+                    span: SpanId(0),
                     is_raw: tt::IdentIsRaw::No,
                 })),
                 tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("T"),
-                    span: TokenId(0),
+                    span: SpanId(0),
                     is_raw: tt::IdentIsRaw::No,
                 })),
                 tt::TokenTree::Subtree(tt::Subtree {
                     delimiter: tt::Delimiter {
-                        open: TokenId(0),
-                        close: TokenId(0),
+                        open: SpanId(0),
+                        close: SpanId(0),
                         kind: tt::DelimiterKind::Brace,
                     },
                     len: 0,
@@ -238,8 +245,8 @@ mod tests {
         let subtree_paren_a = vec![
             tt::TokenTree::Subtree(tt::Subtree {
                 delimiter: tt::Delimiter {
-                    open: TokenId(0),
-                    close: TokenId(0),
+                    open: SpanId(0),
+                    close: SpanId(0),
                     kind: tt::DelimiterKind::Parenthesis,
                 },
                 len: 1,
@@ -247,24 +254,24 @@ mod tests {
             tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                 is_raw: tt::IdentIsRaw::No,
                 sym: Symbol::intern("a"),
-                span: TokenId(0),
+                span: SpanId(0),
             })),
         ];
 
-        let t1 = TokenStream::from_str("(a)", TokenId(0)).unwrap();
+        let t1 = TokenStream::from_str("(a)", SpanId(0)).unwrap();
         assert_eq!(t1.token_trees.len(), 2);
         assert!(t1.token_trees[0..2] == subtree_paren_a);
 
-        let t2 = TokenStream::from_str("(a);", TokenId(0)).unwrap();
+        let t2 = TokenStream::from_str("(a);", SpanId(0)).unwrap();
         assert_eq!(t2.token_trees.len(), 3);
         assert!(t2.token_trees[0..2] == subtree_paren_a);
 
-        let underscore = TokenStream::from_str("_", TokenId(0)).unwrap();
+        let underscore = TokenStream::from_str("_", SpanId(0)).unwrap();
         assert!(
             underscore.token_trees[0]
                 == tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("_"),
-                    span: TokenId(0),
+                    span: SpanId(0),
                     is_raw: tt::IdentIsRaw::No,
                 }))
         );
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 10af5662b5c..f5a76e30bbc 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
@@ -1,14 +1,12 @@
 //! utils used in proc-macro tests
 
 use expect_test::Expect;
-use span::{
-    EditionedFileId, FileId, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext, TokenId,
-};
+use span::{EditionedFileId, FileId, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext};
 use tt::TextRange;
 
-use crate::{EnvSnapshot, ProcMacroSrv, dylib, proc_macro_test_dylib_path};
+use crate::{EnvSnapshot, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path};
 
-fn parse_string(call_site: TokenId, src: &str) -> crate::server_impl::TokenStream<TokenId> {
+fn parse_string(call_site: SpanId, src: &str) -> crate::server_impl::TokenStream<SpanId> {
     crate::server_impl::TokenStream::with_subtree(crate::server_impl::TopSubtree(
         syntax_bridge::parse_to_token_tree_static_span(span::Edition::CURRENT, call_site, src)
             .unwrap()
@@ -57,11 +55,11 @@ fn assert_expand_impl(
     expect_spanned: Expect,
 ) {
     let path = proc_macro_test_dylib_path();
-    let expander = dylib::Expander::new(&path).unwrap();
+    let expander = dylib::Expander::new(&temp_dir::TempDir::new().unwrap(), &path).unwrap();
 
-    let def_site = TokenId(0);
-    let call_site = TokenId(1);
-    let mixed_site = TokenId(2);
+    let def_site = SpanId(0);
+    let call_site = SpanId(1);
+    let mixed_site = SpanId(2);
     let input_ts = parse_string(call_site, input).into_subtree(call_site);
     let attr_ts = attr.map(|attr| parse_string(call_site, attr).into_subtree(call_site));
     let input_ts_string = format!("{input_ts:?}");
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
index ec4b6b2a4ac..277cc0b269d 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
@@ -278,15 +278,15 @@ pub(crate) fn query_group_impl(
                 return Err(syn::Error::new(signature.span(), "Queries must have a return type"));
             };
 
-            if let syn::Type::Path(ref ty_path) = *return_ty {
-                if matches!(query_kind, QueryKind::Input) {
-                    let field = InputStructField {
-                        name: method_name.to_token_stream(),
-                        ty: ty_path.path.to_token_stream(),
-                    };
-
-                    input_struct_fields.push(field);
-                }
+            if let syn::Type::Path(ref ty_path) = *return_ty
+                && matches!(query_kind, QueryKind::Input)
+            {
+                let field = InputStructField {
+                    name: method_name.to_token_stream(),
+                    ty: ty_path.path.to_token_stream(),
+                };
+
+                input_struct_fields.push(field);
             }
 
             if let Some(block) = &mut method.default {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
index 4dba97c8ec4..ab045e0bf9f 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
@@ -122,12 +122,12 @@ fn setup_logging(log_file_flag: Option<PathBuf>) -> anyhow::Result<()> {
         // directory which we set to the project workspace.
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/general-environment-variables
         // https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-syminitialize
-        if let Ok(path) = env::current_exe() {
-            if let Some(path) = path.parent() {
-                // SAFETY: This is safe because this is single-threaded.
-                unsafe {
-                    env::set_var("_NT_SYMBOL_PATH", path);
-                }
+        if let Ok(path) = env::current_exe()
+            && let Some(path) = path.parent()
+        {
+            // SAFETY: This is safe because this is single-threaded.
+            unsafe {
+                env::set_var("_NT_SYMBOL_PATH", path);
             }
         }
     }
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 4f75d14834c..97886844a9f 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
@@ -136,34 +136,30 @@ impl flags::AnalysisStats {
         for source_root_id in source_roots {
             let source_root = db.source_root(source_root_id).source_root(db);
             for file_id in source_root.iter() {
-                if let Some(p) = source_root.path_for_file(&file_id) {
-                    if let Some((_, Some("rs"))) = p.name_and_extension() {
-                        // measure workspace/project code
-                        if !source_root.is_library || self.with_deps {
-                            let length = db.file_text(file_id).text(db).lines().count();
-                            let item_stats = db
-                                .file_item_tree(
-                                    EditionedFileId::current_edition(db, file_id).into(),
-                                )
-                                .item_tree_stats()
-                                .into();
-
-                            workspace_loc += length;
-                            workspace_item_trees += 1;
-                            workspace_item_stats += item_stats;
-                        } else {
-                            let length = db.file_text(file_id).text(db).lines().count();
-                            let item_stats = db
-                                .file_item_tree(
-                                    EditionedFileId::current_edition(db, file_id).into(),
-                                )
-                                .item_tree_stats()
-                                .into();
-
-                            dep_loc += length;
-                            dep_item_trees += 1;
-                            dep_item_stats += item_stats;
-                        }
+                if let Some(p) = source_root.path_for_file(&file_id)
+                    && let Some((_, Some("rs"))) = p.name_and_extension()
+                {
+                    // measure workspace/project code
+                    if !source_root.is_library || self.with_deps {
+                        let length = db.file_text(file_id).text(db).lines().count();
+                        let item_stats = db
+                            .file_item_tree(EditionedFileId::current_edition(db, file_id).into())
+                            .item_tree_stats()
+                            .into();
+
+                        workspace_loc += length;
+                        workspace_item_trees += 1;
+                        workspace_item_stats += item_stats;
+                    } else {
+                        let length = db.file_text(file_id).text(db).lines().count();
+                        let item_stats = db
+                            .file_item_tree(EditionedFileId::current_edition(db, file_id).into())
+                            .item_tree_stats()
+                            .into();
+
+                        dep_loc += length;
+                        dep_item_trees += 1;
+                        dep_item_stats += item_stats;
                     }
                 }
             }
@@ -560,29 +556,35 @@ impl flags::AnalysisStats {
                         std::fs::write(path, txt).unwrap();
 
                         let res = ws.run_build_scripts(&cargo_config, &|_| ()).unwrap();
-                        if let Some(err) = res.error() {
-                            if err.contains("error: could not compile") {
-                                if let Some(mut err_idx) = err.find("error[E") {
-                                    err_idx += 7;
-                                    let err_code = &err[err_idx..err_idx + 4];
-                                    match err_code {
-                                        "0282" | "0283" => continue, // Byproduct of testing method
-                                        "0277" | "0308" if generated.contains(&todo) => continue, // See https://github.com/rust-lang/rust/issues/69882
-                                        // FIXME: In some rare cases `AssocItem::container_or_implemented_trait` returns `None` for trait methods.
-                                        // Generated code is valid in case traits are imported
-                                        "0599" if err.contains("the following trait is implemented but not in scope") => continue,
-                                        _ => (),
+                        if let Some(err) = res.error()
+                            && err.contains("error: could not compile")
+                        {
+                            if let Some(mut err_idx) = err.find("error[E") {
+                                err_idx += 7;
+                                let err_code = &err[err_idx..err_idx + 4];
+                                match err_code {
+                                    "0282" | "0283" => continue, // Byproduct of testing method
+                                    "0277" | "0308" if generated.contains(&todo) => continue, // See https://github.com/rust-lang/rust/issues/69882
+                                    // FIXME: In some rare cases `AssocItem::container_or_implemented_trait` returns `None` for trait methods.
+                                    // Generated code is valid in case traits are imported
+                                    "0599"
+                                        if err.contains(
+                                            "the following trait is implemented but not in scope",
+                                        ) =>
+                                    {
+                                        continue;
                                     }
-                                    bar.println(err);
-                                    bar.println(generated);
-                                    acc.error_codes
-                                        .entry(err_code.to_owned())
-                                        .and_modify(|n| *n += 1)
-                                        .or_insert(1);
-                                } else {
-                                    acc.syntax_errors += 1;
-                                    bar.println(format!("Syntax error: \n{err}"));
+                                    _ => (),
                                 }
+                                bar.println(err);
+                                bar.println(generated);
+                                acc.error_codes
+                                    .entry(err_code.to_owned())
+                                    .and_modify(|n| *n += 1)
+                                    .or_insert(1);
+                            } else {
+                                acc.syntax_errors += 1;
+                                bar.println(format!("Syntax error: \n{err}"));
                             }
                         }
                     }
@@ -731,12 +733,11 @@ impl flags::AnalysisStats {
             let name = body_id.name(db).unwrap_or_else(Name::missing);
             let module = body_id.module(db);
             let display_target = module.krate().to_display_target(db);
-            if let Some(only_name) = self.only.as_deref() {
-                if name.display(db, Edition::LATEST).to_string() != only_name
-                    && full_name(db, body_id, module) != only_name
-                {
-                    continue;
-                }
+            if let Some(only_name) = self.only.as_deref()
+                && name.display(db, Edition::LATEST).to_string() != only_name
+                && full_name(db, body_id, module) != only_name
+            {
+                continue;
             }
             let msg = move || {
                 if verbosity.is_verbose() {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/progress_report.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/progress_report.rs
index 1b9b870a7c7..028311388c5 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/progress_report.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/progress_report.rs
@@ -83,11 +83,11 @@ impl<'a> ProgressReport<'a> {
         output.extend(text.chars().skip(common_prefix_length));
 
         // If the new text is shorter than the old one: delete overlapping characters
-        if let Some(overlap_count) = self.text.len().checked_sub(text.len()) {
-            if overlap_count > 0 {
-                output += &" ".repeat(overlap_count);
-                output += &"\x08".repeat(overlap_count);
-            }
+        if let Some(overlap_count) = self.text.len().checked_sub(text.len())
+            && overlap_count > 0
+        {
+            output += &" ".repeat(overlap_count);
+            output += &"\x08".repeat(overlap_count);
         }
 
         let _ = io::stdout().write(output.as_bytes());
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs
index 30ac93fb6f8..36ae98b321b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs
@@ -305,10 +305,10 @@ impl flags::RustcTests {
         for i in walk_dir {
             let i = i?;
             let p = i.into_path();
-            if let Some(f) = &self.filter {
-                if !p.as_os_str().to_string_lossy().contains(f) {
-                    continue;
-                }
+            if let Some(f) = &self.filter
+                && !p.as_os_str().to_string_lossy().contains(f)
+            {
+                continue;
             }
             if p.extension().is_none_or(|x| x != "rs") {
                 continue;
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 9456fd8809b..1a00295b9ac 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -61,233 +61,312 @@ pub enum MaxSubstitutionLength {
     Limit(usize),
 }
 
-// Defines the server-side configuration of the rust-analyzer. We generate
-// *parts* of VS Code's `package.json` config from this. Run `cargo test` to
-// re-generate that file.
+// Defines the server-side configuration of the rust-analyzer. We generate *parts* of VS Code's
+// `package.json` config from this. Run `cargo test` to re-generate that file.
 //
-// However, editor specific config, which the server doesn't know about, should
-// be specified directly in `package.json`.
+// However, editor specific config, which the server doesn't know about, should be specified
+// directly in `package.json`.
 //
-// To deprecate an option by replacing it with another name use `new_name` | `old_name` so that we keep
-// parsing the old name.
+// To deprecate an option by replacing it with another name use `new_name` | `old_name` so that we
+// keep parsing the old name.
 config_data! {
-    /// Configs that apply on a workspace-wide scope. There are 2 levels on which a global configuration can be configured
+    /// Configs that apply on a workspace-wide scope. There are 2 levels on which a global
+    /// configuration can be configured
     ///
-    /// 1. `rust-analyzer.toml` file under user's config directory (e.g ~/.config/rust-analyzer/rust-analyzer.toml)
+    /// 1. `rust-analyzer.toml` file under user's config directory (e.g
+    ///    ~/.config/rust-analyzer/rust-analyzer.toml)
     /// 2. Client's own configurations (e.g `settings.json` on VS Code)
     ///
-    /// A config is searched for by traversing a "config tree" in a bottom up fashion. It is chosen by the nearest first principle.
+    /// A config is searched for by traversing a "config tree" in a bottom up fashion. It is chosen
+    /// by the nearest first principle.
     global: struct GlobalDefaultConfigData <- GlobalConfigInput -> {
         /// Warm up caches on project load.
         cachePriming_enable: bool = true,
-        /// How many worker threads to handle priming caches. The default `0` means to pick automatically.
+
+        /// How many worker threads to handle priming caches. The default `0` means to pick
+        /// automatically.
         cachePriming_numThreads: NumThreads = NumThreads::Physical,
 
         /// Custom completion snippets.
-        completion_snippets_custom: FxIndexMap<String, SnippetDef> = Config::completion_snippets_default(),
-
+        completion_snippets_custom: FxIndexMap<String, SnippetDef> =
+            Config::completion_snippets_default(),
 
-        /// These paths (file/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`.
+        /// List of files to ignore
+        ///
+        /// These paths (file/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`.
         files_exclude | files_excludeDirs: Vec<Utf8PathBuf> = vec![],
 
-
-
-        /// Enables highlighting of related return values while the cursor is on any `match`, `if`, or match arm arrow (`=>`).
+        /// Highlight related return values while the cursor is on any `match`, `if`, or match arm
+        /// arrow (`=>`).
         highlightRelated_branchExitPoints_enable: bool = true,
-        /// Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords.
+
+        /// Highlight related references while the cursor is on `break`, `loop`, `while`, or `for`
+        /// keywords.
         highlightRelated_breakPoints_enable: bool = true,
-        /// Enables highlighting of all captures of a closure while the cursor is on the `|` or move keyword of a closure.
+
+        /// Highlight all captures of a closure while the cursor is on the `|` or move keyword of a closure.
         highlightRelated_closureCaptures_enable: bool = true,
-        /// Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`).
+
+        /// Highlight all exit points while the cursor is on any `return`, `?`, `fn`, or return type
+        /// arrow (`->`).
         highlightRelated_exitPoints_enable: bool = true,
-        /// Enables highlighting of related references while the cursor is on any identifier.
+
+        /// Highlight related references while the cursor is on any identifier.
         highlightRelated_references_enable: bool = true,
-        /// Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords.
+
+        /// Highlight all break points for a loop or block context while the cursor is on any
+        /// `async` or `await` keywords.
         highlightRelated_yieldPoints_enable: bool = true,
 
-        /// Whether to show `Debug` action. Only applies when
-        /// `#rust-analyzer.hover.actions.enable#` is set.
-        hover_actions_debug_enable: bool           = true,
-        /// Whether to show HoverActions in Rust files.
-        hover_actions_enable: bool          = true,
-        /// Whether to show `Go to Type Definition` action. Only applies when
-        /// `#rust-analyzer.hover.actions.enable#` is set.
-        hover_actions_gotoTypeDef_enable: bool     = true,
-        /// Whether to show `Implementations` action. Only applies when
+        /// Show `Debug` action. Only applies when `#rust-analyzer.hover.actions.enable#` is set.
+        hover_actions_debug_enable: bool = true,
+
+        /// Show HoverActions in Rust files.
+        hover_actions_enable: bool = true,
+
+        /// Show `Go to Type Definition` action. Only applies when
         /// `#rust-analyzer.hover.actions.enable#` is set.
+        hover_actions_gotoTypeDef_enable: bool = true,
+
+        /// Show `Implementations` action. Only applies when `#rust-analyzer.hover.actions.enable#`
+        /// is set.
         hover_actions_implementations_enable: bool = true,
-        /// Whether to show `References` action. Only applies when
-        /// `#rust-analyzer.hover.actions.enable#` is set.
-        hover_actions_references_enable: bool      = false,
-        /// Whether to show `Run` action. Only applies when
-        /// `#rust-analyzer.hover.actions.enable#` is set.
-        hover_actions_run_enable: bool             = true,
-        /// Whether to show `Update Test` action. Only applies when
-        /// `#rust-analyzer.hover.actions.enable#` and `#rust-analyzer.hover.actions.run.enable#` are set.
-        hover_actions_updateTest_enable: bool     = true,
-
-        /// Whether to show documentation on hover.
-        hover_documentation_enable: bool           = true,
-        /// Whether to show keyword hover popups. Only applies when
+
+        /// Show `References` action. Only applies when `#rust-analyzer.hover.actions.enable#` is
+        /// set.
+        hover_actions_references_enable: bool = false,
+
+        /// Show `Run` action. Only applies when `#rust-analyzer.hover.actions.enable#` is set.
+        hover_actions_run_enable: bool = true,
+
+        /// Show `Update Test` action. Only applies when `#rust-analyzer.hover.actions.enable#` and
+        /// `#rust-analyzer.hover.actions.run.enable#` are set.
+        hover_actions_updateTest_enable: bool = true,
+
+        /// Show documentation on hover.
+        hover_documentation_enable: bool = true,
+
+        /// Show keyword hover popups. Only applies when
         /// `#rust-analyzer.hover.documentation.enable#` is set.
-        hover_documentation_keywords_enable: bool  = true,
-        /// Whether to show drop glue information on hover.
-        hover_dropGlue_enable: bool                = true,
+        hover_documentation_keywords_enable: bool = true,
+
+        /// Show drop glue information on hover.
+        hover_dropGlue_enable: bool = true,
+
         /// Use markdown syntax for links on hover.
         hover_links_enable: bool = true,
-        /// 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.
+
+        /// Show what types are used as generic arguments in calls etc. on hover, and limit the max
+        /// length to show such types, beyond which 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.
+        /// 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.
-        hover_maxSubstitutionLength: Option<MaxSubstitutionLength> = Some(MaxSubstitutionLength::Limit(20)),
+        hover_maxSubstitutionLength: Option<MaxSubstitutionLength> =
+            Some(MaxSubstitutionLength::Limit(20)),
+
         /// How to render the align information in a memory layout hover.
-        hover_memoryLayout_alignment: Option<MemoryLayoutHoverRenderKindDef> = Some(MemoryLayoutHoverRenderKindDef::Hexadecimal),
-        /// Whether to show memory layout data on hover.
+        hover_memoryLayout_alignment: Option<MemoryLayoutHoverRenderKindDef> =
+            Some(MemoryLayoutHoverRenderKindDef::Hexadecimal),
+
+        /// Show memory layout data on hover.
         hover_memoryLayout_enable: bool = true,
+
         /// How to render the niche information in a memory layout hover.
         hover_memoryLayout_niches: Option<bool> = Some(false),
+
         /// How to render the offset information in a memory layout hover.
-        hover_memoryLayout_offset: Option<MemoryLayoutHoverRenderKindDef> = Some(MemoryLayoutHoverRenderKindDef::Hexadecimal),
+        hover_memoryLayout_offset: Option<MemoryLayoutHoverRenderKindDef> =
+            Some(MemoryLayoutHoverRenderKindDef::Hexadecimal),
+
         /// How to render the padding information in a memory layout hover.
         hover_memoryLayout_padding: Option<MemoryLayoutHoverRenderKindDef> = None,
+
         /// How to render the size information in a memory layout hover.
-        hover_memoryLayout_size: Option<MemoryLayoutHoverRenderKindDef> = Some(MemoryLayoutHoverRenderKindDef::Both),
+        hover_memoryLayout_size: Option<MemoryLayoutHoverRenderKindDef> =
+            Some(MemoryLayoutHoverRenderKindDef::Both),
 
         /// How many variants of an enum to display when hovering on. Show none if empty.
         hover_show_enumVariants: Option<usize> = Some(5),
-        /// How many fields of a struct, variant or union to display when hovering on. Show none if empty.
+
+        /// How many fields of a struct, variant or union to display when hovering on. Show none if
+        /// empty.
         hover_show_fields: Option<usize> = Some(5),
+
         /// How many associated items of a trait to display when hovering a trait.
         hover_show_traitAssocItems: Option<usize> = None,
 
-        /// Whether to show inlay type hints for binding modes.
-        inlayHints_bindingModeHints_enable: bool                   = false,
-        /// Whether to show inlay type hints for method chains.
-        inlayHints_chainingHints_enable: bool                      = true,
-        /// Whether to show inlay hints after a closing `}` to indicate what item it belongs to.
-        inlayHints_closingBraceHints_enable: bool                  = true,
+        /// Show inlay type hints for binding modes.
+        inlayHints_bindingModeHints_enable: bool = false,
+
+        /// Show inlay type hints for method chains.
+        inlayHints_chainingHints_enable: bool = true,
+
+        /// Show inlay hints after a closing `}` to indicate what item it belongs to.
+        inlayHints_closingBraceHints_enable: bool = true,
+
         /// Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1
         /// to always show them).
-        inlayHints_closingBraceHints_minLines: usize               = 25,
-        /// Whether to show inlay hints for closure captures.
-        inlayHints_closureCaptureHints_enable: bool                          = false,
-        /// Whether to show inlay type hints for return types of closures.
-        inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef  = ClosureReturnTypeHintsDef::Never,
+        inlayHints_closingBraceHints_minLines: usize = 25,
+
+        /// Show inlay hints for closure captures.
+        inlayHints_closureCaptureHints_enable: bool = false,
+
+        /// Show inlay type hints for return types of closures.
+        inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef =
+            ClosureReturnTypeHintsDef::Never,
+
         /// Closure notation in type and chaining inlay hints.
-        inlayHints_closureStyle: ClosureStyle                                = ClosureStyle::ImplFn,
-        /// Whether to show enum variant discriminant hints.
-        inlayHints_discriminantHints_enable: DiscriminantHintsDef            = DiscriminantHintsDef::Never,
-        /// Whether to show inlay hints for type adjustments.
-        inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = AdjustmentHintsDef::Never,
-        /// Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
+        inlayHints_closureStyle: ClosureStyle = ClosureStyle::ImplFn,
+
+        /// Show enum variant discriminant hints.
+        inlayHints_discriminantHints_enable: DiscriminantHintsDef =
+            DiscriminantHintsDef::Never,
+
+        /// Show inlay hints for type adjustments.
+        inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef =
+            AdjustmentHintsDef::Never,
+
+        /// Hide inlay hints for type adjustments outside of `unsafe` blocks.
         inlayHints_expressionAdjustmentHints_hideOutsideUnsafe: bool = false,
-        /// Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).
-        inlayHints_expressionAdjustmentHints_mode: AdjustmentHintsModeDef = AdjustmentHintsModeDef::Prefix,
-        /// Whether to show const generic parameter name inlay hints.
-        inlayHints_genericParameterHints_const_enable: bool= true,
-        /// Whether to show generic lifetime parameter name inlay hints.
+
+        /// Show inlay hints as postfix ops (`.*` instead of `*`, etc).
+        inlayHints_expressionAdjustmentHints_mode: AdjustmentHintsModeDef =
+            AdjustmentHintsModeDef::Prefix,
+
+        /// Show const generic parameter name inlay hints.
+        inlayHints_genericParameterHints_const_enable: bool = true,
+
+        /// Show generic lifetime parameter name inlay hints.
         inlayHints_genericParameterHints_lifetime_enable: bool = false,
-        /// Whether to show generic type parameter name inlay hints.
+
+        /// Show generic type parameter name inlay hints.
         inlayHints_genericParameterHints_type_enable: bool = false,
-        /// Whether to show implicit drop hints.
-        inlayHints_implicitDrops_enable: bool                      = false,
-        /// Whether to show inlay hints for the implied type parameter `Sized` bound.
-        inlayHints_implicitSizedBoundHints_enable: bool            = false,
-        /// Whether to show inlay type hints for elided lifetimes in function signatures.
+
+        /// Show implicit drop hints.
+        inlayHints_implicitDrops_enable: bool = false,
+
+        /// Show inlay hints for the implied type parameter `Sized` bound.
+        inlayHints_implicitSizedBoundHints_enable: bool = false,
+
+        /// Show inlay type hints for elided lifetimes in function signatures.
         inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = LifetimeElisionDef::Never,
-        /// Whether to prefer using parameter names as the name for elided lifetime hints if possible.
-        inlayHints_lifetimeElisionHints_useParameterNames: bool    = false,
+
+        /// Prefer using parameter names as the name for elided lifetime hints if possible.
+        inlayHints_lifetimeElisionHints_useParameterNames: bool = false,
+
         /// Maximum length for inlay hints. Set to null to have an unlimited length.
-        inlayHints_maxLength: Option<usize>                        = Some(25),
-        /// Whether to show function parameter name inlay hints at the call
-        /// site.
-        inlayHints_parameterHints_enable: bool                     = true,
-        /// Whether to show exclusive range inlay hints.
-        inlayHints_rangeExclusiveHints_enable: bool                = false,
-        /// Whether to show inlay hints for compiler inserted reborrows.
-        /// This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.
-        inlayHints_reborrowHints_enable: ReborrowHintsDef          = ReborrowHintsDef::Never,
+        inlayHints_maxLength: Option<usize> = Some(25),
+
+        /// Show function parameter name inlay hints at the call site.
+        inlayHints_parameterHints_enable: bool = true,
+
+        /// Show exclusive range inlay hints.
+        inlayHints_rangeExclusiveHints_enable: bool = false,
+
+        /// Show inlay hints for compiler inserted reborrows.
+        ///
+        /// This setting is deprecated in favor of
+        /// #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.
+        inlayHints_reborrowHints_enable: ReborrowHintsDef = ReborrowHintsDef::Never,
+
         /// Whether to render leading colons for type hints, and trailing colons for parameter hints.
-        inlayHints_renderColons: bool                              = true,
-        /// Whether to show inlay type hints for variables.
-        inlayHints_typeHints_enable: bool                          = true,
-        /// 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,
-
-        /// Enables the experimental support for interpreting tests.
+        inlayHints_renderColons: bool = true,
+
+        /// Show inlay type hints for variables.
+        inlayHints_typeHints_enable: bool = true,
+
+        /// 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,
+
+        /// Hide inlay parameter type hints for closures.
+        inlayHints_typeHints_hideClosureParameter: bool = false,
+
+        /// Hide inlay type hints for constructors.
+        inlayHints_typeHints_hideNamedConstructor: bool = false,
+
+        /// Enable the experimental support for interpreting tests.
         interpret_tests: bool = false,
 
         /// Join lines merges consecutive declaration and initialization of an assignment.
         joinLines_joinAssignments: bool = true,
+
         /// Join lines inserts else between consecutive ifs.
         joinLines_joinElseIf: bool = true,
+
         /// Join lines removes trailing commas.
         joinLines_removeTrailingComma: bool = true,
+
         /// Join lines unwraps trivial blocks.
         joinLines_unwrapTrivialBlock: bool = true,
 
-        /// Whether to show `Debug` lens. Only applies when
-        /// `#rust-analyzer.lens.enable#` is set.
-        lens_debug_enable: bool            = true,
-        /// Whether to show CodeLens in Rust files.
-        lens_enable: bool           = true,
-        /// Whether to show `Implementations` lens. Only applies when
-        /// `#rust-analyzer.lens.enable#` is set.
-        lens_implementations_enable: bool  = true,
+        /// Show `Debug` lens. Only applies when `#rust-analyzer.lens.enable#` is set.
+        lens_debug_enable: bool = true,
+
+        /// Show CodeLens in Rust files.
+        lens_enable: bool = true,
+
+        /// Show `Implementations` lens. Only applies when `#rust-analyzer.lens.enable#` is set.
+        lens_implementations_enable: bool = true,
+
         /// Where to render annotations.
         lens_location: AnnotationLocation = AnnotationLocation::AboveName,
-        /// Whether to show `References` lens for Struct, Enum, and Union.
-        /// Only applies when `#rust-analyzer.lens.enable#` is set.
+
+        /// Show `References` lens for Struct, Enum, and Union. Only applies when
+        /// `#rust-analyzer.lens.enable#` is set.
         lens_references_adt_enable: bool = false,
-        /// Whether to show `References` lens for Enum Variants.
-        /// Only applies when `#rust-analyzer.lens.enable#` is set.
-        lens_references_enumVariant_enable: bool = false,
-        /// Whether to show `Method References` lens. Only applies when
+
+        /// Show `References` lens for Enum Variants. Only applies when
         /// `#rust-analyzer.lens.enable#` is set.
+        lens_references_enumVariant_enable: bool = false,
+
+        /// Show `Method References` lens. Only applies when `#rust-analyzer.lens.enable#` is set.
         lens_references_method_enable: bool = false,
-        /// Whether to show `References` lens for Trait.
-        /// Only applies when `#rust-analyzer.lens.enable#` is set.
+
+        /// Show `References` lens for Trait. Only applies when `#rust-analyzer.lens.enable#` is
+        /// set.
         lens_references_trait_enable: bool = false,
-        /// Whether to show `Run` lens. Only applies when
-        /// `#rust-analyzer.lens.enable#` is set.
-        lens_run_enable: bool              = true,
-        /// Whether to show `Update Test` lens. Only applies when
-        /// `#rust-analyzer.lens.enable#` and `#rust-analyzer.lens.run.enable#` are set.
+
+        /// Show `Run` lens. Only applies when `#rust-analyzer.lens.enable#` is set.
+        lens_run_enable: bool = true,
+
+        /// Show `Update Test` lens. Only applies when `#rust-analyzer.lens.enable#` and
+        /// `#rust-analyzer.lens.run.enable#` are set.
         lens_updateTest_enable: bool = true,
 
-        /// Disable project auto-discovery in favor of explicitly specified set
-        /// of projects.
+        /// 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.
+        /// 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.
         linkedProjects: Vec<ManifestOrProjectJson> = vec![],
 
         /// Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
-        lru_capacity: Option<u16>                 = None,
-        /// Sets the LRU capacity of the specified queries.
+        lru_capacity: Option<u16> = None,
+
+        /// The LRU capacity of the specified queries.
         lru_query_capacities: FxHashMap<Box<str>, u16> = FxHashMap::default(),
 
-        /// Whether to show `can't find Cargo.toml` error message.
-        notifications_cargoTomlNotFound: bool      = true,
+        /// Show `can't find Cargo.toml` error message.
+        notifications_cargoTomlNotFound: bool = true,
 
-        /// How many worker threads in the main loop. The default `null` means to pick automatically.
+        /// The number of worker threads in the main loop. The default `null` means to pick
+        /// automatically.
         numThreads: Option<NumThreads> = None,
 
         /// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.
         procMacro_attributes_enable: bool = true,
+
         /// Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`.
-        procMacro_enable: bool                     = true,
+        procMacro_enable: bool = true,
+
         /// Internal config, path to proc-macro server executable.
-        procMacro_server: Option<Utf8PathBuf>          = None,
+        procMacro_server: Option<Utf8PathBuf> = None,
 
         /// Exclude imports from find-all-references.
         references_excludeImports: bool = false,
@@ -300,31 +379,41 @@ config_data! {
         /// When enabled, rust-analyzer will highlight rust source in doc comments as well as intra
         /// doc links.
         semanticHighlighting_doc_comment_inject_enable: bool = true,
-        /// Whether the server is allowed to emit non-standard tokens and modifiers.
+
+        /// Emit non-standard tokens and modifiers
+        ///
+        /// When enabled, rust-analyzer will emit tokens and modifiers that are not part of the
+        /// standard set of semantic tokens.
         semanticHighlighting_nonStandardTokens: bool = true,
+
         /// Use semantic tokens for operators.
         ///
         /// When disabled, rust-analyzer will emit semantic tokens only for operator tokens when
         /// they are tagged with modifiers.
         semanticHighlighting_operator_enable: bool = true,
+
         /// 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.
         semanticHighlighting_operator_specialization_enable: bool = 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.
         semanticHighlighting_punctuation_enable: bool = false,
+
         /// When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro
         /// calls.
         semanticHighlighting_punctuation_separate_macro_bang: bool = 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.
         semanticHighlighting_punctuation_specialization_enable: bool = false,
+
         /// Use semantic tokens for strings.
         ///
         /// In some editors (e.g. vscode) semantic tokens override other highlighting grammars.
@@ -333,16 +422,21 @@ config_data! {
         semanticHighlighting_strings_enable: bool = true,
 
         /// Show full signature of the callable. Only shows parameters if disabled.
-        signatureInfo_detail: SignatureDetail                           = SignatureDetail::Full,
+        signatureInfo_detail: SignatureDetail = SignatureDetail::Full,
+
         /// Show documentation.
-        signatureInfo_documentation_enable: bool                       = true,
+        signatureInfo_documentation_enable: bool = true,
 
         /// 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 `=` 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 `=` 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 `{` 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.
@@ -374,8 +468,8 @@ config_data! {
         ///
         /// **Warning**: This format is provisional and subject to change.
         ///
-        /// [`DiscoverWorkspaceConfig::command`] *must* return a JSON object
-        /// corresponding to `DiscoverProjectData::Finished`:
+        /// [`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to
+        /// `DiscoverProjectData::Finished`:
         ///
         /// ```norun
         /// #[derive(Debug, Clone, Deserialize, Serialize)]
@@ -405,12 +499,11 @@ config_data! {
         /// }
         /// ```
         ///
-        /// It is encouraged, but not required, to use the other variants on
-        /// `DiscoverProjectData` to provide a more polished end-user experience.
+        /// 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:
+        /// `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)]
@@ -437,11 +530,10 @@ config_data! {
         /// }
         /// ```
         ///
-        /// `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.
+        /// `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.
         workspace_discoverConfig: Option<DiscoverWorkspaceConfig> = None,
     }
 }
@@ -449,109 +541,154 @@ config_data! {
 config_data! {
     /// Local configurations can be defined per `SourceRoot`. This almost always corresponds to a `Crate`.
     local: struct LocalDefaultConfigData <- LocalConfigInput ->  {
-        /// Whether to insert #[must_use] when generating `as_` methods
-        /// for enum variants.
-        assist_emitMustUse: bool               = false,
+        /// Insert #[must_use] when generating `as_` methods for enum variants.
+        assist_emitMustUse: bool = false,
+
         /// Placeholder expression to use for missing expressions in assists.
-        assist_expressionFillDefault: ExprFillDefaultDef              = ExprFillDefaultDef::Todo,
-        /// When inserting a type (e.g. in "fill match arms" assist), prefer to use `Self` over the type name where possible.
+        assist_expressionFillDefault: ExprFillDefaultDef = ExprFillDefaultDef::Todo,
+
+        /// Prefer to use `Self` over the type name when inserting a type (e.g. in "fill match arms" assist).
         assist_preferSelf: bool = false,
-        /// 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.
+
+        /// 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.
         assist_termSearch_borrowcheck: bool = true,
+
         /// Term search fuel in "units of work" for assists (Defaults to 1800).
         assist_termSearch_fuel: usize = 1800,
 
-
-        /// Whether to automatically add a semicolon when completing unit-returning functions.
+        /// Automatically add a semicolon when completing unit-returning functions.
         ///
         /// In `match` arms it completes a comma instead.
         completion_addSemicolonToUnit: bool = true,
-        /// Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.
-        completion_autoAwait_enable: bool        = 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.
-        completion_autoIter_enable: bool        = 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.
-        completion_autoimport_enable: bool       = true,
+
+        /// Show method calls and field accesses completions with `await` prefixed to them when
+        /// completing on a future.
+        completion_autoAwait_enable: bool = true,
+
+        /// Show method call completions with `iter()` or `into_iter()` prefixed to them when
+        /// completing on a type that has them.
+        completion_autoIter_enable: bool = true,
+
+        /// Show completions that automatically add imports when completed.
+        ///
+        /// Note that your client must specify the `additionalTextEdits` LSP client capability to
+        /// truly have this feature enabled.
+        completion_autoimport_enable: bool = true,
+
         /// 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" }`.
+        /// 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.
+        /// 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#`.
         completion_autoimport_exclude: Vec<AutoImportExclusion> = vec![
             AutoImportExclusion::Verbose { path: "core::borrow::Borrow".to_owned(), r#type: AutoImportExclusionType::Methods },
             AutoImportExclusion::Verbose { path: "core::borrow::BorrowMut".to_owned(), r#type: AutoImportExclusionType::Methods },
         ],
-        /// Toggles the additional completions that automatically show method calls and field accesses
-        /// with `self` prefixed to them when inside a method.
-        completion_autoself_enable: bool        = true,
-        /// Whether to add parenthesis and argument snippets when completing function.
-        completion_callable_snippets: CallableCompletionDef  = CallableCompletionDef::FillArguments,
+
+        /// Show method calls and field access completions with `self` prefixed to them when
+        /// inside a method.
+        completion_autoself_enable: bool = true,
+
+        /// Add parenthesis and argument snippets when completing function.
+        completion_callable_snippets: CallableCompletionDef = CallableCompletionDef::FillArguments,
+
         /// 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`.
+        /// 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.
         completion_excludeTraits: Vec<String> = Vec::new(),
-        /// Whether to show full function/method signatures in completion docs.
+
+        /// Show full function / method signatures in completion docs.
         completion_fullFunctionSignatures_enable: bool = false,
-        /// Whether to omit deprecated items from autocompletion. By default they are marked as deprecated but not hidden.
+
+        /// Omit deprecated items from completions. By default they are marked as deprecated but not
+        /// hidden.
         completion_hideDeprecated: bool = false,
+
         /// Maximum number of completions to return. If `None`, the limit is infinite.
         completion_limit: Option<usize> = None,
-        /// Whether to show postfix snippets like `dbg`, `if`, `not`, etc.
-        completion_postfix_enable: bool         = true,
-        /// Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position.
+
+        /// Show postfix snippets like `dbg`, `if`, `not`, etc.
+        completion_postfix_enable: bool = true,
+
+        /// Show completions of private items and fields that are defined in the current workspace
+        /// even if they are not visible at the current position.
         completion_privateEditable_enable: bool = false,
-        /// Whether to enable term search based snippets like `Some(foo.bar().baz())`.
+
+        /// Enable term search based snippets like `Some(foo.bar().baz())`.
         completion_termSearch_enable: bool = false,
+
         /// Term search fuel in "units of work" for autocompletion (Defaults to 1000).
         completion_termSearch_fuel: usize = 1000,
 
         /// List of rust-analyzer diagnostics to disable.
         diagnostics_disabled: FxHashSet<String> = FxHashSet::default(),
-        /// Whether to show native rust-analyzer diagnostics.
-        diagnostics_enable: bool                = true,
-        /// Whether to show experimental rust-analyzer diagnostics that might
-        /// have more false positives than usual.
-        diagnostics_experimental_enable: bool    = false,
-        /// 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`.
+
+        /// Show native rust-analyzer diagnostics.
+        diagnostics_enable: bool = true,
+
+        /// Show experimental rust-analyzer diagnostics that might have more false positives than
+        /// usual.
+        diagnostics_experimental_enable: bool = false,
+
+        /// 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`.
         diagnostics_remapPrefix: FxHashMap<String, String> = FxHashMap::default(),
-        /// Whether to run additional style lints.
-        diagnostics_styleLints_enable: bool =    false,
+
+        /// Run additional style lints.
+        diagnostics_styleLints_enable: bool = false,
+
         /// 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`.
+        /// The warnings will be indicated by faded text or three dots in code and will not show up
+        /// in the `Problems Panel`.
         diagnostics_warningsAsHint: Vec<String> = vec![],
+
         /// 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`.
+        /// The warnings will be indicated by a blue squiggly underline in code and a blue icon in
+        /// the `Problems Panel`.
         diagnostics_warningsAsInfo: Vec<String> = vec![],
 
-        /// 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.
-        imports_granularity_enforce: bool              = false,
+        /// Enforce the import granularity setting for all files. If set to false rust-analyzer will
+        /// try to keep import styles consistent per file.
+        imports_granularity_enforce: bool = false,
+
         /// How imports should be grouped into use statements.
-        imports_granularity_group: ImportGranularityDef  = ImportGranularityDef::Crate,
-        /// Group inserted imports by the [following order](https://rust-analyzer.github.io/book/features.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,
+        imports_granularity_group: ImportGranularityDef = ImportGranularityDef::Crate,
+
+        /// Group inserted imports by the [following
+        /// order](https://rust-analyzer.github.io/book/features.html#auto-import). Groups are
+        /// separated by newlines.
+        imports_group_enable: bool = true,
+
+        /// Allow import insertion to merge new imports into single path glob imports like `use
+        /// std::fmt::*;`.
+        imports_merge_glob: bool = true,
+
         /// Prefer to unconditionally use imports of the core and alloc crate, over the std crate.
         imports_preferNoStd | imports_prefer_no_std: bool = false,
-         /// Whether to prefer import paths containing a `prelude` module.
-        imports_preferPrelude: bool                       = false,
+
+        /// Prefer import paths containing a `prelude` module.
+        imports_preferPrelude: bool = false,
+
         /// The path structure for newly inserted paths to use.
-        imports_prefix: ImportPrefixDef               = ImportPrefixDef::ByCrate,
-        /// Whether to prefix external (including std, core) crate imports with `::`. e.g. "use ::std::io::Read;".
+        imports_prefix: ImportPrefixDef = ImportPrefixDef::ByCrate,
+
+        /// Prefix external (including std, core) crate imports with `::`.
+        ///
+        /// E.g. `use ::std::io::Read;`.
         imports_prefixExternPrelude: bool = false,
     }
 }
@@ -589,7 +726,9 @@ config_data! {
         /// ```bash
         /// cargo check --quiet --workspace --message-format=json --all-targets --keep-going
         /// ```
-        /// .
+        ///
+        /// Note: The option must be specified as an array of command line arguments, with
+        /// the first argument being the name of the command to run.
         cargo_buildScripts_overrideCommand: Option<Vec<String>> = None,
         /// Rerun proc-macros building/build-scripts running when proc-macro
         /// or build-script sources change and are saved.
@@ -703,7 +842,9 @@ config_data! {
         /// ```bash
         /// cargo check --workspace --message-format=json --all-targets
         /// ```
-        /// .
+        ///
+        /// Note: The option must be specified as an array of command line arguments, with
+        /// the first argument being the name of the command to run.
         check_overrideCommand | checkOnSave_overrideCommand: Option<Vec<String>>             = None,
         /// Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.
         ///
@@ -753,6 +894,9 @@ config_data! {
         /// 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.
+        ///
+        /// Note: The option must be specified as an array of command line arguments, with
+        /// the first argument being the name of the command to run.
         rustfmt_overrideCommand: Option<Vec<String>> = None,
         /// Enables the use of rustfmt's unstable range formatting command for the
         /// `textDocument/rangeFormatting` request. The rustfmt option is unstable and only
@@ -3201,8 +3345,10 @@ fn schema(fields: &[SchemaField]) -> serde_json::Value {
         .iter()
         .map(|(field, ty, doc, default)| {
             let name = field.replace('_', ".");
-            let category =
-                name.find('.').map(|end| String::from(&name[..end])).unwrap_or("general".into());
+            let category = name
+                .split_once(".")
+                .map(|(category, _name)| to_title_case(category))
+                .unwrap_or("rust-analyzer".into());
             let name = format!("rust-analyzer.{name}");
             let props = field_props(field, ty, doc, default);
             serde_json::json!({
@@ -3216,6 +3362,29 @@ fn schema(fields: &[SchemaField]) -> serde_json::Value {
     map.into()
 }
 
+/// Translate a field name to a title case string suitable for use in the category names on the
+/// vscode settings page.
+///
+/// First letter of word should be uppercase, if an uppercase letter is encountered, add a space
+/// before it e.g. "fooBar" -> "Foo Bar", "fooBarBaz" -> "Foo Bar Baz", "foo" -> "Foo"
+///
+/// This likely should be in stdx (or just use heck instead), but it doesn't handle any edge cases
+/// and is intentionally simple.
+fn to_title_case(s: &str) -> String {
+    let mut result = String::with_capacity(s.len());
+    let mut chars = s.chars();
+    if let Some(first) = chars.next() {
+        result.push(first.to_ascii_uppercase());
+        for c in chars {
+            if c.is_uppercase() {
+                result.push(' ');
+            }
+            result.push(c);
+        }
+    }
+    result
+}
+
 fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json::Value {
     let doc = doc_comment_to_string(doc);
     let doc = doc.trim_end_matches('\n');
@@ -3742,17 +3911,16 @@ mod tests {
         for idx in url_offsets {
             let link = &schema[idx..];
             // matching on whitespace to ignore normal links
-            if let Some(link_end) = link.find([' ', '[']) {
-                if link.chars().nth(link_end) == Some('[') {
-                    if let Some(link_text_end) = link.find(']') {
-                        let link_text = link[link_end..(link_text_end + 1)].to_string();
-
-                        schema.replace_range((idx + link_end)..(idx + link_text_end + 1), "");
-                        schema.insert(idx, '(');
-                        schema.insert(idx + link_end + 1, ')');
-                        schema.insert_str(idx, &link_text);
-                    }
-                }
+            if let Some(link_end) = link.find([' ', '['])
+                && link.chars().nth(link_end) == Some('[')
+                && let Some(link_text_end) = link.find(']')
+            {
+                let link_text = link[link_end..(link_text_end + 1)].to_string();
+
+                schema.replace_range((idx + link_end)..(idx + link_text_end + 1), "");
+                schema.insert(idx, '(');
+                schema.insert(idx + link_end + 1, ')');
+                schema.insert_str(idx, &link_text);
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs
index 95857dd8f3b..389bb7848c0 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs
@@ -73,19 +73,19 @@ pub(super) fn patch_json_for_outdated_configs(json: &mut Value) {
     }
 
     // completion.snippets -> completion.snippets.custom;
-    if let Some(Value::Object(obj)) = copy.pointer("/completion/snippets").cloned() {
-        if obj.len() != 1 || obj.get("custom").is_none() {
-            merge(
-                json,
-                json! {{
-                    "completion": {
-                        "snippets": {
-                            "custom": obj
-                        },
+    if let Some(Value::Object(obj)) = copy.pointer("/completion/snippets").cloned()
+        && (obj.len() != 1 || obj.get("custom").is_none())
+    {
+        merge(
+            json,
+            json! {{
+                "completion": {
+                    "snippets": {
+                        "custom": obj
                     },
-                }},
-            );
-        }
+                },
+            }},
+        );
     }
 
     // callInfo_full -> signatureInfo_detail, signatureInfo_documentation_enable
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
index 79d8f678de4..3f64628de86 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -298,10 +298,10 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
     let mut source = String::from("rustc");
     let mut code = rd.code.as_ref().map(|c| c.code.clone());
 
-    if let Some(code_val) = &code {
-        if config.check_ignore.contains(code_val) {
-            return Vec::new();
-        }
+    if let Some(code_val) = &code
+        && config.check_ignore.contains(code_val)
+    {
+        return Vec::new();
     }
 
     if let Some(code_val) = &code {
@@ -373,10 +373,8 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
             let primary_location = primary_location(config, workspace_root, primary_span, snap);
             let message = {
                 let mut message = message.clone();
-                if needs_primary_span_label {
-                    if let Some(primary_span_label) = &primary_span.label {
-                        format_to!(message, "\n{}", primary_span_label);
-                    }
+                if needs_primary_span_label && let Some(primary_span_label) = &primary_span.label {
+                    format_to!(message, "\n{}", primary_span_label);
                 }
                 message
             };
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
index 512ce0b9de3..e4e0bcdc1cd 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
@@ -492,12 +492,11 @@ impl FlycheckActor {
             FlycheckConfig::CargoCommand { command, options, ansi_color_output } => {
                 let mut cmd =
                     toolchain::command(Tool::Cargo.path(), &*self.root, &options.extra_env);
-                if let Some(sysroot_root) = &self.sysroot_root {
-                    if !options.extra_env.contains_key("RUSTUP_TOOLCHAIN")
-                        && std::env::var_os("RUSTUP_TOOLCHAIN").is_none()
-                    {
-                        cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(sysroot_root));
-                    }
+                if let Some(sysroot_root) = &self.sysroot_root
+                    && !options.extra_env.contains_key("RUSTUP_TOOLCHAIN")
+                    && std::env::var_os("RUSTUP_TOOLCHAIN").is_none()
+                {
+                    cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(sysroot_root));
                 }
                 cmd.arg(command);
 
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 62a28a1a685..2f1afba3634 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
@@ -448,7 +448,7 @@ impl GlobalState {
                     tracing::info!(%vfs_path, ?change_kind, "Processing rust-analyzer.toml changes");
                     if vfs_path.as_path() == user_config_abs_path {
                         tracing::info!(%vfs_path, ?change_kind, "Use config rust-analyzer.toml changes");
-                        change.change_user_config(Some(db.file_text(file_id).text(db)));
+                        change.change_user_config(Some(db.file_text(file_id).text(db).clone()));
                     }
 
                     // If change has been made to a ratoml file that
@@ -462,14 +462,14 @@ impl GlobalState {
                             change.change_workspace_ratoml(
                                 source_root_id,
                                 vfs_path.clone(),
-                                Some(db.file_text(file_id).text(db)),
+                                Some(db.file_text(file_id).text(db).clone()),
                             )
                         } else {
                             tracing::info!(%vfs_path, ?source_root_id, "crate rust-analyzer.toml changes");
                             change.change_ratoml(
                                 source_root_id,
                                 vfs_path.clone(),
-                                Some(db.file_text(file_id).text(db)),
+                                Some(db.file_text(file_id).text(db).clone()),
                             )
                         };
 
@@ -591,10 +591,10 @@ impl GlobalState {
 
     pub(crate) fn respond(&mut self, response: lsp_server::Response) {
         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));
-                }
+            if let Some(err) = &response.error
+                && err.message.starts_with("server panicked")
+            {
+                self.poke_rust_analyzer_developer(format!("{}, check the log", err.message));
             }
 
             let duration = start.elapsed();
@@ -663,18 +663,18 @@ impl GlobalState {
 
     pub(crate) fn check_workspaces_msrv(&self) -> impl Iterator<Item = String> + '_ {
         self.workspaces.iter().filter_map(|ws| {
-            if let Some(toolchain) = &ws.toolchain {
-                if *toolchain < crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION {
-                    return Some(format!(
-                        "Workspace `{}` is using an outdated toolchain version `{}` but \
+            if let Some(toolchain) = &ws.toolchain
+                && *toolchain < crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION
+            {
+                return Some(format!(
+                    "Workspace `{}` is using an outdated toolchain version `{}` but \
                         rust-analyzer only supports `{}` and higher.\n\
                         Consider using the rust-analyzer rustup component for your toolchain or
                         upgrade your toolchain to a supported version.\n\n",
-                        ws.manifest_or_root(),
-                        toolchain,
-                        crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION,
-                    ));
-                }
+                    ws.manifest_or_root(),
+                    toolchain,
+                    crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION,
+                ));
             }
             None
         })
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 aea116e647d..b25245dd884 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
@@ -433,10 +433,10 @@ impl NotificationDispatcher<'_> {
     }
 
     pub(crate) fn finish(&mut self) {
-        if let Some(not) = &self.not {
-            if !not.method.starts_with("$/") {
-                tracing::error!("unhandled notification: {:?}", not);
-            }
+        if let Some(not) = &self.not
+            && !not.method.starts_with("$/")
+        {
+            tracing::error!("unhandled notification: {:?}", not);
         }
     }
 }
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 200e972e428..e193ff77743 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
@@ -39,14 +39,12 @@ pub(crate) fn handle_work_done_progress_cancel(
     state: &mut GlobalState,
     params: WorkDoneProgressCancelParams,
 ) -> anyhow::Result<()> {
-    if let lsp_types::NumberOrString::String(s) = &params.token {
-        if let Some(id) = s.strip_prefix("rust-analyzer/flycheck/") {
-            if let Ok(id) = id.parse::<u32>() {
-                if let Some(flycheck) = state.flycheck.get(id as usize) {
-                    flycheck.cancel();
-                }
-            }
-        }
+    if let lsp_types::NumberOrString::String(s) = &params.token
+        && let Some(id) = s.strip_prefix("rust-analyzer/flycheck/")
+        && let Ok(id) = id.parse::<u32>()
+        && let Some(flycheck) = state.flycheck.get(id as usize)
+    {
+        flycheck.cancel();
     }
 
     // Just ignore this. It is OK to continue sending progress
@@ -76,12 +74,12 @@ pub(crate) fn handle_did_open_text_document(
             tracing::error!("duplicate DidOpenTextDocument: {}", path);
         }
 
-        if let Some(abs_path) = path.as_path() {
-            if state.config.excluded().any(|excluded| abs_path.starts_with(&excluded)) {
-                tracing::trace!("opened excluded file {abs_path}");
-                state.vfs.write().0.insert_excluded_file(path);
-                return Ok(());
-            }
+        if let Some(abs_path) = path.as_path()
+            && state.config.excluded().any(|excluded| abs_path.starts_with(&excluded))
+        {
+            tracing::trace!("opened excluded file {abs_path}");
+            state.vfs.write().0.insert_excluded_file(path);
+            return Ok(());
         }
 
         let contents = params.text_document.text.into_bytes();
@@ -449,12 +447,11 @@ pub(crate) fn handle_run_flycheck(
     params: RunFlycheckParams,
 ) -> anyhow::Result<()> {
     let _p = tracing::info_span!("handle_run_flycheck").entered();
-    if let Some(text_document) = params.text_document {
-        if let Ok(vfs_path) = from_proto::vfs_path(&text_document.uri) {
-            if run_flycheck(state, vfs_path) {
-                return Ok(());
-            }
-        }
+    if let Some(text_document) = params.text_document
+        && let Ok(vfs_path) = from_proto::vfs_path(&text_document.uri)
+        && run_flycheck(state, vfs_path)
+    {
+        return Ok(());
     }
     // No specific flycheck was triggered, so let's trigger all of them.
     if state.config.flycheck_workspace(None) {
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 a76a65220d3..25c0aac405e 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
@@ -973,14 +973,13 @@ pub(crate) fn handle_runnables(
                 res.push(runnable);
             }
 
-            if let lsp_ext::RunnableArgs::Cargo(r) = &mut runnable.args {
-                if let Some(TargetSpec::Cargo(CargoTargetSpec {
+            if let lsp_ext::RunnableArgs::Cargo(r) = &mut runnable.args
+                && let Some(TargetSpec::Cargo(CargoTargetSpec {
                     sysroot_root: Some(sysroot_root),
                     ..
                 })) = &target_spec
-                {
-                    r.environment.insert("RUSTC_TOOLCHAIN".to_owned(), sysroot_root.to_string());
-                }
+            {
+                r.environment.insert("RUSTC_TOOLCHAIN".to_owned(), sysroot_root.to_string());
             };
 
             res.push(runnable);
@@ -1034,25 +1033,25 @@ pub(crate) fn handle_runnables(
         }
         Some(TargetSpec::ProjectJson(_)) => {}
         None => {
-            if !snap.config.linked_or_discovered_projects().is_empty() {
-                if let Some(path) = snap.file_id_to_file_path(file_id).parent() {
-                    let mut cargo_args = vec!["check".to_owned(), "--workspace".to_owned()];
-                    cargo_args.extend(config.cargo_extra_args.iter().cloned());
-                    res.push(lsp_ext::Runnable {
-                        label: "cargo check --workspace".to_owned(),
-                        location: None,
-                        kind: lsp_ext::RunnableKind::Cargo,
-                        args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
-                            workspace_root: None,
-                            cwd: path.as_path().unwrap().to_path_buf().into(),
-                            override_cargo: config.override_cargo,
-                            cargo_args,
-                            executable_args: Vec::new(),
-                            environment: Default::default(),
-                        }),
-                    });
-                };
-            }
+            if !snap.config.linked_or_discovered_projects().is_empty()
+                && let Some(path) = snap.file_id_to_file_path(file_id).parent()
+            {
+                let mut cargo_args = vec!["check".to_owned(), "--workspace".to_owned()];
+                cargo_args.extend(config.cargo_extra_args.iter().cloned());
+                res.push(lsp_ext::Runnable {
+                    label: "cargo check --workspace".to_owned(),
+                    location: None,
+                    kind: lsp_ext::RunnableKind::Cargo,
+                    args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
+                        workspace_root: None,
+                        cwd: path.as_path().unwrap().to_path_buf().into(),
+                        override_cargo: config.override_cargo,
+                        cargo_args,
+                        executable_args: Vec::new(),
+                        environment: Default::default(),
+                    }),
+                });
+            };
         }
     }
     Ok(res)
@@ -1557,12 +1556,12 @@ pub(crate) fn handle_code_action_resolve(
     code_action.edit = ca.edit;
     code_action.command = ca.command;
 
-    if let Some(edit) = code_action.edit.as_ref() {
-        if let Some(changes) = edit.document_changes.as_ref() {
-            for change in changes {
-                if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change {
-                    resource_ops_supported(&snap.config, resolve_resource_op(res_op))?
-                }
+    if let Some(edit) = code_action.edit.as_ref()
+        && let Some(changes) = edit.document_changes.as_ref()
+    {
+        for change in changes {
+            if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change {
+                resource_ops_supported(&snap.config, resolve_resource_op(res_op))?
             }
         }
     }
@@ -1958,12 +1957,11 @@ pub(crate) fn handle_semantic_tokens_full_delta(
 
     if let Some(cached_tokens @ lsp_types::SemanticTokens { result_id: Some(prev_id), .. }) =
         &cached_tokens
+        && *prev_id == params.previous_result_id
     {
-        if *prev_id == params.previous_result_id {
-            let delta = to_proto::semantic_token_delta(cached_tokens, &semantic_tokens);
-            snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens);
-            return Ok(Some(delta.into()));
-        }
+        let delta = to_proto::semantic_token_delta(cached_tokens, &semantic_tokens);
+        snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens);
+        return Ok(Some(delta.into()));
     }
 
     // Clone first to keep the lock short
@@ -2122,24 +2120,25 @@ fn show_impl_command_link(
     snap: &GlobalStateSnapshot,
     position: &FilePosition,
 ) -> Option<lsp_ext::CommandLinkGroup> {
-    if snap.config.hover_actions().implementations && snap.config.client_commands().show_reference {
-        if let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None) {
-            let uri = to_proto::url(snap, position.file_id);
-            let line_index = snap.file_line_index(position.file_id).ok()?;
-            let position = to_proto::position(&line_index, position.offset);
-            let locations: Vec<_> = nav_data
-                .info
-                .into_iter()
-                .filter_map(|nav| to_proto::location_from_nav(snap, nav).ok())
-                .collect();
-            let title = to_proto::implementation_title(locations.len());
-            let command = to_proto::command::show_references(title, &uri, position, locations);
-
-            return Some(lsp_ext::CommandLinkGroup {
-                commands: vec![to_command_link(command, "Go to implementations".into())],
-                ..Default::default()
-            });
-        }
+    if snap.config.hover_actions().implementations
+        && snap.config.client_commands().show_reference
+        && let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None)
+    {
+        let uri = to_proto::url(snap, position.file_id);
+        let line_index = snap.file_line_index(position.file_id).ok()?;
+        let position = to_proto::position(&line_index, position.offset);
+        let locations: Vec<_> = nav_data
+            .info
+            .into_iter()
+            .filter_map(|nav| to_proto::location_from_nav(snap, nav).ok())
+            .collect();
+        let title = to_proto::implementation_title(locations.len());
+        let command = to_proto::command::show_references(title, &uri, position, locations);
+
+        return Some(lsp_ext::CommandLinkGroup {
+            commands: vec![to_command_link(command, "Go to implementations".into())],
+            ..Default::default()
+        });
     }
     None
 }
@@ -2148,28 +2147,29 @@ fn show_ref_command_link(
     snap: &GlobalStateSnapshot,
     position: &FilePosition,
 ) -> Option<lsp_ext::CommandLinkGroup> {
-    if snap.config.hover_actions().references && snap.config.client_commands().show_reference {
-        if let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None) {
-            let uri = to_proto::url(snap, position.file_id);
-            let line_index = snap.file_line_index(position.file_id).ok()?;
-            let position = to_proto::position(&line_index, position.offset);
-            let locations: Vec<_> = ref_search_res
-                .into_iter()
-                .flat_map(|res| res.references)
-                .flat_map(|(file_id, ranges)| {
-                    ranges.into_iter().map(move |(range, _)| FileRange { file_id, range })
-                })
-                .unique()
-                .filter_map(|range| to_proto::location(snap, range).ok())
-                .collect();
-            let title = to_proto::reference_title(locations.len());
-            let command = to_proto::command::show_references(title, &uri, position, locations);
-
-            return Some(lsp_ext::CommandLinkGroup {
-                commands: vec![to_command_link(command, "Go to references".into())],
-                ..Default::default()
-            });
-        }
+    if snap.config.hover_actions().references
+        && snap.config.client_commands().show_reference
+        && let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None)
+    {
+        let uri = to_proto::url(snap, position.file_id);
+        let line_index = snap.file_line_index(position.file_id).ok()?;
+        let position = to_proto::position(&line_index, position.offset);
+        let locations: Vec<_> = ref_search_res
+            .into_iter()
+            .flat_map(|res| res.references)
+            .flat_map(|(file_id, ranges)| {
+                ranges.into_iter().map(move |(range, _)| FileRange { file_id, range })
+            })
+            .unique()
+            .filter_map(|range| to_proto::location(snap, range).ok())
+            .collect();
+        let title = to_proto::reference_title(locations.len());
+        let command = to_proto::command::show_references(title, &uri, position, locations);
+
+        return Some(lsp_ext::CommandLinkGroup {
+            commands: vec![to_command_link(command, "Go to references".into())],
+            ..Default::default()
+        });
     }
     None
 }
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 00cf890510d..61c758d5e86 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
@@ -501,14 +501,12 @@ impl GlobalState {
             }
         }
 
-        if self.config.cargo_autoreload_config(None)
-            || self.config.discover_workspace_config().is_some()
-        {
-            if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) =
+        if (self.config.cargo_autoreload_config(None)
+            || self.config.discover_workspace_config().is_some())
+            && let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) =
                 self.fetch_workspaces_queue.should_start_op()
-            {
-                self.fetch_workspaces(cause, path, force_crate_graph_reload);
-            }
+        {
+            self.fetch_workspaces(cause, path, force_crate_graph_reload);
         }
 
         if !self.fetch_workspaces_queue.op_in_progress() {
@@ -765,33 +763,33 @@ impl GlobalState {
                 self.report_progress("Fetching", state, msg, None, None);
             }
             Task::DiscoverLinkedProjects(arg) => {
-                if let Some(cfg) = self.config.discover_workspace_config() {
-                    if !self.discover_workspace_queue.op_in_progress() {
-                        // the clone is unfortunately necessary to avoid a borrowck error when
-                        // `self.report_progress` is called later
-                        let title = &cfg.progress_label.clone();
-                        let command = cfg.command.clone();
-                        let discover = DiscoverCommand::new(self.discover_sender.clone(), command);
-
-                        self.report_progress(title, Progress::Begin, None, None, None);
-                        self.discover_workspace_queue
-                            .request_op("Discovering workspace".to_owned(), ());
-                        let _ = self.discover_workspace_queue.should_start_op();
-
-                        let arg = match arg {
-                            DiscoverProjectParam::Buildfile(it) => DiscoverArgument::Buildfile(it),
-                            DiscoverProjectParam::Path(it) => DiscoverArgument::Path(it),
-                        };
+                if let Some(cfg) = self.config.discover_workspace_config()
+                    && !self.discover_workspace_queue.op_in_progress()
+                {
+                    // the clone is unfortunately necessary to avoid a borrowck error when
+                    // `self.report_progress` is called later
+                    let title = &cfg.progress_label.clone();
+                    let command = cfg.command.clone();
+                    let discover = DiscoverCommand::new(self.discover_sender.clone(), command);
+
+                    self.report_progress(title, Progress::Begin, None, None, None);
+                    self.discover_workspace_queue
+                        .request_op("Discovering workspace".to_owned(), ());
+                    let _ = self.discover_workspace_queue.should_start_op();
+
+                    let arg = match arg {
+                        DiscoverProjectParam::Buildfile(it) => DiscoverArgument::Buildfile(it),
+                        DiscoverProjectParam::Path(it) => DiscoverArgument::Path(it),
+                    };
 
-                        let handle = discover.spawn(
-                            arg,
-                            &std::env::current_dir()
-                                .expect("Failed to get cwd during project discovery"),
-                        );
-                        self.discover_handle = Some(handle.unwrap_or_else(|e| {
-                            panic!("Failed to spawn project discovery command: {e}")
-                        }));
-                    }
+                    let handle = discover.spawn(
+                        arg,
+                        &std::env::current_dir()
+                            .expect("Failed to get cwd during project discovery"),
+                    );
+                    self.discover_handle = Some(handle.unwrap_or_else(|e| {
+                        panic!("Failed to spawn project discovery command: {e}")
+                    }));
                 }
             }
             Task::FetchBuildData(progress) => {
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 e798aa6a8a6..aa38aa72d44 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -306,13 +306,13 @@ impl GlobalState {
                         _ => None,
                     });
 
-                    if let Some(build) = build {
-                        if is_quiescent {
-                            let path = AbsPathBuf::try_from(build.build_file)
-                                .expect("Unable to convert to an AbsPath");
-                            let arg = DiscoverProjectParam::Buildfile(path);
-                            sender.send(Task::DiscoverLinkedProjects(arg)).unwrap();
-                        }
+                    if let Some(build) = build
+                        && is_quiescent
+                    {
+                        let path = AbsPathBuf::try_from(build.build_file)
+                            .expect("Unable to convert to an AbsPath");
+                        let arg = DiscoverProjectParam::Buildfile(path);
+                        sender.send(Task::DiscoverLinkedProjects(arg)).unwrap();
                     }
                 }
 
diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs
index b81d08eed6d..ae9e038459e 100644
--- a/src/tools/rust-analyzer/crates/span/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/span/src/lib.rs
@@ -203,15 +203,3 @@ pub struct HirFileId(pub salsa::Id);
 /// `println!("Hello, {}", world)`.
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct MacroCallId(pub salsa::Id);
-
-/// Legacy span type, only defined here as it is still used by the proc-macro server.
-/// While rust-analyzer doesn't use this anymore at all, RustRover relies on the legacy type for
-/// proc-macro expansion.
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
-pub struct TokenId(pub u32);
-
-impl std::fmt::Debug for TokenId {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        self.0.fmt(f)
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/span/src/map.rs b/src/tools/rust-analyzer/crates/span/src/map.rs
index f58201793da..bb09933536e 100644
--- a/src/tools/rust-analyzer/crates/span/src/map.rs
+++ b/src/tools/rust-analyzer/crates/span/src/map.rs
@@ -41,13 +41,13 @@ where
 
     /// Pushes a new span onto the [`SpanMap`].
     pub fn push(&mut self, offset: TextSize, span: SpanData<S>) {
-        if cfg!(debug_assertions) {
-            if let Some(&(last_offset, _)) = self.spans.last() {
-                assert!(
-                    last_offset < offset,
-                    "last_offset({last_offset:?}) must be smaller than offset({offset:?})"
-                );
-            }
+        if cfg!(debug_assertions)
+            && let Some(&(last_offset, _)) = self.spans.last()
+        {
+            assert!(
+                last_offset < offset,
+                "last_offset({last_offset:?}) must be smaller than offset({offset:?})"
+            );
         }
         self.spans.push((offset, span));
     }
diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs
index d59229952f5..bdff671802c 100644
--- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs
@@ -768,17 +768,17 @@ where
     }
 
     fn bump(&mut self) -> Option<(Self::Token, TextRange)> {
-        if let Some((punct, offset)) = self.punct_offset.clone() {
-            if usize::from(offset) + 1 < punct.text().len() {
-                let offset = offset + TextSize::of('.');
-                let range = punct.text_range();
-                self.punct_offset = Some((punct.clone(), offset));
-                let range = TextRange::at(range.start() + offset, TextSize::of('.'));
-                return Some((
-                    SynToken::Punct { token: punct, offset: u32::from(offset) as usize },
-                    range,
-                ));
-            }
+        if let Some((punct, offset)) = self.punct_offset.clone()
+            && usize::from(offset) + 1 < punct.text().len()
+        {
+            let offset = offset + TextSize::of('.');
+            let range = punct.text_range();
+            self.punct_offset = Some((punct.clone(), offset));
+            let range = TextRange::at(range.start() + offset, TextSize::of('.'));
+            return Some((
+                SynToken::Punct { token: punct, offset: u32::from(offset) as usize },
+                range,
+            ));
         }
 
         if let Some(leaf) = self.current_leaves.pop() {
diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/prettify_macro_expansion.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/prettify_macro_expansion.rs
index 0a5c8df0d0a..2f932e04583 100644
--- a/src/tools/rust-analyzer/crates/syntax-bridge/src/prettify_macro_expansion.rs
+++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/prettify_macro_expansion.rs
@@ -61,10 +61,11 @@ pub fn prettify_macro_expansion(
             }
             _ => continue,
         };
-        if token.kind() == SyntaxKind::IDENT && token.text() == "$crate" {
-            if let Some(replacement) = dollar_crate_replacement(&token) {
-                dollar_crate_replacements.push((token.clone(), replacement));
-            }
+        if token.kind() == SyntaxKind::IDENT
+            && token.text() == "$crate"
+            && let Some(replacement) = dollar_crate_replacement(&token)
+        {
+            dollar_crate_replacements.push((token.clone(), replacement));
         }
         let tok = &token;
 
diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs
index 8871bf56a5d..c8dc3131b59 100644
--- a/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs
@@ -34,14 +34,11 @@ fn check_punct_spacing(fixture: &str) {
     while !cursor.eof() {
         while let Some(token_tree) = cursor.token_tree() {
             if let tt::TokenTree::Leaf(Leaf::Punct(Punct {
-                spacing,
-                span: Span { range, .. },
-                ..
+                spacing, span: Span { range, .. }, ..
             })) = token_tree
+                && let Some(expected) = annotations.remove(range)
             {
-                if let Some(expected) = annotations.remove(range) {
-                    assert_eq!(expected, *spacing);
-                }
+                assert_eq!(expected, *spacing);
             }
             cursor.bump();
         }
diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs
index 021dc6595f9..c0ff8e1db2c 100644
--- a/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs
+++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs
@@ -21,17 +21,17 @@ pub fn to_parser_input<Ctx: Copy + fmt::Debug + PartialEq + Eq + Hash>(
         let tt = current.token_tree();
 
         // Check if it is lifetime
-        if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = tt {
-            if punct.char == '\'' {
-                current.bump();
-                match current.token_tree() {
-                    Some(tt::TokenTree::Leaf(tt::Leaf::Ident(_ident))) => {
-                        res.push(LIFETIME_IDENT);
-                        current.bump();
-                        continue;
-                    }
-                    _ => panic!("Next token must be ident"),
+        if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = tt
+            && punct.char == '\''
+        {
+            current.bump();
+            match current.token_tree() {
+                Some(tt::TokenTree::Leaf(tt::Leaf::Ident(_ident))) => {
+                    res.push(LIFETIME_IDENT);
+                    current.bump();
+                    continue;
                 }
+                _ => panic!("Next token must be ident"),
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs
index d97fdec524f..9b30642fe4b 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs
@@ -89,11 +89,11 @@ impl IndentLevel {
             _ => None,
         });
         for token in tokens {
-            if let Some(ws) = ast::Whitespace::cast(token) {
-                if ws.text().contains('\n') {
-                    let new_ws = make::tokens::whitespace(&format!("{}{self}", ws.syntax()));
-                    ted::replace(ws.syntax(), &new_ws);
-                }
+            if let Some(ws) = ast::Whitespace::cast(token)
+                && ws.text().contains('\n')
+            {
+                let new_ws = make::tokens::whitespace(&format!("{}{self}", ws.syntax()));
+                ted::replace(ws.syntax(), &new_ws);
             }
         }
     }
@@ -122,13 +122,13 @@ impl IndentLevel {
             _ => None,
         });
         for token in tokens {
-            if let Some(ws) = ast::Whitespace::cast(token) {
-                if ws.text().contains('\n') {
-                    let new_ws = make::tokens::whitespace(
-                        &ws.syntax().text().replace(&format!("\n{self}"), "\n"),
-                    );
-                    ted::replace(ws.syntax(), &new_ws);
-                }
+            if let Some(ws) = ast::Whitespace::cast(token)
+                && ws.text().contains('\n')
+            {
+                let new_ws = make::tokens::whitespace(
+                    &ws.syntax().text().replace(&format!("\n{self}"), "\n"),
+                );
+                ted::replace(ws.syntax(), &new_ws);
             }
         }
     }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
index 28b543ea706..b50ce644243 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
@@ -9,11 +9,11 @@ use crate::{
     SyntaxKind::{ATTR, COMMENT, WHITESPACE},
     SyntaxNode, SyntaxToken,
     algo::{self, neighbor},
-    ast::{self, HasGenericArgs, HasGenericParams, edit::IndentLevel, make},
+    ast::{self, HasGenericParams, edit::IndentLevel, make},
     ted::{self, Position},
 };
 
-use super::{GenericParam, HasArgList, HasName};
+use super::{GenericParam, HasName};
 
 pub trait GenericParamsOwnerEdit: ast::HasGenericParams {
     fn get_or_create_generic_param_list(&self) -> ast::GenericParamList;
@@ -383,10 +383,10 @@ impl ast::GenericParamList {
 
 impl ast::WhereClause {
     pub fn add_predicate(&self, predicate: ast::WherePred) {
-        if let Some(pred) = self.predicates().last() {
-            if !pred.syntax().siblings_with_tokens(Direction::Next).any(|it| it.kind() == T![,]) {
-                ted::append_child_raw(self.syntax(), make::token(T![,]));
-            }
+        if let Some(pred) = self.predicates().last()
+            && !pred.syntax().siblings_with_tokens(Direction::Next).any(|it| it.kind() == T![,])
+        {
+            ted::append_child_raw(self.syntax(), make::token(T![,]));
         }
         ted::append_child(self.syntax(), predicate.syntax());
     }
@@ -419,34 +419,6 @@ impl Removable for ast::TypeBoundList {
     }
 }
 
-impl ast::PathSegment {
-    pub fn get_or_create_generic_arg_list(&self) -> ast::GenericArgList {
-        if self.generic_arg_list().is_none() {
-            let arg_list = make::generic_arg_list(empty()).clone_for_update();
-            ted::append_child(self.syntax(), arg_list.syntax());
-        }
-        self.generic_arg_list().unwrap()
-    }
-}
-
-impl ast::MethodCallExpr {
-    pub fn get_or_create_generic_arg_list(&self) -> ast::GenericArgList {
-        if self.generic_arg_list().is_none() {
-            let generic_arg_list = make::turbofish_generic_arg_list(empty()).clone_for_update();
-
-            if let Some(arg_list) = self.arg_list() {
-                ted::insert_raw(
-                    ted::Position::before(arg_list.syntax()),
-                    generic_arg_list.syntax(),
-                );
-            } else {
-                ted::append_child(self.syntax(), generic_arg_list.syntax());
-            }
-        }
-        self.generic_arg_list().unwrap()
-    }
-}
-
 impl Removable for ast::UseTree {
     fn remove(&self) {
         for dir in [Direction::Next, Direction::Prev] {
@@ -677,106 +649,6 @@ impl ast::AssocItemList {
         ];
         ted::insert_all(position, elements);
     }
-
-    /// Adds a new associated item at the start of the associated item list.
-    ///
-    /// Attention! This function does align the first line of `item` with respect to `self`,
-    /// but it does _not_ change indentation of other lines (if any).
-    pub fn add_item_at_start(&self, item: ast::AssocItem) {
-        match self.assoc_items().next() {
-            Some(first_item) => {
-                let indent = IndentLevel::from_node(first_item.syntax());
-                let before = Position::before(first_item.syntax());
-
-                ted::insert_all(
-                    before,
-                    vec![
-                        item.syntax().clone().into(),
-                        make::tokens::whitespace(&format!("\n\n{indent}")).into(),
-                    ],
-                )
-            }
-            None => {
-                let (indent, position, whitespace) = match self.l_curly_token() {
-                    Some(l_curly) => {
-                        normalize_ws_between_braces(self.syntax());
-                        (IndentLevel::from_token(&l_curly) + 1, Position::after(&l_curly), "\n")
-                    }
-                    None => (IndentLevel::single(), Position::first_child_of(self.syntax()), ""),
-                };
-
-                let mut elements = vec![];
-
-                // Avoid pushing an empty whitespace token
-                if !indent.is_zero() || !whitespace.is_empty() {
-                    elements.push(make::tokens::whitespace(&format!("{whitespace}{indent}")).into())
-                }
-                elements.push(item.syntax().clone().into());
-
-                ted::insert_all(position, elements)
-            }
-        };
-    }
-}
-
-impl ast::Fn {
-    pub fn get_or_create_body(&self) -> ast::BlockExpr {
-        if self.body().is_none() {
-            let body = make::ext::empty_block_expr().clone_for_update();
-            match self.semicolon_token() {
-                Some(semi) => {
-                    ted::replace(semi, body.syntax());
-                    ted::insert(Position::before(body.syntax), make::tokens::single_space());
-                }
-                None => ted::append_child(self.syntax(), body.syntax()),
-            }
-        }
-        self.body().unwrap()
-    }
-}
-
-impl ast::LetStmt {
-    pub fn set_ty(&self, ty: Option<ast::Type>) {
-        match ty {
-            None => {
-                if let Some(colon_token) = self.colon_token() {
-                    ted::remove(colon_token);
-                }
-
-                if let Some(existing_ty) = self.ty() {
-                    if let Some(sibling) = existing_ty.syntax().prev_sibling_or_token() {
-                        if sibling.kind() == SyntaxKind::WHITESPACE {
-                            ted::remove(sibling);
-                        }
-                    }
-
-                    ted::remove(existing_ty.syntax());
-                }
-
-                // Remove any trailing ws
-                if let Some(last) = self.syntax().last_token().filter(|it| it.kind() == WHITESPACE)
-                {
-                    last.detach();
-                }
-            }
-            Some(new_ty) => {
-                if self.colon_token().is_none() {
-                    ted::insert_raw(
-                        Position::after(
-                            self.pat().expect("let stmt should have a pattern").syntax(),
-                        ),
-                        make::token(T![:]),
-                    );
-                }
-
-                if let Some(old_ty) = self.ty() {
-                    ted::replace(old_ty.syntax(), new_ty.syntax());
-                } else {
-                    ted::insert(Position::after(self.colon_token().unwrap()), new_ty.syntax());
-                }
-            }
-        }
-    }
 }
 
 impl ast::RecordExprFieldList {
@@ -823,19 +695,18 @@ impl ast::RecordExprField {
             return;
         }
         // this is a shorthand
-        if let Some(ast::Expr::PathExpr(path_expr)) = self.expr() {
-            if let Some(path) = path_expr.path() {
-                if let Some(name_ref) = path.as_single_name_ref() {
-                    path_expr.syntax().detach();
-                    let children = vec![
-                        name_ref.syntax().clone().into(),
-                        ast::make::token(T![:]).into(),
-                        ast::make::tokens::single_space().into(),
-                        expr.syntax().clone().into(),
-                    ];
-                    ted::insert_all_raw(Position::last_child_of(self.syntax()), children);
-                }
-            }
+        if let Some(ast::Expr::PathExpr(path_expr)) = self.expr()
+            && let Some(path) = path_expr.path()
+            && let Some(name_ref) = path.as_single_name_ref()
+        {
+            path_expr.syntax().detach();
+            let children = vec![
+                name_ref.syntax().clone().into(),
+                ast::make::token(T![:]).into(),
+                ast::make::tokens::single_space().into(),
+                expr.syntax().clone().into(),
+            ];
+            ted::insert_all_raw(Position::last_child_of(self.syntax()), children);
         }
     }
 }
@@ -1092,35 +963,4 @@ mod tests {
         check("let a @ ()", "let a", None);
         check("let a @ ", "let a", None);
     }
-
-    #[test]
-    fn test_let_stmt_set_ty() {
-        #[track_caller]
-        fn check(before: &str, expected: &str, ty: Option<ast::Type>) {
-            let ty = ty.map(|it| it.clone_for_update());
-
-            let let_stmt = ast_mut_from_text::<ast::LetStmt>(&format!("fn f() {{ {before} }}"));
-            let_stmt.set_ty(ty);
-
-            let after = ast_mut_from_text::<ast::LetStmt>(&format!("fn f() {{ {expected} }}"));
-            assert_eq!(let_stmt.to_string(), after.to_string(), "{let_stmt:#?}\n!=\n{after:#?}");
-        }
-
-        // adding
-        check("let a;", "let a: ();", Some(make::ty_tuple([])));
-        // no semicolon due to it being eaten during error recovery
-        check("let a:", "let a: ()", Some(make::ty_tuple([])));
-
-        // replacing
-        check("let a: u8;", "let a: ();", Some(make::ty_tuple([])));
-        check("let a: u8 = 3;", "let a: () = 3;", Some(make::ty_tuple([])));
-        check("let a: = 3;", "let a: () = 3;", Some(make::ty_tuple([])));
-
-        // removing
-        check("let a: u8;", "let a;", None);
-        check("let a:;", "let a;", None);
-
-        check("let a: u8 = 3;", "let a = 3;", None);
-        check("let a: = 3;", "let a = 3;", None);
-    }
 }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index 2a7b51c3c24..daeb79cf081 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -229,9 +229,7 @@ pub fn ty_fn_ptr<I: Iterator<Item = Param>>(
     }
 }
 
-pub fn assoc_item_list(
-    body: Option<Vec<either::Either<ast::Attr, ast::AssocItem>>>,
-) -> ast::AssocItemList {
+pub fn assoc_item_list(body: Option<Vec<ast::AssocItem>>) -> ast::AssocItemList {
     let is_break_braces = body.is_some();
     let body_newline = if is_break_braces { "\n".to_owned() } else { String::new() };
     let body_indent = if is_break_braces { "    ".to_owned() } else { String::new() };
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 00750bff0ba..1364adb187f 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
@@ -276,19 +276,19 @@ impl Expr {
         }
 
         // Not every expression can be followed by `else` in the `let-else`
-        if let Some(ast::Stmt::LetStmt(e)) = stmt {
-            if e.let_else().is_some() {
-                match self {
-                    BinExpr(e)
-                        if e.op_kind()
-                            .map(|op| matches!(op, BinaryOp::LogicOp(_)))
-                            .unwrap_or(false) =>
-                    {
-                        return true;
-                    }
-                    _ if self.clone().trailing_brace().is_some() => return true,
-                    _ => {}
+        if let Some(ast::Stmt::LetStmt(e)) = stmt
+            && e.let_else().is_some()
+        {
+            match self {
+                BinExpr(e)
+                    if e.op_kind()
+                        .map(|op| matches!(op, BinaryOp::LogicOp(_)))
+                        .unwrap_or(false) =>
+                {
+                    return true;
                 }
+                _ if self.clone().trailing_brace().is_some() => return true,
+                _ => {}
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
index 1ba61073151..738a26fed5d 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -939,6 +939,24 @@ impl SyntaxFactory {
         ast
     }
 
+    pub fn record_expr(
+        &self,
+        path: ast::Path,
+        fields: ast::RecordExprFieldList,
+    ) -> ast::RecordExpr {
+        let ast = make::record_expr(path.clone(), fields.clone()).clone_for_update();
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone());
+            builder.map_node(
+                fields.syntax().clone(),
+                ast.record_expr_field_list().unwrap().syntax().clone(),
+            );
+            builder.finish(&mut mapping);
+        }
+        ast
+    }
+
     pub fn record_expr_field(
         &self,
         name: ast::NameRef,
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
index 5107754b182..18f5015e9ea 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
@@ -83,6 +83,16 @@ impl SyntaxEditor {
         self.changes.push(Change::Replace(element.syntax_element(), None));
     }
 
+    pub fn delete_all(&mut self, range: RangeInclusive<SyntaxElement>) {
+        if range.start() == range.end() {
+            self.delete(range.start());
+            return;
+        }
+
+        debug_assert!(is_ancestor_or_self_of_element(range.start(), &self.root));
+        self.changes.push(Change::ReplaceAll(range, Vec::new()))
+    }
+
     pub fn replace(&mut self, old: impl Element, new: impl Element) {
         let old = old.syntax_element();
         debug_assert!(is_ancestor_or_self_of_element(&old, &self.root));
@@ -626,10 +636,10 @@ mod tests {
         if let Some(ret_ty) = parent_fn.ret_type() {
             editor.delete(ret_ty.syntax().clone());
 
-            if let Some(SyntaxElement::Token(token)) = ret_ty.syntax().next_sibling_or_token() {
-                if token.kind().is_trivia() {
-                    editor.delete(token);
-                }
+            if let Some(SyntaxElement::Token(token)) = ret_ty.syntax().next_sibling_or_token()
+                && token.kind().is_trivia()
+            {
+                editor.delete(token);
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs
index 840e7697979..9090f7c9eb1 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs
@@ -153,6 +153,23 @@ impl ast::VariantList {
     }
 }
 
+impl ast::Fn {
+    pub fn replace_or_insert_body(&self, editor: &mut SyntaxEditor, body: ast::BlockExpr) {
+        if let Some(old_body) = self.body() {
+            editor.replace(old_body.syntax(), body.syntax());
+        } else {
+            let single_space = make::tokens::single_space();
+            let elements = vec![single_space.into(), body.syntax().clone().into()];
+
+            if let Some(semicolon) = self.semicolon_token() {
+                editor.replace_with_many(semicolon, elements);
+            } else {
+                editor.insert_all(Position::last_child_of(self.syntax()), elements);
+            }
+        }
+    }
+}
+
 fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) -> Option<()> {
     let make = SyntaxFactory::without_mappings();
     let l = node
@@ -184,6 +201,15 @@ pub trait Removable: AstNode {
     fn remove(&self, editor: &mut SyntaxEditor);
 }
 
+impl Removable for ast::TypeBoundList {
+    fn remove(&self, editor: &mut SyntaxEditor) {
+        match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) {
+            Some(colon) => editor.delete_all(colon..=self.syntax().clone().into()),
+            None => editor.delete(self.syntax()),
+        }
+    }
+}
+
 impl Removable for ast::Use {
     fn remove(&self, editor: &mut SyntaxEditor) {
         let make = SyntaxFactory::without_mappings();
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ted.rs b/src/tools/rust-analyzer/crates/syntax/src/ted.rs
index 6fcbdd006c2..5c286479c4e 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ted.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ted.rs
@@ -90,15 +90,15 @@ pub fn insert_raw(position: Position, elem: impl Element) {
     insert_all_raw(position, vec![elem.syntax_element()]);
 }
 pub fn insert_all(position: Position, mut elements: Vec<SyntaxElement>) {
-    if let Some(first) = elements.first() {
-        if let Some(ws) = ws_before(&position, first) {
-            elements.insert(0, ws.into());
-        }
+    if let Some(first) = elements.first()
+        && let Some(ws) = ws_before(&position, first)
+    {
+        elements.insert(0, ws.into());
     }
-    if let Some(last) = elements.last() {
-        if let Some(ws) = ws_after(&position, last) {
-            elements.push(ws.into());
-        }
+    if let Some(last) = elements.last()
+        && let Some(ws) = ws_after(&position, last)
+    {
+        elements.push(ws.into());
     }
     insert_all_raw(position, elements);
 }
@@ -165,20 +165,22 @@ fn ws_before(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> {
         PositionRepr::After(it) => it,
     };
 
-    if prev.kind() == T!['{'] && new.kind() == SyntaxKind::USE {
-        if let Some(item_list) = prev.parent().and_then(ast::ItemList::cast) {
-            let mut indent = IndentLevel::from_element(&item_list.syntax().clone().into());
-            indent.0 += 1;
-            return Some(make::tokens::whitespace(&format!("\n{indent}")));
-        }
+    if prev.kind() == T!['{']
+        && new.kind() == SyntaxKind::USE
+        && let Some(item_list) = prev.parent().and_then(ast::ItemList::cast)
+    {
+        let mut indent = IndentLevel::from_element(&item_list.syntax().clone().into());
+        indent.0 += 1;
+        return Some(make::tokens::whitespace(&format!("\n{indent}")));
     }
 
-    if prev.kind() == T!['{'] && ast::Stmt::can_cast(new.kind()) {
-        if let Some(stmt_list) = prev.parent().and_then(ast::StmtList::cast) {
-            let mut indent = IndentLevel::from_element(&stmt_list.syntax().clone().into());
-            indent.0 += 1;
-            return Some(make::tokens::whitespace(&format!("\n{indent}")));
-        }
+    if prev.kind() == T!['{']
+        && ast::Stmt::can_cast(new.kind())
+        && let Some(stmt_list) = prev.parent().and_then(ast::StmtList::cast)
+    {
+        let mut indent = IndentLevel::from_element(&stmt_list.syntax().clone().into());
+        indent.0 += 1;
+        return Some(make::tokens::whitespace(&format!("\n{indent}")));
     }
 
     ws_between(prev, new)
diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs
index 4180f9cd185..485140be8f6 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs
@@ -142,50 +142,50 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
 
     match literal.kind() {
         ast::LiteralKind::String(s) => {
-            if !s.is_raw() {
-                if let Some(without_quotes) = unquote(text, 1, '"') {
-                    unescape_str(without_quotes, |range, char| {
-                        if let Err(err) = char {
-                            push_err(1, range.start, err);
-                        }
-                    });
-                }
+            if !s.is_raw()
+                && let Some(without_quotes) = unquote(text, 1, '"')
+            {
+                unescape_str(without_quotes, |range, char| {
+                    if let Err(err) = char {
+                        push_err(1, range.start, err);
+                    }
+                });
             }
         }
         ast::LiteralKind::ByteString(s) => {
-            if !s.is_raw() {
-                if let Some(without_quotes) = unquote(text, 2, '"') {
-                    unescape_byte_str(without_quotes, |range, char| {
-                        if let Err(err) = char {
-                            push_err(1, range.start, err);
-                        }
-                    });
-                }
+            if !s.is_raw()
+                && let Some(without_quotes) = unquote(text, 2, '"')
+            {
+                unescape_byte_str(without_quotes, |range, char| {
+                    if let Err(err) = char {
+                        push_err(1, range.start, err);
+                    }
+                });
             }
         }
         ast::LiteralKind::CString(s) => {
-            if !s.is_raw() {
-                if let Some(without_quotes) = unquote(text, 2, '"') {
-                    unescape_c_str(without_quotes, |range, char| {
-                        if let Err(err) = char {
-                            push_err(1, range.start, err);
-                        }
-                    });
-                }
+            if !s.is_raw()
+                && let Some(without_quotes) = unquote(text, 2, '"')
+            {
+                unescape_c_str(without_quotes, |range, char| {
+                    if let Err(err) = char {
+                        push_err(1, range.start, err);
+                    }
+                });
             }
         }
         ast::LiteralKind::Char(_) => {
-            if let Some(without_quotes) = unquote(text, 1, '\'') {
-                if let Err(err) = unescape_char(without_quotes) {
-                    push_err(1, 0, err);
-                }
+            if let Some(without_quotes) = unquote(text, 1, '\'')
+                && let Err(err) = unescape_char(without_quotes)
+            {
+                push_err(1, 0, err);
             }
         }
         ast::LiteralKind::Byte(_) => {
-            if let Some(without_quotes) = unquote(text, 2, '\'') {
-                if let Err(err) = unescape_byte(without_quotes) {
-                    push_err(2, 0, err);
-                }
+            if let Some(without_quotes) = unquote(text, 2, '\'')
+                && let Err(err) = unescape_byte(without_quotes)
+            {
+                push_err(2, 0, err);
             }
         }
         ast::LiteralKind::IntNumber(_)
@@ -224,14 +224,14 @@ pub(crate) fn validate_block_structure(root: &SyntaxNode) {
 }
 
 fn validate_numeric_name(name_ref: Option<ast::NameRef>, errors: &mut Vec<SyntaxError>) {
-    if let Some(int_token) = int_token(name_ref) {
-        if int_token.text().chars().any(|c| !c.is_ascii_digit()) {
-            errors.push(SyntaxError::new(
-                "Tuple (struct) field access is only allowed through \
+    if let Some(int_token) = int_token(name_ref)
+        && int_token.text().chars().any(|c| !c.is_ascii_digit())
+    {
+        errors.push(SyntaxError::new(
+            "Tuple (struct) field access is only allowed through \
                 decimal integers with no underscores or suffix",
-                int_token.text_range(),
-            ));
-        }
+            int_token.text_range(),
+        ));
     }
 
     fn int_token(name_ref: Option<ast::NameRef>) -> Option<SyntaxToken> {
@@ -285,13 +285,13 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro
                 token.text_range(),
             ));
         }
-    } else if let Some(token) = segment.crate_token() {
-        if !is_path_start || use_prefix(path).is_some() {
-            errors.push(SyntaxError::new(
-                "The `crate` keyword is only allowed as the first segment of a path",
-                token.text_range(),
-            ));
-        }
+    } else if let Some(token) = segment.crate_token()
+        && (!is_path_start || use_prefix(path).is_some())
+    {
+        errors.push(SyntaxError::new(
+            "The `crate` keyword is only allowed as the first segment of a path",
+            token.text_range(),
+        ));
     }
 
     fn use_prefix(mut path: ast::Path) -> Option<ast::Path> {
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 8937e53175a..4413d2f222c 100644
--- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
@@ -955,12 +955,12 @@ impl ProcMacroExpander for DisallowCfgProcMacroExpander {
         _: String,
     ) -> Result<TopSubtree, ProcMacroExpansionError> {
         for tt in subtree.token_trees().flat_tokens() {
-            if let tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) = tt {
-                if ident.sym == sym::cfg || ident.sym == sym::cfg_attr {
-                    return Err(ProcMacroExpansionError::Panic(
-                        "cfg or cfg_attr found in DisallowCfgProcMacroExpander".to_owned(),
-                    ));
-                }
+            if let tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) = tt
+                && (ident.sym == sym::cfg || ident.sym == sym::cfg_attr)
+            {
+                return Err(ProcMacroExpansionError::Panic(
+                    "cfg or cfg_attr found in DisallowCfgProcMacroExpander".to_owned(),
+                ));
             }
         }
         Ok(subtree.clone())
diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs
index 44123385c8c..243a27b83b0 100644
--- a/src/tools/rust-analyzer/crates/tt/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs
@@ -357,10 +357,10 @@ impl<'a, S: Copy> TokenTreesView<'a, S> {
     }
 
     pub fn try_into_subtree(self) -> Option<SubtreeView<'a, S>> {
-        if let Some(TokenTree::Subtree(subtree)) = self.0.first() {
-            if subtree.usize_len() == (self.0.len() - 1) {
-                return Some(SubtreeView::new(self.0));
-            }
+        if let Some(TokenTree::Subtree(subtree)) = self.0.first()
+            && subtree.usize_len() == (self.0.len() - 1)
+        {
+            return Some(SubtreeView::new(self.0));
         }
         None
     }
@@ -1028,10 +1028,10 @@ pub fn pretty<S>(mut tkns: &[TokenTree<S>]) -> String {
         tkns = rest;
         last = [last, tokentree_to_text(tkn, &mut tkns)].join(if last_to_joint { "" } else { " " });
         last_to_joint = false;
-        if let TokenTree::Leaf(Leaf::Punct(punct)) = tkn {
-            if punct.spacing == Spacing::Joint {
-                last_to_joint = true;
-            }
+        if let TokenTree::Leaf(Leaf::Punct(punct)) = tkn
+            && punct.spacing == Spacing::Joint
+        {
+            last_to_joint = true;
         }
     }
     last
diff --git a/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs b/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
index a03337dbc51..c6393cc6922 100644
--- a/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
@@ -194,52 +194,49 @@ impl NotifyActor {
                     }
                 },
                 Event::NotifyEvent(event) => {
-                    if let Some(event) = log_notify_error(event) {
-                        if let EventKind::Create(_) | EventKind::Modify(_) | EventKind::Remove(_) =
+                    if let Some(event) = log_notify_error(event)
+                        && let EventKind::Create(_) | EventKind::Modify(_) | EventKind::Remove(_) =
                             event.kind
-                        {
-                            let files = event
-                                .paths
-                                .into_iter()
-                                .filter_map(|path| {
-                                    Some(
-                                        AbsPathBuf::try_from(
-                                            Utf8PathBuf::from_path_buf(path).ok()?,
-                                        )
+                    {
+                        let files = event
+                            .paths
+                            .into_iter()
+                            .filter_map(|path| {
+                                Some(
+                                    AbsPathBuf::try_from(Utf8PathBuf::from_path_buf(path).ok()?)
                                         .expect("path is absolute"),
-                                    )
-                                })
-                                .filter_map(|path| -> Option<(AbsPathBuf, Option<Vec<u8>>)> {
-                                    let meta = fs::metadata(&path).ok()?;
-                                    if meta.file_type().is_dir()
-                                        && self
-                                            .watched_dir_entries
-                                            .iter()
-                                            .any(|dir| dir.contains_dir(&path))
-                                    {
-                                        self.watch(path.as_ref());
-                                        return None;
-                                    }
-
-                                    if !meta.file_type().is_file() {
-                                        return None;
-                                    }
-
-                                    if !(self.watched_file_entries.contains(&path)
-                                        || self
-                                            .watched_dir_entries
-                                            .iter()
-                                            .any(|dir| dir.contains_file(&path)))
-                                    {
-                                        return None;
-                                    }
-
-                                    let contents = read(&path);
-                                    Some((path, contents))
-                                })
-                                .collect();
-                            self.send(loader::Message::Changed { files });
-                        }
+                                )
+                            })
+                            .filter_map(|path| -> Option<(AbsPathBuf, Option<Vec<u8>>)> {
+                                let meta = fs::metadata(&path).ok()?;
+                                if meta.file_type().is_dir()
+                                    && self
+                                        .watched_dir_entries
+                                        .iter()
+                                        .any(|dir| dir.contains_dir(&path))
+                                {
+                                    self.watch(path.as_ref());
+                                    return None;
+                                }
+
+                                if !meta.file_type().is_file() {
+                                    return None;
+                                }
+
+                                if !(self.watched_file_entries.contains(&path)
+                                    || self
+                                        .watched_dir_entries
+                                        .iter()
+                                        .any(|dir| dir.contains_file(&path)))
+                                {
+                                    return None;
+                                }
+
+                                let contents = read(&path);
+                                Some((path, contents))
+                            })
+                            .collect();
+                        self.send(loader::Message::Changed { files });
                     }
                 }
             }
diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
index ebac26e1d60..99a30d8f621 100644
--- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
+++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
@@ -2,8 +2,7 @@
 
 Default: `false`
 
-Whether to insert #[must_use] when generating `as_` methods
-for enum variants.
+Insert #[must_use] when generating `as_` methods for enum variants.
 
 
 ## rust-analyzer.assist.expressionFillDefault {#assist.expressionFillDefault}
@@ -17,14 +16,15 @@ Placeholder expression to use for missing expressions in assists.
 
 Default: `false`
 
-When inserting a type (e.g. in "fill match arms" assist), prefer to use `Self` over the type name where possible.
+Prefer to use `Self` over the type name when inserting a type (e.g. in "fill match arms" assist).
 
 
 ## rust-analyzer.assist.termSearch.borrowcheck {#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.
+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 {#assist.termSearch.fuel}
@@ -45,7 +45,8 @@ Warm up caches on project load.
 
 Default: `"physical"`
 
-How many worker threads to handle priming caches. The default `0` means to pick automatically.
+How many worker threads to handle priming caches. The default `0` means to pick
+automatically.
 
 
 ## rust-analyzer.cargo.allTargets {#cargo.allTargets}
@@ -103,7 +104,9 @@ targets and features, with the following base command line:
 ```bash
 cargo check --quiet --workspace --message-format=json --all-targets --keep-going
 ```
-.
+
+Note: The option must be specified as an array of command line arguments, with
+the first argument being the name of the command to run.
 
 
 ## rust-analyzer.cargo.buildScripts.rebuildOnSave {#cargo.buildScripts.rebuildOnSave}
@@ -330,7 +333,9 @@ An example command would be:
 ```bash
 cargo check --workspace --message-format=json --all-targets
 ```
-.
+
+Note: The option must be specified as an array of command line arguments, with
+the first argument being the name of the command to run.
 
 
 ## rust-analyzer.check.targets {#check.targets}
@@ -358,7 +363,7 @@ check will be performed.
 
 Default: `true`
 
-Whether to automatically add a semicolon when completing unit-returning functions.
+Automatically add a semicolon when completing unit-returning functions.
 
 In `match` arms it completes a comma instead.
 
@@ -367,22 +372,26 @@ In `match` arms it completes a comma instead.
 
 Default: `true`
 
-Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.
+Show method calls and field accesses completions with `await` prefixed to them when
+completing on a future.
 
 
 ## rust-analyzer.completion.autoIter.enable {#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.
+Show method call completions with `iter()` or `into_iter()` prefixed to them when
+completing on a type that has them.
 
 
 ## rust-analyzer.completion.autoimport.enable {#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.
+Show 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 {#completion.autoimport.exclude}
@@ -406,10 +415,11 @@ 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" }`.
+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.
+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#`.
 
@@ -418,15 +428,15 @@ This setting also inherits `#rust-analyzer.completion.excludeTraits#`.
 
 Default: `true`
 
-Toggles the additional completions that automatically show method calls and field accesses
-with `self` prefixed to them when inside a method.
+Show method calls and field access completions with `self` prefixed to them when
+inside a method.
 
 
 ## rust-analyzer.completion.callable.snippets {#completion.callable.snippets}
 
 Default: `"fill_arguments"`
 
-Whether to add parenthesis and argument snippets when completing function.
+Add parenthesis and argument snippets when completing function.
 
 
 ## rust-analyzer.completion.excludeTraits {#completion.excludeTraits}
@@ -435,7 +445,9 @@ 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`.
+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.
 
@@ -444,14 +456,15 @@ Note that the trait themselves can still be completed.
 
 Default: `false`
 
-Whether to show full function/method signatures in completion docs.
+Show full function / method signatures in completion docs.
 
 
 ## rust-analyzer.completion.hideDeprecated {#completion.hideDeprecated}
 
 Default: `false`
 
-Whether to omit deprecated items from autocompletion. By default they are marked as deprecated but not hidden.
+Omit deprecated items from completions. By default they are marked as deprecated but not
+hidden.
 
 
 ## rust-analyzer.completion.limit {#completion.limit}
@@ -465,14 +478,15 @@ Maximum number of completions to return. If `None`, the limit is infinite.
 
 Default: `true`
 
-Whether to show postfix snippets like `dbg`, `if`, `not`, etc.
+Show postfix snippets like `dbg`, `if`, `not`, etc.
 
 
 ## rust-analyzer.completion.privateEditable.enable {#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.
+Show 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 {#completion.snippets.custom}
@@ -529,7 +543,7 @@ Custom completion snippets.
 
 Default: `false`
 
-Whether to enable term search based snippets like `Some(foo.bar().baz())`.
+Enable term search based snippets like `Some(foo.bar().baz())`.
 
 
 ## rust-analyzer.completion.termSearch.fuel {#completion.termSearch.fuel}
@@ -550,30 +564,30 @@ List of rust-analyzer diagnostics to disable.
 
 Default: `true`
 
-Whether to show native rust-analyzer diagnostics.
+Show native rust-analyzer diagnostics.
 
 
 ## rust-analyzer.diagnostics.experimental.enable {#diagnostics.experimental.enable}
 
 Default: `false`
 
-Whether to show experimental rust-analyzer diagnostics that might
-have more false positives than usual.
+Show experimental rust-analyzer diagnostics that might have more false positives than
+usual.
 
 
 ## rust-analyzer.diagnostics.remapPrefix {#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`.
+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 {#diagnostics.styleLints.enable}
 
 Default: `false`
 
-Whether to run additional style lints.
+Run additional style lints.
 
 
 ## rust-analyzer.diagnostics.warningsAsHint {#diagnostics.warningsAsHint}
@@ -582,8 +596,8 @@ 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`.
+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 {#diagnostics.warningsAsInfo}
@@ -592,17 +606,19 @@ 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`.
+The warnings will be indicated by a blue squiggly underline in code and a blue icon in
+the `Problems Panel`.
 
 
 ## rust-analyzer.files.exclude {#files.exclude}
 
 Default: `[]`
 
-These paths (file/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`.
+List of files to ignore
+
+These paths (file/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 {#files.watcher}
@@ -616,64 +632,67 @@ Controls file watching implementation.
 
 Default: `true`
 
-Enables highlighting of related return values while the cursor is on any `match`, `if`, or match arm arrow (`=>`).
+Highlight related return values while the cursor is on any `match`, `if`, or match arm
+arrow (`=>`).
 
 
 ## rust-analyzer.highlightRelated.breakPoints.enable {#highlightRelated.breakPoints.enable}
 
 Default: `true`
 
-Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords.
+Highlight related references while the cursor is on `break`, `loop`, `while`, or `for`
+keywords.
 
 
 ## rust-analyzer.highlightRelated.closureCaptures.enable {#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.
+Highlight all captures of a closure while the cursor is on the `|` or move keyword of a closure.
 
 
 ## rust-analyzer.highlightRelated.exitPoints.enable {#highlightRelated.exitPoints.enable}
 
 Default: `true`
 
-Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`).
+Highlight all exit points while the cursor is on any `return`, `?`, `fn`, or return type
+arrow (`->`).
 
 
 ## rust-analyzer.highlightRelated.references.enable {#highlightRelated.references.enable}
 
 Default: `true`
 
-Enables highlighting of related references while the cursor is on any identifier.
+Highlight related references while the cursor is on any identifier.
 
 
 ## rust-analyzer.highlightRelated.yieldPoints.enable {#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.
+Highlight 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 {#hover.actions.debug.enable}
 
 Default: `true`
 
-Whether to show `Debug` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
+Show `Debug` action. Only applies when `#rust-analyzer.hover.actions.enable#` is set.
 
 
 ## rust-analyzer.hover.actions.enable {#hover.actions.enable}
 
 Default: `true`
 
-Whether to show HoverActions in Rust files.
+Show HoverActions in Rust files.
 
 
 ## rust-analyzer.hover.actions.gotoTypeDef.enable {#hover.actions.gotoTypeDef.enable}
 
 Default: `true`
 
-Whether to show `Go to Type Definition` action. Only applies when
+Show `Go to Type Definition` action. Only applies when
 `#rust-analyzer.hover.actions.enable#` is set.
 
 
@@ -681,46 +700,45 @@ Whether to show `Go to Type Definition` action. Only applies when
 
 Default: `true`
 
-Whether to show `Implementations` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
+Show `Implementations` action. Only applies when `#rust-analyzer.hover.actions.enable#`
+is set.
 
 
 ## rust-analyzer.hover.actions.references.enable {#hover.actions.references.enable}
 
 Default: `false`
 
-Whether to show `References` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
+Show `References` action. Only applies when `#rust-analyzer.hover.actions.enable#` is
+set.
 
 
 ## rust-analyzer.hover.actions.run.enable {#hover.actions.run.enable}
 
 Default: `true`
 
-Whether to show `Run` action. Only applies when
-`#rust-analyzer.hover.actions.enable#` is set.
+Show `Run` action. Only applies when `#rust-analyzer.hover.actions.enable#` is set.
 
 
 ## rust-analyzer.hover.actions.updateTest.enable {#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.
+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 {#hover.documentation.enable}
 
 Default: `true`
 
-Whether to show documentation on hover.
+Show documentation on hover.
 
 
 ## rust-analyzer.hover.documentation.keywords.enable {#hover.documentation.keywords.enable}
 
 Default: `true`
 
-Whether to show keyword hover popups. Only applies when
+Show keyword hover popups. Only applies when
 `#rust-analyzer.hover.documentation.enable#` is set.
 
 
@@ -728,7 +746,7 @@ Whether to show keyword hover popups. Only applies when
 
 Default: `true`
 
-Whether to show drop glue information on hover.
+Show drop glue information on hover.
 
 
 ## rust-analyzer.hover.links.enable {#hover.links.enable}
@@ -742,9 +760,11 @@ Use markdown syntax for links on hover.
 
 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.
+Show what types are used as generic arguments in calls etc. on hover, and limit the max
+length to show such types, beyond which 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.
+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.
 
@@ -760,7 +780,7 @@ How to render the align information in a memory layout hover.
 
 Default: `true`
 
-Whether to show memory layout data on hover.
+Show memory layout data on hover.
 
 
 ## rust-analyzer.hover.memoryLayout.niches {#hover.memoryLayout.niches}
@@ -802,7 +822,8 @@ How many variants of an enum to display when hovering on. Show none if empty.
 
 Default: `5`
 
-How many fields of a struct, variant or union to display when hovering on. Show none if empty.
+How many fields of a struct, variant or union to display when hovering on. Show none if
+empty.
 
 
 ## rust-analyzer.hover.show.traitAssocItems {#hover.show.traitAssocItems}
@@ -816,7 +837,8 @@ How many associated items of a trait to display when hovering a trait.
 
 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.
+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 {#imports.granularity.group}
@@ -830,14 +852,17 @@ How imports should be grouped into use statements.
 
 Default: `true`
 
-Group inserted imports by the [following order](https://rust-analyzer.github.io/book/features.html#auto-import). Groups are separated by newlines.
+Group inserted imports by the [following
+order](https://rust-analyzer.github.io/book/features.html#auto-import). Groups are
+separated by newlines.
 
 
 ## rust-analyzer.imports.merge.glob {#imports.merge.glob}
 
 Default: `true`
 
-Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
+Allow import insertion to merge new imports into single path glob imports like `use
+std::fmt::*;`.
 
 
 ## rust-analyzer.imports.preferNoStd {#imports.preferNoStd}
@@ -851,7 +876,7 @@ Prefer to unconditionally use imports of the core and alloc crate, over the std
 
 Default: `false`
 
-Whether to prefer import paths containing a `prelude` module.
+Prefer import paths containing a `prelude` module.
 
 
 ## rust-analyzer.imports.prefix {#imports.prefix}
@@ -865,28 +890,30 @@ The path structure for newly inserted paths to use.
 
 Default: `false`
 
-Whether to prefix external (including std, core) crate imports with `::`. e.g. "use ::std::io::Read;".
+Prefix external (including std, core) crate imports with `::`.
+
+E.g. `use ::std::io::Read;`.
 
 
 ## rust-analyzer.inlayHints.bindingModeHints.enable {#inlayHints.bindingModeHints.enable}
 
 Default: `false`
 
-Whether to show inlay type hints for binding modes.
+Show inlay type hints for binding modes.
 
 
 ## rust-analyzer.inlayHints.chainingHints.enable {#inlayHints.chainingHints.enable}
 
 Default: `true`
 
-Whether to show inlay type hints for method chains.
+Show inlay type hints for method chains.
 
 
 ## rust-analyzer.inlayHints.closingBraceHints.enable {#inlayHints.closingBraceHints.enable}
 
 Default: `true`
 
-Whether to show inlay hints after a closing `}` to indicate what item it belongs to.
+Show inlay hints after a closing `}` to indicate what item it belongs to.
 
 
 ## rust-analyzer.inlayHints.closingBraceHints.minLines {#inlayHints.closingBraceHints.minLines}
@@ -901,14 +928,14 @@ to always show them).
 
 Default: `false`
 
-Whether to show inlay hints for closure captures.
+Show inlay hints for closure captures.
 
 
 ## rust-analyzer.inlayHints.closureReturnTypeHints.enable {#inlayHints.closureReturnTypeHints.enable}
 
 Default: `"never"`
 
-Whether to show inlay type hints for return types of closures.
+Show inlay type hints for return types of closures.
 
 
 ## rust-analyzer.inlayHints.closureStyle {#inlayHints.closureStyle}
@@ -922,77 +949,77 @@ Closure notation in type and chaining inlay hints.
 
 Default: `"never"`
 
-Whether to show enum variant discriminant hints.
+Show enum variant discriminant hints.
 
 
 ## rust-analyzer.inlayHints.expressionAdjustmentHints.enable {#inlayHints.expressionAdjustmentHints.enable}
 
 Default: `"never"`
 
-Whether to show inlay hints for type adjustments.
+Show inlay hints for type adjustments.
 
 
 ## rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe {#inlayHints.expressionAdjustmentHints.hideOutsideUnsafe}
 
 Default: `false`
 
-Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
+Hide inlay hints for type adjustments outside of `unsafe` blocks.
 
 
 ## rust-analyzer.inlayHints.expressionAdjustmentHints.mode {#inlayHints.expressionAdjustmentHints.mode}
 
 Default: `"prefix"`
 
-Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).
+Show inlay hints as postfix ops (`.*` instead of `*`, etc).
 
 
 ## rust-analyzer.inlayHints.genericParameterHints.const.enable {#inlayHints.genericParameterHints.const.enable}
 
 Default: `true`
 
-Whether to show const generic parameter name inlay hints.
+Show const generic parameter name inlay hints.
 
 
 ## rust-analyzer.inlayHints.genericParameterHints.lifetime.enable {#inlayHints.genericParameterHints.lifetime.enable}
 
 Default: `false`
 
-Whether to show generic lifetime parameter name inlay hints.
+Show generic lifetime parameter name inlay hints.
 
 
 ## rust-analyzer.inlayHints.genericParameterHints.type.enable {#inlayHints.genericParameterHints.type.enable}
 
 Default: `false`
 
-Whether to show generic type parameter name inlay hints.
+Show generic type parameter name inlay hints.
 
 
 ## rust-analyzer.inlayHints.implicitDrops.enable {#inlayHints.implicitDrops.enable}
 
 Default: `false`
 
-Whether to show implicit drop hints.
+Show implicit drop hints.
 
 
 ## rust-analyzer.inlayHints.implicitSizedBoundHints.enable {#inlayHints.implicitSizedBoundHints.enable}
 
 Default: `false`
 
-Whether to show inlay hints for the implied type parameter `Sized` bound.
+Show inlay hints for the implied type parameter `Sized` bound.
 
 
 ## rust-analyzer.inlayHints.lifetimeElisionHints.enable {#inlayHints.lifetimeElisionHints.enable}
 
 Default: `"never"`
 
-Whether to show inlay type hints for elided lifetimes in function signatures.
+Show inlay type hints for elided lifetimes in function signatures.
 
 
 ## rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames {#inlayHints.lifetimeElisionHints.useParameterNames}
 
 Default: `false`
 
-Whether to prefer using parameter names as the name for elided lifetime hints if possible.
+Prefer using parameter names as the name for elided lifetime hints if possible.
 
 
 ## rust-analyzer.inlayHints.maxLength {#inlayHints.maxLength}
@@ -1006,23 +1033,24 @@ Maximum length for inlay hints. Set to null to have an unlimited length.
 
 Default: `true`
 
-Whether to show function parameter name inlay hints at the call
-site.
+Show function parameter name inlay hints at the call site.
 
 
 ## rust-analyzer.inlayHints.rangeExclusiveHints.enable {#inlayHints.rangeExclusiveHints.enable}
 
 Default: `false`
 
-Whether to show exclusive range inlay hints.
+Show exclusive range inlay hints.
 
 
 ## rust-analyzer.inlayHints.reborrowHints.enable {#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#.
+Show inlay hints for compiler inserted reborrows.
+
+This setting is deprecated in favor of
+#rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.
 
 
 ## rust-analyzer.inlayHints.renderColons {#inlayHints.renderColons}
@@ -1036,36 +1064,38 @@ Whether to render leading colons for type hints, and trailing colons for paramet
 
 Default: `true`
 
-Whether to show inlay type hints for variables.
+Show inlay type hints for variables.
 
 
 ## rust-analyzer.inlayHints.typeHints.hideClosureInitialization {#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#`.
+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 {#inlayHints.typeHints.hideClosureParameter}
 
 Default: `false`
 
-Whether to hide inlay parameter type hints for closures.
+Hide inlay parameter type hints for closures.
 
 
 ## rust-analyzer.inlayHints.typeHints.hideNamedConstructor {#inlayHints.typeHints.hideNamedConstructor}
 
 Default: `false`
 
-Whether to hide inlay type hints for constructors.
+Hide inlay type hints for constructors.
 
 
 ## rust-analyzer.interpret.tests {#interpret.tests}
 
 Default: `false`
 
-Enables the experimental support for interpreting tests.
+Enable the experimental support for interpreting tests.
 
 
 ## rust-analyzer.joinLines.joinAssignments {#joinLines.joinAssignments}
@@ -1100,23 +1130,21 @@ Join lines unwraps trivial blocks.
 
 Default: `true`
 
-Whether to show `Debug` lens. Only applies when
-`#rust-analyzer.lens.enable#` is set.
+Show `Debug` lens. Only applies when `#rust-analyzer.lens.enable#` is set.
 
 
 ## rust-analyzer.lens.enable {#lens.enable}
 
 Default: `true`
 
-Whether to show CodeLens in Rust files.
+Show CodeLens in Rust files.
 
 
 ## rust-analyzer.lens.implementations.enable {#lens.implementations.enable}
 
 Default: `true`
 
-Whether to show `Implementations` lens. Only applies when
-`#rust-analyzer.lens.enable#` is set.
+Show `Implementations` lens. Only applies when `#rust-analyzer.lens.enable#` is set.
 
 
 ## rust-analyzer.lens.location {#lens.location}
@@ -1130,60 +1158,56 @@ Where to render annotations.
 
 Default: `false`
 
-Whether to show `References` lens for Struct, Enum, and Union.
-Only applies when `#rust-analyzer.lens.enable#` is set.
+Show `References` lens for Struct, Enum, and Union. Only applies when
+`#rust-analyzer.lens.enable#` is set.
 
 
 ## rust-analyzer.lens.references.enumVariant.enable {#lens.references.enumVariant.enable}
 
 Default: `false`
 
-Whether to show `References` lens for Enum Variants.
-Only applies when `#rust-analyzer.lens.enable#` is set.
+Show `References` lens for Enum Variants. Only applies when
+`#rust-analyzer.lens.enable#` is set.
 
 
 ## rust-analyzer.lens.references.method.enable {#lens.references.method.enable}
 
 Default: `false`
 
-Whether to show `Method References` lens. Only applies when
-`#rust-analyzer.lens.enable#` is set.
+Show `Method References` lens. Only applies when `#rust-analyzer.lens.enable#` is set.
 
 
 ## rust-analyzer.lens.references.trait.enable {#lens.references.trait.enable}
 
 Default: `false`
 
-Whether to show `References` lens for Trait.
-Only applies when `#rust-analyzer.lens.enable#` is set.
+Show `References` lens for Trait. Only applies when `#rust-analyzer.lens.enable#` is
+set.
 
 
 ## rust-analyzer.lens.run.enable {#lens.run.enable}
 
 Default: `true`
 
-Whether to show `Run` lens. Only applies when
-`#rust-analyzer.lens.enable#` is set.
+Show `Run` lens. Only applies when `#rust-analyzer.lens.enable#` is set.
 
 
 ## rust-analyzer.lens.updateTest.enable {#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.
+Show `Update Test` lens. Only applies when `#rust-analyzer.lens.enable#` and
+`#rust-analyzer.lens.run.enable#` are set.
 
 
 ## rust-analyzer.linkedProjects {#linkedProjects}
 
 Default: `[]`
 
-Disable project auto-discovery in favor of explicitly specified set
-of projects.
+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.
+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 {#lru.capacity}
@@ -1197,21 +1221,22 @@ Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
 
 Default: `{}`
 
-Sets the LRU capacity of the specified queries.
+The LRU capacity of the specified queries.
 
 
 ## rust-analyzer.notifications.cargoTomlNotFound {#notifications.cargoTomlNotFound}
 
 Default: `true`
 
-Whether to show `can't find Cargo.toml` error message.
+Show `can't find Cargo.toml` error message.
 
 
 ## rust-analyzer.numThreads {#numThreads}
 
 Default: `null`
 
-How many worker threads in the main loop. The default `null` means to pick automatically.
+The number of worker threads in the main loop. The default `null` means to pick
+automatically.
 
 
 ## rust-analyzer.procMacro.attributes.enable {#procMacro.attributes.enable}
@@ -1322,6 +1347,9 @@ 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.
 
+Note: The option must be specified as an array of command line arguments, with
+the first argument being the name of the command to run.
+
 
 ## rust-analyzer.rustfmt.rangeFormatting.enable {#rustfmt.rangeFormatting.enable}
 
@@ -1346,7 +1374,10 @@ doc links.
 
 Default: `true`
 
-Whether the server is allowed to emit non-standard tokens and modifiers.
+Emit non-standard tokens and modifiers
+
+When enabled, rust-analyzer will emit tokens and modifiers that are not part of the
+standard set of semantic tokens.
 
 
 ## rust-analyzer.semanticHighlighting.operator.enable {#semanticHighlighting.operator.enable}
@@ -1427,11 +1458,15 @@ Show documentation.
 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 `=` 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 `=` 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 `{` 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.
@@ -1475,8 +1510,8 @@ Below is an example of a valid configuration:
 
 **Warning**: This format is provisional and subject to change.
 
-[`DiscoverWorkspaceConfig::command`] *must* return a JSON object
-corresponding to `DiscoverProjectData::Finished`:
+[`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to
+`DiscoverProjectData::Finished`:
 
 ```norun
 #[derive(Debug, Clone, Deserialize, Serialize)]
@@ -1506,12 +1541,11 @@ As JSON, `DiscoverProjectData::Finished` is:
 }
 ```
 
-It is encouraged, but not required, to use the other variants on
-`DiscoverProjectData` to provide a more polished end-user experience.
+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:
+`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)]
@@ -1538,11 +1572,10 @@ Similarly, the JSON representation of `DiscoverArgument::Buildfile` is:
 }
 ```
 
-`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.
+`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.excludeImports {#workspace.symbol.search.excludeImports}
diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/style.md b/src/tools/rust-analyzer/docs/book/src/contributing/style.md
index 5654e37753a..746f3eb1321 100644
--- a/src/tools/rust-analyzer/docs/book/src/contributing/style.md
+++ b/src/tools/rust-analyzer/docs/book/src/contributing/style.md
@@ -49,8 +49,8 @@ In this case, we'll probably ask you to split API changes into a separate PR.
 Changes of the third group should be pretty rare, so we don't specify any specific process for them.
 That said, adding an innocent-looking `pub use` is a very simple way to break encapsulation, keep an eye on it!
 
-Note: if you enjoyed this abstract hand-waving about boundaries, you might appreciate
-https://www.tedinski.com/2018/02/06/system-boundaries.html
+Note: if you enjoyed this abstract hand-waving about boundaries, you might appreciate [this post](https://www.tedinski.com/2018/02/06/system-boundaries.html).
+
 
 ## Crates.io Dependencies
 
@@ -231,7 +231,7 @@ fn is_string_literal(s: &str) -> bool {
 }
 ```
 
-In the "Not as good" version, the precondition that `1` is a valid char boundary is checked in `is_string_literal` and used in `foo`.
+In the "Bad" version, the precondition that `1` and `s.len() - 1` are valid string literal boundaries is checked in `is_string_literal` but used in `main`.
 In the "Good" version, the precondition check and usage are checked in the same block, and then encoded in the types.
 
 **Rationale:** non-local code properties degrade under change.
@@ -271,6 +271,8 @@ fn f() {
 }
 ```
 
+See also [this post](https://matklad.github.io/2023/11/15/push-ifs-up-and-fors-down.html)
+
 ## Assertions
 
 Assert liberally.
@@ -608,7 +610,7 @@ Avoid making a lot of code type parametric, *especially* on the boundaries betwe
 
 ```rust
 // GOOD
-fn frobnicate(f: impl FnMut()) {
+fn frobnicate(mut f: impl FnMut()) {
     frobnicate_impl(&mut f)
 }
 fn frobnicate_impl(f: &mut dyn FnMut()) {
@@ -616,7 +618,7 @@ fn frobnicate_impl(f: &mut dyn FnMut()) {
 }
 
 // BAD
-fn frobnicate(f: impl FnMut()) {
+fn frobnicate(mut f: impl FnMut()) {
     // lots of code
 }
 ```
@@ -975,7 +977,7 @@ Don't use the `ref` keyword.
 **Rationale:** consistency & simplicity.
 `ref` was required before [match ergonomics](https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md).
 Today, it is redundant.
-Between `ref` and mach ergonomics, the latter is more ergonomic in most cases, and is simpler (does not require a keyword).
+Between `ref` and match ergonomics, the latter is more ergonomic in most cases, and is simpler (does not require a keyword).
 
 ## Empty Match Arms
 
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 3cb4c21ee1f..470db244f14 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -354,35 +354,122 @@
         ],
         "configuration": [
             {
-                "title": "general",
+                "title": "Rust Analyzer"
+            },
+            {
+                "title": "Assist"
+            },
+            {
+                "title": "Cache Priming"
+            },
+            {
+                "title": "Cargo"
+            },
+            {
+                "title": "Cfg"
+            },
+            {
+                "title": "Check"
+            },
+            {
+                "title": "Completion"
+            },
+            {
+                "title": "Debug"
+            },
+            {
+                "title": "Diagnostics"
+            },
+            {
+                "title": "Files"
+            },
+            {
+                "title": "Highlight Related"
+            },
+            {
+                "title": "Hover"
+            },
+            {
+                "title": "Imports"
+            },
+            {
+                "title": "Inlay Hints"
+            },
+            {
+                "title": "Interpret"
+            },
+            {
+                "title": "Join Lines"
+            },
+            {
+                "title": "Lens"
+            },
+            {
+                "title": "Lru"
+            },
+            {
+                "title": "Notifications"
+            },
+            {
+                "title": "Proc Macro"
+            },
+            {
+                "title": "References"
+            },
+            {
+                "title": "Runnables"
+            },
+            {
+                "title": "Rustc"
+            },
+            {
+                "title": "Rustfmt"
+            },
+            {
+                "title": "Semantic Highlighting"
+            },
+            {
+                "title": "Signature Info"
+            },
+            {
+                "title": "Typing"
+            },
+            {
+                "title": "Vfs"
+            },
+            {
+                "title": "Workspace"
+            },
+            {
+                "title": "rust-analyzer",
                 "properties": {
                     "rust-analyzer.restartServerOnConfigChange": {
-                        "markdownDescription": "Whether to restart the server automatically when certain settings that require a restart are changed.",
+                        "description": "Restart the server automatically when settings that require a restart are changed.",
                         "default": false,
                         "type": "boolean"
                     },
                     "rust-analyzer.showUnlinkedFileNotification": {
-                        "markdownDescription": "Whether to show a notification for unlinked files asking the user to add the corresponding Cargo.toml to the linked projects setting.",
+                        "description": "Show a notification for unlinked files, prompting the user to add the corresponding Cargo.toml to the linked projects setting.",
                         "default": true,
                         "type": "boolean"
                     },
                     "rust-analyzer.showRequestFailedErrorNotification": {
-                        "markdownDescription": "Whether to show error notifications for failing requests.",
+                        "description": "Show error notifications when requests fail.",
                         "default": true,
                         "type": "boolean"
                     },
                     "rust-analyzer.showDependenciesExplorer": {
-                        "markdownDescription": "Whether to show the dependencies view.",
+                        "description": "Show Rust Dependencies in the Explorer view.",
                         "default": true,
                         "type": "boolean"
                     },
                     "rust-analyzer.showSyntaxTree": {
-                        "markdownDescription": "Whether to show the syntax tree view.",
+                        "description": "Show Syntax Tree in the Explorer view.",
                         "default": false,
                         "type": "boolean"
                     },
                     "rust-analyzer.testExplorer": {
-                        "markdownDescription": "Whether to show the test explorer.",
+                        "description": "Show the Test Explorer view.",
                         "default": false,
                         "type": "boolean"
                     },
@@ -394,7 +481,7 @@
                 }
             },
             {
-                "title": "runnables",
+                "title": "Runnables",
                 "properties": {
                     "rust-analyzer.runnables.extraEnv": {
                         "anyOf": [
@@ -452,7 +539,7 @@
                 }
             },
             {
-                "title": "statusBar",
+                "title": "Status Bar",
                 "properties": {
                     "rust-analyzer.statusBar.clickAction": {
                         "type": "string",
@@ -524,7 +611,7 @@
                 }
             },
             {
-                "title": "server",
+                "title": "Server",
                 "properties": {
                     "rust-analyzer.server.path": {
                         "type": [
@@ -553,7 +640,7 @@
                 }
             },
             {
-                "title": "trace",
+                "title": "Trace",
                 "properties": {
                     "rust-analyzer.trace.server": {
                         "type": "string",
@@ -580,7 +667,7 @@
                 }
             },
             {
-                "title": "debug",
+                "title": "Debug",
                 "properties": {
                     "rust-analyzer.debug.engine": {
                         "type": "string",
@@ -625,7 +712,7 @@
                 }
             },
             {
-                "title": "typing",
+                "title": "Typing",
                 "properties": {
                     "rust-analyzer.typing.continueCommentsOnNewline": {
                         "markdownDescription": "Whether to prefix newlines after comments with the corresponding comment prefix.",
@@ -635,7 +722,7 @@
                 }
             },
             {
-                "title": "diagnostics",
+                "title": "Diagnostics",
                 "properties": {
                     "rust-analyzer.diagnostics.previewRustcOutput": {
                         "markdownDescription": "Whether to show the main part of the rendered rustc output of a diagnostic message.",
@@ -653,17 +740,17 @@
                 "title": "$generated-start"
             },
             {
-                "title": "assist",
+                "title": "Assist",
                 "properties": {
                     "rust-analyzer.assist.emitMustUse": {
-                        "markdownDescription": "Whether to insert #[must_use] when generating `as_` methods\nfor enum variants.",
+                        "markdownDescription": "Insert #[must_use] when generating `as_` methods for enum variants.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "assist",
+                "title": "Assist",
                 "properties": {
                     "rust-analyzer.assist.expressionFillDefault": {
                         "markdownDescription": "Placeholder expression to use for missing expressions in assists.",
@@ -681,27 +768,27 @@
                 }
             },
             {
-                "title": "assist",
+                "title": "Assist",
                 "properties": {
                     "rust-analyzer.assist.preferSelf": {
-                        "markdownDescription": "When inserting a type (e.g. in \"fill match arms\" assist), prefer to use `Self` over the type name where possible.",
+                        "markdownDescription": "Prefer to use `Self` over the type name when inserting a type (e.g. in \"fill match arms\" assist).",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "assist",
+                "title": "Assist",
                 "properties": {
                     "rust-analyzer.assist.termSearch.borrowcheck": {
-                        "markdownDescription": "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.",
+                        "markdownDescription": "Enable borrow checking for term search code assists. If set to false, also there will be\nmore suggestions, but some of them may not borrow-check.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "assist",
+                "title": "Assist",
                 "properties": {
                     "rust-analyzer.assist.termSearch.fuel": {
                         "markdownDescription": "Term search fuel in \"units of work\" for assists (Defaults to 1800).",
@@ -712,7 +799,7 @@
                 }
             },
             {
-                "title": "cachePriming",
+                "title": "Cache Priming",
                 "properties": {
                     "rust-analyzer.cachePriming.enable": {
                         "markdownDescription": "Warm up caches on project load.",
@@ -722,10 +809,10 @@
                 }
             },
             {
-                "title": "cachePriming",
+                "title": "Cache Priming",
                 "properties": {
                     "rust-analyzer.cachePriming.numThreads": {
-                        "markdownDescription": "How many worker threads to handle priming caches. The default `0` means to pick automatically.",
+                        "markdownDescription": "How many worker threads to handle priming caches. The default `0` means to pick\nautomatically.",
                         "default": "physical",
                         "anyOf": [
                             {
@@ -749,7 +836,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.allTargets": {
                         "markdownDescription": "Pass `--all-targets` to cargo invocation.",
@@ -759,7 +846,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.autoreload": {
                         "markdownDescription": "Automatically refresh project info via `cargo metadata` on\n`Cargo.toml` or `.cargo/config.toml` changes.",
@@ -769,7 +856,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.buildScripts.enable": {
                         "markdownDescription": "Run build scripts (`build.rs`) for more precise code analysis.",
@@ -779,7 +866,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.buildScripts.invocationStrategy": {
                         "markdownDescription": "Specifies the invocation strategy to use when running the build scripts command.\nIf `per_workspace` is set, the command will be executed for each Rust workspace with the\nworkspace as the working directory.\nIf `once` is set, the command will be executed once with the opened project as the\nworking directory.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.",
@@ -797,10 +884,10 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.buildScripts.overrideCommand": {
-                        "markdownDescription": "Override the command rust-analyzer uses to run build scripts and\nbuild procedural macros. The command is required to output json\nand should therefore include `--message-format=json` or a similar\noption.\n\nIf there are multiple linked projects/workspaces, this command is invoked for\neach of them, with the working directory being the workspace root\n(i.e., the folder containing the `Cargo.toml`). This can be overwritten\nby changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`.\n\nBy default, a cargo invocation will be constructed for the configured\ntargets and features, with the following base command line:\n\n```bash\ncargo check --quiet --workspace --message-format=json --all-targets --keep-going\n```\n.",
+                        "markdownDescription": "Override the command rust-analyzer uses to run build scripts and\nbuild procedural macros. The command is required to output json\nand should therefore include `--message-format=json` or a similar\noption.\n\nIf there are multiple linked projects/workspaces, this command is invoked for\neach of them, with the working directory being the workspace root\n(i.e., the folder containing the `Cargo.toml`). This can be overwritten\nby changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`.\n\nBy default, a cargo invocation will be constructed for the configured\ntargets and features, with the following base command line:\n\n```bash\ncargo check --quiet --workspace --message-format=json --all-targets --keep-going\n```\n\nNote: The option must be specified as an array of command line arguments, with\nthe first argument being the name of the command to run.",
                         "default": null,
                         "type": [
                             "null",
@@ -813,7 +900,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.buildScripts.rebuildOnSave": {
                         "markdownDescription": "Rerun proc-macros building/build-scripts running when proc-macro\nor build-script sources change and are saved.",
@@ -823,7 +910,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.buildScripts.useRustcWrapper": {
                         "markdownDescription": "Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to\navoid checking unnecessary things.",
@@ -833,7 +920,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.cfgs": {
                         "markdownDescription": "List of cfg options to enable with the given values.\n\nTo enable a name without a value, use `\"key\"`.\nTo enable a name with a value, use `\"key=value\"`.\nTo disable, prefix the entry with a `!`.",
@@ -849,7 +936,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.extraArgs": {
                         "markdownDescription": "Extra arguments that are passed to every cargo invocation.",
@@ -862,7 +949,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.extraEnv": {
                         "markdownDescription": "Extra environment variables that will be set when running cargo, rustc\nor other commands within the workspace. Useful for setting RUSTFLAGS.",
@@ -872,7 +959,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.features": {
                         "markdownDescription": "List of features to activate.\n\nSet this to `\"all\"` to pass `--all-features` to cargo.",
@@ -898,7 +985,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.noDefaultFeatures": {
                         "markdownDescription": "Whether to pass `--no-default-features` to cargo.",
@@ -908,7 +995,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.noDeps": {
                         "markdownDescription": "Whether to skip fetching dependencies. If set to \"true\", the analysis is performed\nentirely offline, and Cargo metadata for dependencies is not fetched.",
@@ -918,7 +1005,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.sysroot": {
                         "markdownDescription": "Relative path to the sysroot, or \"discover\" to try to automatically find it via\n\"rustc --print sysroot\".\n\nUnsetting this disables sysroot loading.\n\nThis option does not take effect until rust-analyzer is restarted.",
@@ -931,7 +1018,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.sysrootSrc": {
                         "markdownDescription": "Relative path to the sysroot library sources. If left unset, this will default to\n`{cargo.sysroot}/lib/rustlib/src/rust/library`.\n\nThis option does not take effect until rust-analyzer is restarted.",
@@ -944,7 +1031,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.target": {
                         "markdownDescription": "Compilation target override (target tuple).",
@@ -957,7 +1044,7 @@
                 }
             },
             {
-                "title": "cargo",
+                "title": "Cargo",
                 "properties": {
                     "rust-analyzer.cargo.targetDir": {
                         "markdownDescription": "Optional path to a rust-analyzer specific target directory.\nThis prevents rust-analyzer's `cargo check` and initial build-script and proc-macro\nbuilding from locking the `Cargo.lock` at the expense of duplicating build artifacts.\n\nSet to `true` to use a subdirectory of the existing target directory or\nset to a path relative to the workspace to use that path.",
@@ -977,7 +1064,7 @@
                 }
             },
             {
-                "title": "cfg",
+                "title": "Cfg",
                 "properties": {
                     "rust-analyzer.cfg.setTest": {
                         "markdownDescription": "Set `cfg(test)` for local crates. Defaults to true.",
@@ -987,7 +1074,7 @@
                 }
             },
             {
-                "title": "general",
+                "title": "rust-analyzer",
                 "properties": {
                     "rust-analyzer.checkOnSave": {
                         "markdownDescription": "Run the check command for diagnostics on save.",
@@ -997,7 +1084,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.allTargets": {
                         "markdownDescription": "Check all targets and tests (`--all-targets`). Defaults to\n`#rust-analyzer.cargo.allTargets#`.",
@@ -1010,7 +1097,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.command": {
                         "markdownDescription": "Cargo command to use for `cargo check`.",
@@ -1020,7 +1107,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.extraArgs": {
                         "markdownDescription": "Extra arguments for `cargo check`.",
@@ -1033,7 +1120,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.extraEnv": {
                         "markdownDescription": "Extra environment variables that will be set when running `cargo check`.\nExtends `#rust-analyzer.cargo.extraEnv#`.",
@@ -1043,7 +1130,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.features": {
                         "markdownDescription": "List of features to activate. Defaults to\n`#rust-analyzer.cargo.features#`.\n\nSet to `\"all\"` to pass `--all-features` to Cargo.",
@@ -1072,7 +1159,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.ignore": {
                         "markdownDescription": "List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.\n\nFor example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...",
@@ -1086,7 +1173,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.invocationStrategy": {
                         "markdownDescription": "Specifies the invocation strategy to use when running the check command.\nIf `per_workspace` is set, the command will be executed for each workspace.\nIf `once` is set, the command will be executed once.\nThis config only has an effect when `#rust-analyzer.check.overrideCommand#`\nis set.",
@@ -1104,7 +1191,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.noDefaultFeatures": {
                         "markdownDescription": "Whether to pass `--no-default-features` to Cargo. Defaults to\n`#rust-analyzer.cargo.noDefaultFeatures#`.",
@@ -1117,10 +1204,10 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.overrideCommand": {
-                        "markdownDescription": "Override the command rust-analyzer uses instead of `cargo check` for\ndiagnostics on save. The command is required to output json and\nshould therefore include `--message-format=json` or a similar option\n(if your client supports the `colorDiagnosticOutput` experimental\ncapability, you can use `--message-format=json-diagnostic-rendered-ansi`).\n\nIf you're changing this because you're using some tool wrapping\nCargo, you might also want to change\n`#rust-analyzer.cargo.buildScripts.overrideCommand#`.\n\nIf there are multiple linked projects/workspaces, this command is invoked for\neach of them, with the working directory being the workspace root\n(i.e., the folder containing the `Cargo.toml`). This can be overwritten\nby changing `#rust-analyzer.check.invocationStrategy#`.\n\nIf `$saved_file` is part of the command, rust-analyzer will pass\nthe absolute path of the saved file to the provided command. This is\nintended to be used with non-Cargo build systems.\nNote that `$saved_file` is experimental and may be removed in the future.\n\nAn example command would be:\n\n```bash\ncargo check --workspace --message-format=json --all-targets\n```\n.",
+                        "markdownDescription": "Override the command rust-analyzer uses instead of `cargo check` for\ndiagnostics on save. The command is required to output json and\nshould therefore include `--message-format=json` or a similar option\n(if your client supports the `colorDiagnosticOutput` experimental\ncapability, you can use `--message-format=json-diagnostic-rendered-ansi`).\n\nIf you're changing this because you're using some tool wrapping\nCargo, you might also want to change\n`#rust-analyzer.cargo.buildScripts.overrideCommand#`.\n\nIf there are multiple linked projects/workspaces, this command is invoked for\neach of them, with the working directory being the workspace root\n(i.e., the folder containing the `Cargo.toml`). This can be overwritten\nby changing `#rust-analyzer.check.invocationStrategy#`.\n\nIf `$saved_file` is part of the command, rust-analyzer will pass\nthe absolute path of the saved file to the provided command. This is\nintended to be used with non-Cargo build systems.\nNote that `$saved_file` is experimental and may be removed in the future.\n\nAn example command would be:\n\n```bash\ncargo check --workspace --message-format=json --all-targets\n```\n\nNote: The option must be specified as an array of command line arguments, with\nthe first argument being the name of the command to run.",
                         "default": null,
                         "type": [
                             "null",
@@ -1133,7 +1220,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.targets": {
                         "markdownDescription": "Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.\n\nCan be a single target, e.g. `\"x86_64-unknown-linux-gnu\"` or a list of targets, e.g.\n`[\"aarch64-apple-darwin\", \"x86_64-apple-darwin\"]`.\n\nAliased as `\"checkOnSave.targets\"`.",
@@ -1156,7 +1243,7 @@
                 }
             },
             {
-                "title": "check",
+                "title": "Check",
                 "properties": {
                     "rust-analyzer.check.workspace": {
                         "markdownDescription": "Whether `--workspace` should be passed to `cargo check`.\nIf false, `-p <package>` will be passed instead if applicable. In case it is not, no\ncheck will be performed.",
@@ -1166,50 +1253,50 @@
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.addSemicolonToUnit": {
-                        "markdownDescription": "Whether to automatically add a semicolon when completing unit-returning functions.\n\nIn `match` arms it completes a comma instead.",
+                        "markdownDescription": "Automatically add a semicolon when completing unit-returning functions.\n\nIn `match` arms it completes a comma instead.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.autoAwait.enable": {
-                        "markdownDescription": "Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.",
+                        "markdownDescription": "Show method calls and field accesses completions with `await` prefixed to them when\ncompleting on a future.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.autoIter.enable": {
-                        "markdownDescription": "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.",
+                        "markdownDescription": "Show method call completions with `iter()` or `into_iter()` prefixed to them when\ncompleting on a type that has them.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.autoimport.enable": {
-                        "markdownDescription": "Toggles the additional completions that automatically add imports when completed.\nNote that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.",
+                        "markdownDescription": "Show completions that automatically add imports when completed.\n\nNote that your client must specify the `additionalTextEdits` LSP client capability to\ntruly have this feature enabled.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.autoimport.exclude": {
-                        "markdownDescription": "A list of full paths to items to exclude from auto-importing completions.\n\nTraits in this list won't have their methods suggested in completions unless the trait\nis in scope.\n\nYou can either specify a string path which defaults to type \"always\" or use the more verbose\nform `{ \"path\": \"path::to::item\", type: \"always\" }`.\n\nFor traits the type \"methods\" can be used to only exclude the methods but not the trait itself.\n\nThis setting also inherits `#rust-analyzer.completion.excludeTraits#`.",
+                        "markdownDescription": "A list of full paths to items to exclude from auto-importing completions.\n\nTraits in this list won't have their methods suggested in completions unless the trait\nis in scope.\n\nYou can either specify a string path which defaults to type \"always\" or use the more\nverbose form `{ \"path\": \"path::to::item\", type: \"always\" }`.\n\nFor traits the type \"methods\" can be used to only exclude the methods but not the trait\nitself.\n\nThis setting also inherits `#rust-analyzer.completion.excludeTraits#`.",
                         "default": [
                             {
                                 "path": "core::borrow::Borrow",
@@ -1251,20 +1338,20 @@
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.autoself.enable": {
-                        "markdownDescription": "Toggles the additional completions that automatically show method calls and field accesses\nwith `self` prefixed to them when inside a method.",
+                        "markdownDescription": "Show method calls and field access completions with `self` prefixed to them when\ninside a method.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.callable.snippets": {
-                        "markdownDescription": "Whether to add parenthesis and argument snippets when completing function.",
+                        "markdownDescription": "Add parenthesis and argument snippets when completing function.",
                         "default": "fill_arguments",
                         "type": "string",
                         "enum": [
@@ -1281,10 +1368,10 @@
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.excludeTraits": {
-                        "markdownDescription": "A list of full paths to traits whose methods to exclude from completion.\n\nMethods 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`.\n\nNote that the trait themselves can still be completed.",
+                        "markdownDescription": "A list of full paths to traits whose methods to exclude from completion.\n\nMethods from these traits won't be completed, even if the trait is in scope. However,\nthey will still be suggested on expressions whose type is `dyn Trait`, `impl Trait` or\n`T where T: Trait`.\n\nNote that the trait themselves can still be completed.",
                         "default": [],
                         "type": "array",
                         "items": {
@@ -1294,27 +1381,27 @@
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.fullFunctionSignatures.enable": {
-                        "markdownDescription": "Whether to show full function/method signatures in completion docs.",
+                        "markdownDescription": "Show full function / method signatures in completion docs.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.hideDeprecated": {
-                        "markdownDescription": "Whether to omit deprecated items from autocompletion. By default they are marked as deprecated but not hidden.",
+                        "markdownDescription": "Omit deprecated items from completions. By default they are marked as deprecated but not\nhidden.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.limit": {
                         "markdownDescription": "Maximum number of completions to return. If `None`, the limit is infinite.",
@@ -1328,27 +1415,27 @@
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.postfix.enable": {
-                        "markdownDescription": "Whether to show postfix snippets like `dbg`, `if`, `not`, etc.",
+                        "markdownDescription": "Show postfix snippets like `dbg`, `if`, `not`, etc.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.privateEditable.enable": {
-                        "markdownDescription": "Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position.",
+                        "markdownDescription": "Show completions of private items and fields that are defined in the current workspace\neven if they are not visible at the current position.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.snippets.custom": {
                         "markdownDescription": "Custom completion snippets.",
@@ -1398,17 +1485,17 @@
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.termSearch.enable": {
-                        "markdownDescription": "Whether to enable term search based snippets like `Some(foo.bar().baz())`.",
+                        "markdownDescription": "Enable term search based snippets like `Some(foo.bar().baz())`.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "completion",
+                "title": "Completion",
                 "properties": {
                     "rust-analyzer.completion.termSearch.fuel": {
                         "markdownDescription": "Term search fuel in \"units of work\" for autocompletion (Defaults to 1000).",
@@ -1419,7 +1506,7 @@
                 }
             },
             {
-                "title": "diagnostics",
+                "title": "Diagnostics",
                 "properties": {
                     "rust-analyzer.diagnostics.disabled": {
                         "markdownDescription": "List of rust-analyzer diagnostics to disable.",
@@ -1433,50 +1520,50 @@
                 }
             },
             {
-                "title": "diagnostics",
+                "title": "Diagnostics",
                 "properties": {
                     "rust-analyzer.diagnostics.enable": {
-                        "markdownDescription": "Whether to show native rust-analyzer diagnostics.",
+                        "markdownDescription": "Show native rust-analyzer diagnostics.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "diagnostics",
+                "title": "Diagnostics",
                 "properties": {
                     "rust-analyzer.diagnostics.experimental.enable": {
-                        "markdownDescription": "Whether to show experimental rust-analyzer diagnostics that might\nhave more false positives than usual.",
+                        "markdownDescription": "Show experimental rust-analyzer diagnostics that might have more false positives than\nusual.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "diagnostics",
+                "title": "Diagnostics",
                 "properties": {
                     "rust-analyzer.diagnostics.remapPrefix": {
-                        "markdownDescription": "Map of prefixes to be substituted when parsing diagnostic file paths.\nThis should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`.",
+                        "markdownDescription": "Map of prefixes to be substituted when parsing diagnostic file paths. This should be the\nreverse mapping of what is passed to `rustc` as `--remap-path-prefix`.",
                         "default": {},
                         "type": "object"
                     }
                 }
             },
             {
-                "title": "diagnostics",
+                "title": "Diagnostics",
                 "properties": {
                     "rust-analyzer.diagnostics.styleLints.enable": {
-                        "markdownDescription": "Whether to run additional style lints.",
+                        "markdownDescription": "Run additional style lints.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "diagnostics",
+                "title": "Diagnostics",
                 "properties": {
                     "rust-analyzer.diagnostics.warningsAsHint": {
-                        "markdownDescription": "List of warnings that should be displayed with hint severity.\n\nThe warnings will be indicated by faded text or three dots in code\nand will not show up in the `Problems Panel`.",
+                        "markdownDescription": "List of warnings that should be displayed with hint severity.\n\nThe warnings will be indicated by faded text or three dots in code and will not show up\nin the `Problems Panel`.",
                         "default": [],
                         "type": "array",
                         "items": {
@@ -1486,10 +1573,10 @@
                 }
             },
             {
-                "title": "diagnostics",
+                "title": "Diagnostics",
                 "properties": {
                     "rust-analyzer.diagnostics.warningsAsInfo": {
-                        "markdownDescription": "List of warnings that should be displayed with info severity.\n\nThe warnings will be indicated by a blue squiggly underline in code\nand a blue icon in the `Problems Panel`.",
+                        "markdownDescription": "List of warnings that should be displayed with info severity.\n\nThe warnings will be indicated by a blue squiggly underline in code and a blue icon in\nthe `Problems Panel`.",
                         "default": [],
                         "type": "array",
                         "items": {
@@ -1499,10 +1586,10 @@
                 }
             },
             {
-                "title": "files",
+                "title": "Files",
                 "properties": {
                     "rust-analyzer.files.exclude": {
-                        "markdownDescription": "These paths (file/directories) will be ignored by rust-analyzer. They are\nrelative to the workspace root, and globs are not supported. You may\nalso need to add the folders to Code's `files.watcherExclude`.",
+                        "markdownDescription": "List of files to ignore\n\nThese paths (file/directories) will be ignored by rust-analyzer. They are relative to\nthe workspace root, and globs are not supported. You may also need to add the folders to\nCode's `files.watcherExclude`.",
                         "default": [],
                         "type": "array",
                         "items": {
@@ -1512,7 +1599,7 @@
                 }
             },
             {
-                "title": "files",
+                "title": "Files",
                 "properties": {
                     "rust-analyzer.files.watcher": {
                         "markdownDescription": "Controls file watching implementation.",
@@ -1530,167 +1617,167 @@
                 }
             },
             {
-                "title": "highlightRelated",
+                "title": "Highlight Related",
                 "properties": {
                     "rust-analyzer.highlightRelated.branchExitPoints.enable": {
-                        "markdownDescription": "Enables highlighting of related return values while the cursor is on any `match`, `if`, or match arm arrow (`=>`).",
+                        "markdownDescription": "Highlight related return values while the cursor is on any `match`, `if`, or match arm\narrow (`=>`).",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "highlightRelated",
+                "title": "Highlight Related",
                 "properties": {
                     "rust-analyzer.highlightRelated.breakPoints.enable": {
-                        "markdownDescription": "Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords.",
+                        "markdownDescription": "Highlight related references while the cursor is on `break`, `loop`, `while`, or `for`\nkeywords.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "highlightRelated",
+                "title": "Highlight Related",
                 "properties": {
                     "rust-analyzer.highlightRelated.closureCaptures.enable": {
-                        "markdownDescription": "Enables highlighting of all captures of a closure while the cursor is on the `|` or move keyword of a closure.",
+                        "markdownDescription": "Highlight all captures of a closure while the cursor is on the `|` or move keyword of a closure.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "highlightRelated",
+                "title": "Highlight Related",
                 "properties": {
                     "rust-analyzer.highlightRelated.exitPoints.enable": {
-                        "markdownDescription": "Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`).",
+                        "markdownDescription": "Highlight all exit points while the cursor is on any `return`, `?`, `fn`, or return type\narrow (`->`).",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "highlightRelated",
+                "title": "Highlight Related",
                 "properties": {
                     "rust-analyzer.highlightRelated.references.enable": {
-                        "markdownDescription": "Enables highlighting of related references while the cursor is on any identifier.",
+                        "markdownDescription": "Highlight related references while the cursor is on any identifier.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "highlightRelated",
+                "title": "Highlight Related",
                 "properties": {
                     "rust-analyzer.highlightRelated.yieldPoints.enable": {
-                        "markdownDescription": "Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords.",
+                        "markdownDescription": "Highlight all break points for a loop or block context while the cursor is on any\n`async` or `await` keywords.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.actions.debug.enable": {
-                        "markdownDescription": "Whether to show `Debug` action. Only applies when\n`#rust-analyzer.hover.actions.enable#` is set.",
+                        "markdownDescription": "Show `Debug` action. Only applies when `#rust-analyzer.hover.actions.enable#` is set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.actions.enable": {
-                        "markdownDescription": "Whether to show HoverActions in Rust files.",
+                        "markdownDescription": "Show HoverActions in Rust files.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.actions.gotoTypeDef.enable": {
-                        "markdownDescription": "Whether to show `Go to Type Definition` action. Only applies when\n`#rust-analyzer.hover.actions.enable#` is set.",
+                        "markdownDescription": "Show `Go to Type Definition` action. Only applies when\n`#rust-analyzer.hover.actions.enable#` is set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.actions.implementations.enable": {
-                        "markdownDescription": "Whether to show `Implementations` action. Only applies when\n`#rust-analyzer.hover.actions.enable#` is set.",
+                        "markdownDescription": "Show `Implementations` action. Only applies when `#rust-analyzer.hover.actions.enable#`\nis set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.actions.references.enable": {
-                        "markdownDescription": "Whether to show `References` action. Only applies when\n`#rust-analyzer.hover.actions.enable#` is set.",
+                        "markdownDescription": "Show `References` action. Only applies when `#rust-analyzer.hover.actions.enable#` is\nset.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.actions.run.enable": {
-                        "markdownDescription": "Whether to show `Run` action. Only applies when\n`#rust-analyzer.hover.actions.enable#` is set.",
+                        "markdownDescription": "Show `Run` action. Only applies when `#rust-analyzer.hover.actions.enable#` is set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.actions.updateTest.enable": {
-                        "markdownDescription": "Whether to show `Update Test` action. Only applies when\n`#rust-analyzer.hover.actions.enable#` and `#rust-analyzer.hover.actions.run.enable#` are set.",
+                        "markdownDescription": "Show `Update Test` action. Only applies when `#rust-analyzer.hover.actions.enable#` and\n`#rust-analyzer.hover.actions.run.enable#` are set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.documentation.enable": {
-                        "markdownDescription": "Whether to show documentation on hover.",
+                        "markdownDescription": "Show documentation on hover.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.documentation.keywords.enable": {
-                        "markdownDescription": "Whether to show keyword hover popups. Only applies when\n`#rust-analyzer.hover.documentation.enable#` is set.",
+                        "markdownDescription": "Show keyword hover popups. Only applies when\n`#rust-analyzer.hover.documentation.enable#` is set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.dropGlue.enable": {
-                        "markdownDescription": "Whether to show drop glue information on hover.",
+                        "markdownDescription": "Show drop glue information on hover.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.links.enable": {
                         "markdownDescription": "Use markdown syntax for links on hover.",
@@ -1700,10 +1787,10 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.maxSubstitutionLength": {
-                        "markdownDescription": "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.\n\nThis 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.\n\nThe default is 20 characters.",
+                        "markdownDescription": "Show what types are used as generic arguments in calls etc. on hover, and limit the max\nlength to show such types, beyond which they will be shown with ellipsis.\n\nThis can take three values: `null` means \"unlimited\", the string `\"hide\"` means to not\nshow generic substitutions at all, and a number means to limit them to X characters.\n\nThe default is 20 characters.",
                         "default": 20,
                         "anyOf": [
                             {
@@ -1723,7 +1810,7 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.memoryLayout.alignment": {
                         "markdownDescription": "How to render the align information in a memory layout hover.",
@@ -1750,17 +1837,17 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.memoryLayout.enable": {
-                        "markdownDescription": "Whether to show memory layout data on hover.",
+                        "markdownDescription": "Show memory layout data on hover.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.memoryLayout.niches": {
                         "markdownDescription": "How to render the niche information in a memory layout hover.",
@@ -1773,7 +1860,7 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.memoryLayout.offset": {
                         "markdownDescription": "How to render the offset information in a memory layout hover.",
@@ -1800,7 +1887,7 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.memoryLayout.padding": {
                         "markdownDescription": "How to render the padding information in a memory layout hover.",
@@ -1827,7 +1914,7 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.memoryLayout.size": {
                         "markdownDescription": "How to render the size information in a memory layout hover.",
@@ -1854,7 +1941,7 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.show.enumVariants": {
                         "markdownDescription": "How many variants of an enum to display when hovering on. Show none if empty.",
@@ -1868,10 +1955,10 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.show.fields": {
-                        "markdownDescription": "How many fields of a struct, variant or union to display when hovering on. Show none if empty.",
+                        "markdownDescription": "How many fields of a struct, variant or union to display when hovering on. Show none if\nempty.",
                         "default": 5,
                         "type": [
                             "null",
@@ -1882,7 +1969,7 @@
                 }
             },
             {
-                "title": "hover",
+                "title": "Hover",
                 "properties": {
                     "rust-analyzer.hover.show.traitAssocItems": {
                         "markdownDescription": "How many associated items of a trait to display when hovering a trait.",
@@ -1896,17 +1983,17 @@
                 }
             },
             {
-                "title": "imports",
+                "title": "Imports",
                 "properties": {
                     "rust-analyzer.imports.granularity.enforce": {
-                        "markdownDescription": "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.",
+                        "markdownDescription": "Enforce the import granularity setting for all files. If set to false rust-analyzer will\ntry to keep import styles consistent per file.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "imports",
+                "title": "Imports",
                 "properties": {
                     "rust-analyzer.imports.granularity.group": {
                         "markdownDescription": "How imports should be grouped into use statements.",
@@ -1930,27 +2017,27 @@
                 }
             },
             {
-                "title": "imports",
+                "title": "Imports",
                 "properties": {
                     "rust-analyzer.imports.group.enable": {
-                        "markdownDescription": "Group inserted imports by the [following order](https://rust-analyzer.github.io/book/features.html#auto-import). Groups are separated by newlines.",
+                        "markdownDescription": "Group inserted imports by the [following\norder](https://rust-analyzer.github.io/book/features.html#auto-import). Groups are\nseparated by newlines.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "imports",
+                "title": "Imports",
                 "properties": {
                     "rust-analyzer.imports.merge.glob": {
-                        "markdownDescription": "Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.",
+                        "markdownDescription": "Allow import insertion to merge new imports into single path glob imports like `use\nstd::fmt::*;`.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "imports",
+                "title": "Imports",
                 "properties": {
                     "rust-analyzer.imports.preferNoStd": {
                         "markdownDescription": "Prefer to unconditionally use imports of the core and alloc crate, over the std crate.",
@@ -1960,17 +2047,17 @@
                 }
             },
             {
-                "title": "imports",
+                "title": "Imports",
                 "properties": {
                     "rust-analyzer.imports.preferPrelude": {
-                        "markdownDescription": "Whether to prefer import paths containing a `prelude` module.",
+                        "markdownDescription": "Prefer import paths containing a `prelude` module.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "imports",
+                "title": "Imports",
                 "properties": {
                     "rust-analyzer.imports.prefix": {
                         "markdownDescription": "The path structure for newly inserted paths to use.",
@@ -1990,47 +2077,47 @@
                 }
             },
             {
-                "title": "imports",
+                "title": "Imports",
                 "properties": {
                     "rust-analyzer.imports.prefixExternPrelude": {
-                        "markdownDescription": "Whether to prefix external (including std, core) crate imports with `::`. e.g. \"use ::std::io::Read;\".",
+                        "markdownDescription": "Prefix external (including std, core) crate imports with `::`.\n\nE.g. `use ::std::io::Read;`.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.bindingModeHints.enable": {
-                        "markdownDescription": "Whether to show inlay type hints for binding modes.",
+                        "markdownDescription": "Show inlay type hints for binding modes.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.chainingHints.enable": {
-                        "markdownDescription": "Whether to show inlay type hints for method chains.",
+                        "markdownDescription": "Show inlay type hints for method chains.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.closingBraceHints.enable": {
-                        "markdownDescription": "Whether to show inlay hints after a closing `}` to indicate what item it belongs to.",
+                        "markdownDescription": "Show inlay hints after a closing `}` to indicate what item it belongs to.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.closingBraceHints.minLines": {
                         "markdownDescription": "Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1\nto always show them).",
@@ -2041,20 +2128,20 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.closureCaptureHints.enable": {
-                        "markdownDescription": "Whether to show inlay hints for closure captures.",
+                        "markdownDescription": "Show inlay hints for closure captures.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.closureReturnTypeHints.enable": {
-                        "markdownDescription": "Whether to show inlay type hints for return types of closures.",
+                        "markdownDescription": "Show inlay type hints for return types of closures.",
                         "default": "never",
                         "type": "string",
                         "enum": [
@@ -2071,7 +2158,7 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.closureStyle": {
                         "markdownDescription": "Closure notation in type and chaining inlay hints.",
@@ -2093,10 +2180,10 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.discriminantHints.enable": {
-                        "markdownDescription": "Whether to show enum variant discriminant hints.",
+                        "markdownDescription": "Show enum variant discriminant hints.",
                         "default": "never",
                         "type": "string",
                         "enum": [
@@ -2113,10 +2200,10 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.expressionAdjustmentHints.enable": {
-                        "markdownDescription": "Whether to show inlay hints for type adjustments.",
+                        "markdownDescription": "Show inlay hints for type adjustments.",
                         "default": "never",
                         "type": "string",
                         "enum": [
@@ -2133,20 +2220,20 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe": {
-                        "markdownDescription": "Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.",
+                        "markdownDescription": "Hide inlay hints for type adjustments outside of `unsafe` blocks.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.expressionAdjustmentHints.mode": {
-                        "markdownDescription": "Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).",
+                        "markdownDescription": "Show inlay hints as postfix ops (`.*` instead of `*`, etc).",
                         "default": "prefix",
                         "type": "string",
                         "enum": [
@@ -2165,60 +2252,60 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.genericParameterHints.const.enable": {
-                        "markdownDescription": "Whether to show const generic parameter name inlay hints.",
+                        "markdownDescription": "Show const generic parameter name inlay hints.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.genericParameterHints.lifetime.enable": {
-                        "markdownDescription": "Whether to show generic lifetime parameter name inlay hints.",
+                        "markdownDescription": "Show generic lifetime parameter name inlay hints.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.genericParameterHints.type.enable": {
-                        "markdownDescription": "Whether to show generic type parameter name inlay hints.",
+                        "markdownDescription": "Show generic type parameter name inlay hints.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.implicitDrops.enable": {
-                        "markdownDescription": "Whether to show implicit drop hints.",
+                        "markdownDescription": "Show implicit drop hints.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.implicitSizedBoundHints.enable": {
-                        "markdownDescription": "Whether to show inlay hints for the implied type parameter `Sized` bound.",
+                        "markdownDescription": "Show inlay hints for the implied type parameter `Sized` bound.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.lifetimeElisionHints.enable": {
-                        "markdownDescription": "Whether to show inlay type hints for elided lifetimes in function signatures.",
+                        "markdownDescription": "Show inlay type hints for elided lifetimes in function signatures.",
                         "default": "never",
                         "type": "string",
                         "enum": [
@@ -2235,17 +2322,17 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames": {
-                        "markdownDescription": "Whether to prefer using parameter names as the name for elided lifetime hints if possible.",
+                        "markdownDescription": "Prefer using parameter names as the name for elided lifetime hints if possible.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.maxLength": {
                         "markdownDescription": "Maximum length for inlay hints. Set to null to have an unlimited length.",
@@ -2259,30 +2346,30 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.parameterHints.enable": {
-                        "markdownDescription": "Whether to show function parameter name inlay hints at the call\nsite.",
+                        "markdownDescription": "Show function parameter name inlay hints at the call site.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.rangeExclusiveHints.enable": {
-                        "markdownDescription": "Whether to show exclusive range inlay hints.",
+                        "markdownDescription": "Show exclusive range inlay hints.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.reborrowHints.enable": {
-                        "markdownDescription": "Whether to show inlay hints for compiler inserted reborrows.\nThis setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.",
+                        "markdownDescription": "Show inlay hints for compiler inserted reborrows.\n\nThis setting is deprecated in favor of\n#rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.",
                         "default": "never",
                         "type": "string",
                         "enum": [
@@ -2299,7 +2386,7 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.renderColons": {
                         "markdownDescription": "Whether to render leading colons for type hints, and trailing colons for parameter hints.",
@@ -2309,57 +2396,57 @@
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.typeHints.enable": {
-                        "markdownDescription": "Whether to show inlay type hints for variables.",
+                        "markdownDescription": "Show inlay type hints for variables.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.typeHints.hideClosureInitialization": {
-                        "markdownDescription": "Whether to hide inlay type hints for `let` statements that initialize to a closure.\nOnly applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`.",
+                        "markdownDescription": "Hide inlay type hints for `let` statements that initialize to a closure.\n\nOnly applies to closures with blocks, same as\n`#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.typeHints.hideClosureParameter": {
-                        "markdownDescription": "Whether to hide inlay parameter type hints for closures.",
+                        "markdownDescription": "Hide inlay parameter type hints for closures.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "inlayHints",
+                "title": "Inlay Hints",
                 "properties": {
                     "rust-analyzer.inlayHints.typeHints.hideNamedConstructor": {
-                        "markdownDescription": "Whether to hide inlay type hints for constructors.",
+                        "markdownDescription": "Hide inlay type hints for constructors.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "interpret",
+                "title": "Interpret",
                 "properties": {
                     "rust-analyzer.interpret.tests": {
-                        "markdownDescription": "Enables the experimental support for interpreting tests.",
+                        "markdownDescription": "Enable the experimental support for interpreting tests.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "joinLines",
+                "title": "Join Lines",
                 "properties": {
                     "rust-analyzer.joinLines.joinAssignments": {
                         "markdownDescription": "Join lines merges consecutive declaration and initialization of an assignment.",
@@ -2369,7 +2456,7 @@
                 }
             },
             {
-                "title": "joinLines",
+                "title": "Join Lines",
                 "properties": {
                     "rust-analyzer.joinLines.joinElseIf": {
                         "markdownDescription": "Join lines inserts else between consecutive ifs.",
@@ -2379,7 +2466,7 @@
                 }
             },
             {
-                "title": "joinLines",
+                "title": "Join Lines",
                 "properties": {
                     "rust-analyzer.joinLines.removeTrailingComma": {
                         "markdownDescription": "Join lines removes trailing commas.",
@@ -2389,7 +2476,7 @@
                 }
             },
             {
-                "title": "joinLines",
+                "title": "Join Lines",
                 "properties": {
                     "rust-analyzer.joinLines.unwrapTrivialBlock": {
                         "markdownDescription": "Join lines unwraps trivial blocks.",
@@ -2399,37 +2486,37 @@
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.debug.enable": {
-                        "markdownDescription": "Whether to show `Debug` lens. Only applies when\n`#rust-analyzer.lens.enable#` is set.",
+                        "markdownDescription": "Show `Debug` lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.enable": {
-                        "markdownDescription": "Whether to show CodeLens in Rust files.",
+                        "markdownDescription": "Show CodeLens in Rust files.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.implementations.enable": {
-                        "markdownDescription": "Whether to show `Implementations` lens. Only applies when\n`#rust-analyzer.lens.enable#` is set.",
+                        "markdownDescription": "Show `Implementations` lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.location": {
                         "markdownDescription": "Where to render annotations.",
@@ -2447,70 +2534,70 @@
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.references.adt.enable": {
-                        "markdownDescription": "Whether to show `References` lens for Struct, Enum, and Union.\nOnly applies when `#rust-analyzer.lens.enable#` is set.",
+                        "markdownDescription": "Show `References` lens for Struct, Enum, and Union. Only applies when\n`#rust-analyzer.lens.enable#` is set.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.references.enumVariant.enable": {
-                        "markdownDescription": "Whether to show `References` lens for Enum Variants.\nOnly applies when `#rust-analyzer.lens.enable#` is set.",
+                        "markdownDescription": "Show `References` lens for Enum Variants. Only applies when\n`#rust-analyzer.lens.enable#` is set.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.references.method.enable": {
-                        "markdownDescription": "Whether to show `Method References` lens. Only applies when\n`#rust-analyzer.lens.enable#` is set.",
+                        "markdownDescription": "Show `Method References` lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.references.trait.enable": {
-                        "markdownDescription": "Whether to show `References` lens for Trait.\nOnly applies when `#rust-analyzer.lens.enable#` is set.",
+                        "markdownDescription": "Show `References` lens for Trait. Only applies when `#rust-analyzer.lens.enable#` is\nset.",
                         "default": false,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.run.enable": {
-                        "markdownDescription": "Whether to show `Run` lens. Only applies when\n`#rust-analyzer.lens.enable#` is set.",
+                        "markdownDescription": "Show `Run` lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "lens",
+                "title": "Lens",
                 "properties": {
                     "rust-analyzer.lens.updateTest.enable": {
-                        "markdownDescription": "Whether to show `Update Test` lens. Only applies when\n`#rust-analyzer.lens.enable#` and `#rust-analyzer.lens.run.enable#` are set.",
+                        "markdownDescription": "Show `Update Test` lens. Only applies when `#rust-analyzer.lens.enable#` and\n`#rust-analyzer.lens.run.enable#` are set.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "general",
+                "title": "rust-analyzer",
                 "properties": {
                     "rust-analyzer.linkedProjects": {
-                        "markdownDescription": "Disable project auto-discovery in favor of explicitly specified set\nof projects.\n\nElements must be paths pointing to `Cargo.toml`,\n`rust-project.json`, `.rs` files (which will be treated as standalone files) or JSON\nobjects in `rust-project.json` format.",
+                        "markdownDescription": "Disable project auto-discovery in favor of explicitly specified set of projects.\n\nElements must be paths pointing to `Cargo.toml`, `rust-project.json`, `.rs` files (which\nwill be treated as standalone files) or JSON objects in `rust-project.json` format.",
                         "default": [],
                         "type": "array",
                         "items": {
@@ -2523,7 +2610,7 @@
                 }
             },
             {
-                "title": "lru",
+                "title": "Lru",
                 "properties": {
                     "rust-analyzer.lru.capacity": {
                         "markdownDescription": "Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.",
@@ -2538,30 +2625,30 @@
                 }
             },
             {
-                "title": "lru",
+                "title": "Lru",
                 "properties": {
                     "rust-analyzer.lru.query.capacities": {
-                        "markdownDescription": "Sets the LRU capacity of the specified queries.",
+                        "markdownDescription": "The LRU capacity of the specified queries.",
                         "default": {},
                         "type": "object"
                     }
                 }
             },
             {
-                "title": "notifications",
+                "title": "Notifications",
                 "properties": {
                     "rust-analyzer.notifications.cargoTomlNotFound": {
-                        "markdownDescription": "Whether to show `can't find Cargo.toml` error message.",
+                        "markdownDescription": "Show `can't find Cargo.toml` error message.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "general",
+                "title": "rust-analyzer",
                 "properties": {
                     "rust-analyzer.numThreads": {
-                        "markdownDescription": "How many worker threads in the main loop. The default `null` means to pick automatically.",
+                        "markdownDescription": "The number of worker threads in the main loop. The default `null` means to pick\nautomatically.",
                         "default": null,
                         "anyOf": [
                             {
@@ -2588,7 +2675,7 @@
                 }
             },
             {
-                "title": "procMacro",
+                "title": "Proc Macro",
                 "properties": {
                     "rust-analyzer.procMacro.attributes.enable": {
                         "markdownDescription": "Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.",
@@ -2598,7 +2685,7 @@
                 }
             },
             {
-                "title": "procMacro",
+                "title": "Proc Macro",
                 "properties": {
                     "rust-analyzer.procMacro.enable": {
                         "markdownDescription": "Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`.",
@@ -2608,7 +2695,7 @@
                 }
             },
             {
-                "title": "procMacro",
+                "title": "Proc Macro",
                 "properties": {
                     "rust-analyzer.procMacro.ignored": {
                         "markdownDescription": "These proc-macros will be ignored when trying to expand them.\n\nThis config takes a map of crate names with the exported proc-macro names to ignore as values.",
@@ -2618,7 +2705,7 @@
                 }
             },
             {
-                "title": "procMacro",
+                "title": "Proc Macro",
                 "properties": {
                     "rust-analyzer.procMacro.server": {
                         "markdownDescription": "Internal config, path to proc-macro server executable.",
@@ -2631,7 +2718,7 @@
                 }
             },
             {
-                "title": "references",
+                "title": "References",
                 "properties": {
                     "rust-analyzer.references.excludeImports": {
                         "markdownDescription": "Exclude imports from find-all-references.",
@@ -2641,7 +2728,7 @@
                 }
             },
             {
-                "title": "references",
+                "title": "References",
                 "properties": {
                     "rust-analyzer.references.excludeTests": {
                         "markdownDescription": "Exclude tests from find-all-references and call-hierarchy.",
@@ -2651,7 +2738,7 @@
                 }
             },
             {
-                "title": "runnables",
+                "title": "Runnables",
                 "properties": {
                     "rust-analyzer.runnables.command": {
                         "markdownDescription": "Command to be executed instead of 'cargo' for runnables.",
@@ -2664,7 +2751,7 @@
                 }
             },
             {
-                "title": "runnables",
+                "title": "Runnables",
                 "properties": {
                     "rust-analyzer.runnables.extraArgs": {
                         "markdownDescription": "Additional arguments to be passed to cargo for runnables such as\ntests or binaries. For example, it may be `--release`.",
@@ -2677,7 +2764,7 @@
                 }
             },
             {
-                "title": "runnables",
+                "title": "Runnables",
                 "properties": {
                     "rust-analyzer.runnables.extraTestBinaryArgs": {
                         "markdownDescription": "Additional arguments to be passed through Cargo to launched tests, benchmarks, or\ndoc-tests.\n\nUnless the launched target uses a\n[custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field),\nthey will end up being interpreted as options to\n[`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).",
@@ -2692,7 +2779,7 @@
                 }
             },
             {
-                "title": "rustc",
+                "title": "Rustc",
                 "properties": {
                     "rust-analyzer.rustc.source": {
                         "markdownDescription": "Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private\nprojects, or \"discover\" to try to automatically find it if the `rustc-dev` component\nis installed.\n\nAny project which uses rust-analyzer with the rustcPrivate\ncrates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it.\n\nThis option does not take effect until rust-analyzer is restarted.",
@@ -2705,7 +2792,7 @@
                 }
             },
             {
-                "title": "rustfmt",
+                "title": "Rustfmt",
                 "properties": {
                     "rust-analyzer.rustfmt.extraArgs": {
                         "markdownDescription": "Additional arguments to `rustfmt`.",
@@ -2718,10 +2805,10 @@
                 }
             },
             {
-                "title": "rustfmt",
+                "title": "Rustfmt",
                 "properties": {
                     "rust-analyzer.rustfmt.overrideCommand": {
-                        "markdownDescription": "Advanced option, fully override the command rust-analyzer uses for\nformatting. This should be the equivalent of `rustfmt` here, and\nnot that of `cargo fmt`. The file contents will be passed on the\nstandard input and the formatted result will be read from the\nstandard output.",
+                        "markdownDescription": "Advanced option, fully override the command rust-analyzer uses for\nformatting. This should be the equivalent of `rustfmt` here, and\nnot that of `cargo fmt`. The file contents will be passed on the\nstandard input and the formatted result will be read from the\nstandard output.\n\nNote: The option must be specified as an array of command line arguments, with\nthe first argument being the name of the command to run.",
                         "default": null,
                         "type": [
                             "null",
@@ -2734,7 +2821,7 @@
                 }
             },
             {
-                "title": "rustfmt",
+                "title": "Rustfmt",
                 "properties": {
                     "rust-analyzer.rustfmt.rangeFormatting.enable": {
                         "markdownDescription": "Enables the use of rustfmt's unstable range formatting command for the\n`textDocument/rangeFormatting` request. The rustfmt option is unstable and only\navailable on a nightly build.",
@@ -2744,7 +2831,7 @@
                 }
             },
             {
-                "title": "semanticHighlighting",
+                "title": "Semantic Highlighting",
                 "properties": {
                     "rust-analyzer.semanticHighlighting.doc.comment.inject.enable": {
                         "markdownDescription": "Inject additional highlighting into doc comments.\n\nWhen enabled, rust-analyzer will highlight rust source in doc comments as well as intra\ndoc links.",
@@ -2754,17 +2841,17 @@
                 }
             },
             {
-                "title": "semanticHighlighting",
+                "title": "Semantic Highlighting",
                 "properties": {
                     "rust-analyzer.semanticHighlighting.nonStandardTokens": {
-                        "markdownDescription": "Whether the server is allowed to emit non-standard tokens and modifiers.",
+                        "markdownDescription": "Emit non-standard tokens and modifiers\n\nWhen enabled, rust-analyzer will emit tokens and modifiers that are not part of the\nstandard set of semantic tokens.",
                         "default": true,
                         "type": "boolean"
                     }
                 }
             },
             {
-                "title": "semanticHighlighting",
+                "title": "Semantic Highlighting",
                 "properties": {
                     "rust-analyzer.semanticHighlighting.operator.enable": {
                         "markdownDescription": "Use semantic tokens for operators.\n\nWhen disabled, rust-analyzer will emit semantic tokens only for operator tokens when\nthey are tagged with modifiers.",
@@ -2774,7 +2861,7 @@
                 }
             },
             {
-                "title": "semanticHighlighting",
+                "title": "Semantic Highlighting",
                 "properties": {
                     "rust-analyzer.semanticHighlighting.operator.specialization.enable": {
                         "markdownDescription": "Use specialized semantic tokens for operators.\n\nWhen enabled, rust-analyzer will emit special token types for operator tokens instead\nof the generic `operator` token type.",
@@ -2784,7 +2871,7 @@
                 }
             },
             {
-                "title": "semanticHighlighting",
+                "title": "Semantic Highlighting",
                 "properties": {
                     "rust-analyzer.semanticHighlighting.punctuation.enable": {
                         "markdownDescription": "Use semantic tokens for punctuation.\n\nWhen disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when\nthey are tagged with modifiers or have a special role.",
@@ -2794,7 +2881,7 @@
                 }
             },
             {
-                "title": "semanticHighlighting",
+                "title": "Semantic Highlighting",
                 "properties": {
                     "rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang": {
                         "markdownDescription": "When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro\ncalls.",
@@ -2804,7 +2891,7 @@
                 }
             },
             {
-                "title": "semanticHighlighting",
+                "title": "Semantic Highlighting",
                 "properties": {
                     "rust-analyzer.semanticHighlighting.punctuation.specialization.enable": {
                         "markdownDescription": "Use specialized semantic tokens for punctuation.\n\nWhen enabled, rust-analyzer will emit special token types for punctuation tokens instead\nof the generic `punctuation` token type.",
@@ -2814,7 +2901,7 @@
                 }
             },
             {
-                "title": "semanticHighlighting",
+                "title": "Semantic Highlighting",
                 "properties": {
                     "rust-analyzer.semanticHighlighting.strings.enable": {
                         "markdownDescription": "Use semantic tokens for strings.\n\nIn some editors (e.g. vscode) semantic tokens override other highlighting grammars.\nBy disabling semantic tokens for strings, other grammars can be used to highlight\ntheir contents.",
@@ -2824,7 +2911,7 @@
                 }
             },
             {
-                "title": "signatureInfo",
+                "title": "Signature Info",
                 "properties": {
                     "rust-analyzer.signatureInfo.detail": {
                         "markdownDescription": "Show full signature of the callable. Only shows parameters if disabled.",
@@ -2842,7 +2929,7 @@
                 }
             },
             {
-                "title": "signatureInfo",
+                "title": "Signature Info",
                 "properties": {
                     "rust-analyzer.signatureInfo.documentation.enable": {
                         "markdownDescription": "Show documentation.",
@@ -2852,10 +2939,10 @@
                 }
             },
             {
-                "title": "typing",
+                "title": "Typing",
                 "properties": {
                     "rust-analyzer.typing.triggerChars": {
-                        "markdownDescription": "Specify the characters allowed to invoke special on typing triggers.\n- typing `=` after `let` tries to smartly add `;` if `=` is followed by an existing expression\n- typing `=` between two expressions adds `;` when in statement position\n- typing `=` to turn an assignment into an equality comparison removes `;` when in expression position\n- typing `.` in a chain method call auto-indents\n- typing `{` or `(` in front of an expression inserts a closing `}` or `)` after the expression\n- typing `{` in a use item adds a closing `}` in the right place\n- typing `>` to complete a return type `->` will insert a whitespace after it\n- typing `<` in a path or type position inserts a closing `>` after the path or type.",
+                        "markdownDescription": "Specify the characters allowed to invoke special on typing triggers.\n\n- typing `=` after `let` tries to smartly add `;` if `=` is followed by an existing\n    expression\n- typing `=` between two expressions adds `;` when in statement position\n- typing `=` to turn an assignment into an equality comparison removes `;` when in\n    expression position\n- typing `.` in a chain method call auto-indents\n- typing `{` or `(` in front of an expression inserts a closing `}` or `)` after the\n    expression\n- typing `{` in a use item adds a closing `}` in the right place\n- typing `>` to complete a return type `->` will insert a whitespace after it\n- typing `<` in a path or type position inserts a closing `>` after the path or type.",
                         "default": "=.",
                         "type": [
                             "null",
@@ -2865,7 +2952,7 @@
                 }
             },
             {
-                "title": "vfs",
+                "title": "Vfs",
                 "properties": {
                     "rust-analyzer.vfs.extraIncludes": {
                         "markdownDescription": "Additional paths to include in the VFS. Generally for code that is\ngenerated or otherwise managed by a build system outside of Cargo,\nthough Cargo might be the eventual consumer.",
@@ -2878,10 +2965,10 @@
                 }
             },
             {
-                "title": "workspace",
+                "title": "Workspace",
                 "properties": {
                     "rust-analyzer.workspace.discoverConfig": {
-                        "markdownDescription": "Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].\n\n[`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`.\n`progress_label` is used for the title in progress indicators, whereas `files_to_watch`\nis used to determine which build system-specific files should be watched in order to\nreload rust-analyzer.\n\nBelow is an example of a valid configuration:\n```json\n\"rust-analyzer.workspace.discoverConfig\": {\n        \"command\": [\n                \"rust-project\",\n                \"develop-json\"\n        ],\n        \"progressLabel\": \"rust-analyzer\",\n        \"filesToWatch\": [\n                \"BUCK\"\n        ]\n}\n```\n\n## On `DiscoverWorkspaceConfig::command`\n\n**Warning**: This format is provisional and subject to change.\n\n[`DiscoverWorkspaceConfig::command`] *must* return a JSON object\ncorresponding to `DiscoverProjectData::Finished`:\n\n```norun\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(tag = \"kind\")]\n#[serde(rename_all = \"snake_case\")]\nenum DiscoverProjectData {\n        Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },\n        Error { error: String, source: Option<String> },\n        Progress { message: String },\n}\n```\n\nAs JSON, `DiscoverProjectData::Finished` is:\n\n```json\n{\n        // the internally-tagged representation of the enum.\n        \"kind\": \"finished\",\n        // the file used by a non-Cargo build system to define\n        // a package or target.\n        \"buildfile\": \"rust-analyzer/BUILD\",\n        // the contents of a rust-project.json, elided for brevity\n        \"project\": {\n                \"sysroot\": \"foo\",\n                \"crates\": []\n        }\n}\n```\n\nIt is encouraged, but not required, to use the other variants on\n`DiscoverProjectData` to provide a more polished end-user experience.\n\n`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`,\nwhich will be substituted with the JSON-serialized form of the following\nenum:\n\n```norun\n#[derive(PartialEq, Clone, Debug, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum DiscoverArgument {\n     Path(AbsPathBuf),\n     Buildfile(AbsPathBuf),\n}\n```\n\nThe JSON representation of `DiscoverArgument::Path` is:\n\n```json\n{\n        \"path\": \"src/main.rs\"\n}\n```\n\nSimilarly, the JSON representation of `DiscoverArgument::Buildfile` is:\n\n```json\n{\n        \"buildfile\": \"BUILD\"\n}\n```\n\n`DiscoverArgument::Path` is used to find and generate a `rust-project.json`,\nand therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to\nto update an existing workspace. As a reference for implementors,\nbuck2's `rust-project` will likely be useful:\nhttps://github.com/facebook/buck2/tree/main/integrations/rust-project.",
+                        "markdownDescription": "Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].\n\n[`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`.\n`progress_label` is used for the title in progress indicators, whereas `files_to_watch`\nis used to determine which build system-specific files should be watched in order to\nreload rust-analyzer.\n\nBelow is an example of a valid configuration:\n```json\n\"rust-analyzer.workspace.discoverConfig\": {\n        \"command\": [\n                \"rust-project\",\n                \"develop-json\"\n        ],\n        \"progressLabel\": \"rust-analyzer\",\n        \"filesToWatch\": [\n                \"BUCK\"\n        ]\n}\n```\n\n## On `DiscoverWorkspaceConfig::command`\n\n**Warning**: This format is provisional and subject to change.\n\n[`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to\n`DiscoverProjectData::Finished`:\n\n```norun\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(tag = \"kind\")]\n#[serde(rename_all = \"snake_case\")]\nenum DiscoverProjectData {\n        Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },\n        Error { error: String, source: Option<String> },\n        Progress { message: String },\n}\n```\n\nAs JSON, `DiscoverProjectData::Finished` is:\n\n```json\n{\n        // the internally-tagged representation of the enum.\n        \"kind\": \"finished\",\n        // the file used by a non-Cargo build system to define\n        // a package or target.\n        \"buildfile\": \"rust-analyzer/BUILD\",\n        // the contents of a rust-project.json, elided for brevity\n        \"project\": {\n                \"sysroot\": \"foo\",\n                \"crates\": []\n        }\n}\n```\n\nIt is encouraged, but not required, to use the other variants on `DiscoverProjectData`\nto provide a more polished end-user experience.\n\n`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, which will be\nsubstituted with the JSON-serialized form of the following enum:\n\n```norun\n#[derive(PartialEq, Clone, Debug, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum DiscoverArgument {\n     Path(AbsPathBuf),\n     Buildfile(AbsPathBuf),\n}\n```\n\nThe JSON representation of `DiscoverArgument::Path` is:\n\n```json\n{\n        \"path\": \"src/main.rs\"\n}\n```\n\nSimilarly, the JSON representation of `DiscoverArgument::Buildfile` is:\n\n```json\n{\n        \"buildfile\": \"BUILD\"\n}\n```\n\n`DiscoverArgument::Path` is used to find and generate a `rust-project.json`, and\ntherefore, a workspace, whereas `DiscoverArgument::buildfile` is used to to update an\nexisting workspace. As a reference for implementors, buck2's `rust-project` will likely\nbe useful: https://github.com/facebook/buck2/tree/main/integrations/rust-project.",
                         "default": null,
                         "anyOf": [
                             {
@@ -2912,7 +2999,7 @@
                 }
             },
             {
-                "title": "workspace",
+                "title": "Workspace",
                 "properties": {
                     "rust-analyzer.workspace.symbol.search.excludeImports": {
                         "markdownDescription": "Exclude all imports from workspace symbol search.\n\nIn addition to regular imports (which are always excluded),\nthis option removes public imports (better known as re-exports)\nand removes imports that rename the imported symbol.",
@@ -2922,7 +3009,7 @@
                 }
             },
             {
-                "title": "workspace",
+                "title": "Workspace",
                 "properties": {
                     "rust-analyzer.workspace.symbol.search.kind": {
                         "markdownDescription": "Workspace symbol search kind.",
@@ -2940,7 +3027,7 @@
                 }
             },
             {
-                "title": "workspace",
+                "title": "Workspace",
                 "properties": {
                     "rust-analyzer.workspace.symbol.search.limit": {
                         "markdownDescription": "Limits the number of items returned from a workspace symbol search (Defaults to 128).\nSome clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search.\nOther clients requires all results upfront and might require a higher limit.",
@@ -2951,7 +3038,7 @@
                 }
             },
             {
-                "title": "workspace",
+                "title": "Workspace",
                 "properties": {
                     "rust-analyzer.workspace.symbol.search.scope": {
                         "markdownDescription": "Workspace symbol search scope.",
diff --git a/src/tools/rust-analyzer/triagebot.toml b/src/tools/rust-analyzer/triagebot.toml
index 27fdb672455..c9862495bc0 100644
--- a/src/tools/rust-analyzer/triagebot.toml
+++ b/src/tools/rust-analyzer/triagebot.toml
@@ -28,6 +28,3 @@ labels = ["has-merge-commits", "S-waiting-on-author"]
 
 # Prevents mentions in commits to avoid users being spammed
 [no-mentions]
-
-# Automatically close and reopen PRs made by bots to run CI on them
-[bot-pull-requests]
diff --git a/src/tools/rust-analyzer/xtask/src/codegen.rs b/src/tools/rust-analyzer/xtask/src/codegen.rs
index 19ca62e8a32..bc7eb88f3a8 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen.rs
@@ -173,11 +173,11 @@ fn add_preamble(cg: CodegenType, mut text: String) -> String {
 #[allow(clippy::print_stderr)]
 fn ensure_file_contents(cg: CodegenType, file: &Path, contents: &str, check: bool) -> bool {
     let contents = normalize_newlines(contents);
-    if let Ok(old_contents) = fs::read_to_string(file) {
-        if normalize_newlines(&old_contents) == contents {
-            // File is already up to date.
-            return false;
-        }
+    if let Ok(old_contents) = fs::read_to_string(file)
+        && normalize_newlines(&old_contents) == contents
+    {
+        // File is already up to date.
+        return false;
     }
 
     let display_path = file.strip_prefix(project_root()).unwrap_or(file);
diff --git a/src/tools/rust-analyzer/xtask/src/publish/notes.rs b/src/tools/rust-analyzer/xtask/src/publish/notes.rs
index 93592d4986f..8d36fcb61b4 100644
--- a/src/tools/rust-analyzer/xtask/src/publish/notes.rs
+++ b/src/tools/rust-analyzer/xtask/src/publish/notes.rs
@@ -72,13 +72,13 @@ impl<'a, 'b, R: BufRead> Converter<'a, 'b, R> {
     }
 
     fn process_document_title(&mut self) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if let Some((level, title)) = get_title(&line) {
-                let title = process_inline_macros(title)?;
-                if level == 1 {
-                    self.write_title(level, &title);
-                    return Ok(());
-                }
+        if let Some(Ok(line)) = self.iter.next()
+            && let Some((level, title)) = get_title(&line)
+        {
+            let title = process_inline_macros(title)?;
+            if level == 1 {
+                self.write_title(level, &title);
+                return Ok(());
             }
         }
         bail!("document title not found")
@@ -141,39 +141,39 @@ impl<'a, 'b, R: BufRead> Converter<'a, 'b, R> {
     }
 
     fn process_source_code_block(&mut self, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if let Some(styles) = line.strip_prefix("[source").and_then(|s| s.strip_suffix(']')) {
-                let mut styles = styles.split(',');
-                if !styles.next().unwrap().is_empty() {
-                    bail!("not a source code block");
-                }
-                let language = styles.next();
-                return self.process_listing_block(language, level);
+        if let Some(Ok(line)) = self.iter.next()
+            && let Some(styles) = line.strip_prefix("[source").and_then(|s| s.strip_suffix(']'))
+        {
+            let mut styles = styles.split(',');
+            if !styles.next().unwrap().is_empty() {
+                bail!("not a source code block");
             }
+            let language = styles.next();
+            return self.process_listing_block(language, level);
         }
         bail!("not a source code block")
     }
 
     fn process_listing_block(&mut self, style: Option<&str>, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if line == LISTING_DELIMITER {
-                self.write_indent(level);
-                self.output.push_str("```");
-                if let Some(style) = style {
-                    self.output.push_str(style);
-                }
-                self.output.push('\n');
-                while let Some(line) = self.iter.next() {
-                    let line = line?;
-                    if line == LISTING_DELIMITER {
-                        self.write_line("```", level);
-                        return Ok(());
-                    } else {
-                        self.write_line(&line, level);
-                    }
+        if let Some(Ok(line)) = self.iter.next()
+            && line == LISTING_DELIMITER
+        {
+            self.write_indent(level);
+            self.output.push_str("```");
+            if let Some(style) = style {
+                self.output.push_str(style);
+            }
+            self.output.push('\n');
+            while let Some(line) = self.iter.next() {
+                let line = line?;
+                if line == LISTING_DELIMITER {
+                    self.write_line("```", level);
+                    return Ok(());
+                } else {
+                    self.write_line(&line, level);
                 }
-                bail!("listing block is not terminated")
             }
+            bail!("listing block is not terminated")
         }
         bail!("not a listing block")
     }
@@ -200,49 +200,48 @@ impl<'a, 'b, R: BufRead> Converter<'a, 'b, R> {
     }
 
     fn process_image_block(&mut self, caption: Option<&str>, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if let Some((url, attrs)) = parse_media_block(&line, IMAGE_BLOCK_PREFIX) {
-                let alt = if let Some(stripped) =
-                    attrs.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
-                {
+        if let Some(Ok(line)) = self.iter.next()
+            && let Some((url, attrs)) = parse_media_block(&line, IMAGE_BLOCK_PREFIX)
+        {
+            let alt =
+                if let Some(stripped) = attrs.strip_prefix('"').and_then(|s| s.strip_suffix('"')) {
                     stripped
                 } else {
                     attrs
                 };
-                if let Some(caption) = caption {
-                    self.write_caption_line(caption, level);
-                }
-                self.write_indent(level);
-                self.output.push_str("![");
-                self.output.push_str(alt);
-                self.output.push_str("](");
-                self.output.push_str(url);
-                self.output.push_str(")\n");
-                return Ok(());
+            if let Some(caption) = caption {
+                self.write_caption_line(caption, level);
             }
+            self.write_indent(level);
+            self.output.push_str("![");
+            self.output.push_str(alt);
+            self.output.push_str("](");
+            self.output.push_str(url);
+            self.output.push_str(")\n");
+            return Ok(());
         }
         bail!("not a image block")
     }
 
     fn process_video_block(&mut self, caption: Option<&str>, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if let Some((url, attrs)) = parse_media_block(&line, VIDEO_BLOCK_PREFIX) {
-                let html_attrs = match attrs {
-                    "options=loop" => "controls loop",
-                    r#"options="autoplay,loop""# => "autoplay controls loop",
-                    _ => bail!("unsupported video syntax"),
-                };
-                if let Some(caption) = caption {
-                    self.write_caption_line(caption, level);
-                }
-                self.write_indent(level);
-                self.output.push_str(r#"<video src=""#);
-                self.output.push_str(url);
-                self.output.push_str(r#"" "#);
-                self.output.push_str(html_attrs);
-                self.output.push_str(">Your browser does not support the video tag.</video>\n");
-                return Ok(());
+        if let Some(Ok(line)) = self.iter.next()
+            && let Some((url, attrs)) = parse_media_block(&line, VIDEO_BLOCK_PREFIX)
+        {
+            let html_attrs = match attrs {
+                "options=loop" => "controls loop",
+                r#"options="autoplay,loop""# => "autoplay controls loop",
+                _ => bail!("unsupported video syntax"),
+            };
+            if let Some(caption) = caption {
+                self.write_caption_line(caption, level);
             }
+            self.write_indent(level);
+            self.output.push_str(r#"<video src=""#);
+            self.output.push_str(url);
+            self.output.push_str(r#"" "#);
+            self.output.push_str(html_attrs);
+            self.output.push_str(">Your browser does not support the video tag.</video>\n");
+            return Ok(());
         }
         bail!("not a video block")
     }
@@ -371,12 +370,11 @@ fn strip_prefix_symbol(line: &str, symbol: char) -> Option<(usize, &str)> {
 }
 
 fn parse_media_block<'a>(line: &'a str, prefix: &str) -> Option<(&'a str, &'a str)> {
-    if let Some(line) = line.strip_prefix(prefix) {
-        if let Some((url, rest)) = line.split_once('[') {
-            if let Some(attrs) = rest.strip_suffix(']') {
-                return Some((url, attrs));
-            }
-        }
+    if let Some(line) = line.strip_prefix(prefix)
+        && let Some((url, rest)) = line.split_once('[')
+        && let Some(attrs) = rest.strip_suffix(']')
+    {
+        return Some((url, attrs));
     }
     None
 }
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index 5f30c75732c..d0eeab22062 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -156,9 +156,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
 
 [[package]]
 name = "cc"
-version = "1.2.30"
+version = "1.2.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
+checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2"
 dependencies = [
  "shlex",
 ]
@@ -185,9 +185,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.41"
+version = "4.5.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
+checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -195,9 +195,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.41"
+version = "4.5.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
+checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
 dependencies = [
  "anstream",
  "anstyle",
@@ -1343,9 +1343,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.16"
+version = "0.5.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792"
+checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
 dependencies = [
  "bitflags 2.9.1",
 ]
@@ -1459,9 +1459,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.141"
+version = "1.0.142"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
+checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
 dependencies = [
  "itoa",
  "memchr",
@@ -1969,7 +1969,7 @@ version = "0.60.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
 dependencies = [
- "windows-targets 0.53.2",
+ "windows-targets 0.53.3",
 ]
 
 [[package]]
@@ -1990,10 +1990,11 @@ dependencies = [
 
 [[package]]
 name = "windows-targets"
-version = "0.53.2"
+version = "0.53.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
+checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
 dependencies = [
+ "windows-link",
  "windows_aarch64_gnullvm 0.53.0",
  "windows_aarch64_msvc 0.53.0",
  "windows_i686_gnu 0.53.0",
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 4d195b3952e..5bf966b658c 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -7,47 +7,12 @@ use std::fs;
 use std::io::Write;
 use std::path::{Path, PathBuf};
 
-const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
-    "rs",     // test source files
-    "stderr", // expected stderr file, corresponds to a rs file
-    "svg",    // expected svg file, corresponds to a rs file, equivalent to stderr
-    "stdout", // expected stdout file, corresponds to a rs file
-    "fixed",  // expected source file after applying fixes
-    "md",     // test directory descriptions
-    "ftl",    // translation tests
-];
-
-const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
-    "tests/ui/asm/named-asm-labels.s", // loading an external asm file to test named labels lint
-    "tests/ui/codegen/mismatched-data-layout.json", // testing mismatched data layout w/ custom targets
-    "tests/ui/check-cfg/my-awesome-platform.json",  // testing custom targets with cfgs
-    "tests/ui/argfile/commandline-argfile-badutf8.args", // passing args via a file
-    "tests/ui/argfile/commandline-argfile.args",    // passing args via a file
-    "tests/ui/crate-loading/auxiliary/libfoo.rlib", // testing loading a manually created rlib
-    "tests/ui/include-macros/data.bin", // testing including data with the include macros
-    "tests/ui/include-macros/file.txt", // testing including data with the include macros
-    "tests/ui/macros/macro-expanded-include/file.txt", // testing including data with the include macros
-    "tests/ui/macros/not-utf8.bin", // testing including data with the include macros
-    "tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include
-    "tests/ui/proc-macro/auxiliary/included-file.txt", // more include
-    "tests/ui/unpretty/auxiliary/data.txt", // more include
-    "tests/ui/invalid/foo.natvis.xml", // sample debugger visualizer
-    "tests/ui/sanitizer/dataflow-abilist.txt", // dataflow sanitizer ABI list file
-    "tests/ui/shell-argfiles/shell-argfiles.args", // passing args via a file
-    "tests/ui/shell-argfiles/shell-argfiles-badquotes.args", // passing args via a file
-    "tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args", // passing args via a file
-    "tests/ui/shell-argfiles/shell-argfiles-via-argfile.args", // passing args via a file
-    "tests/ui/std/windows-bat-args1.bat", // tests escaping arguments through batch files
-    "tests/ui/std/windows-bat-args2.bat", // tests escaping arguments through batch files
-    "tests/ui/std/windows-bat-args3.bat", // tests escaping arguments through batch files
-];
-
-pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
-    let issues_txt_header = r#"============================================================
+const ISSUES_TXT_HEADER: &str = r#"============================================================
     ⚠️⚠️⚠️NOTHING SHOULD EVER BE ADDED TO THIS LIST⚠️⚠️⚠️
 ============================================================
 "#;
 
+pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
     let path = &root_path.join("tests");
 
     // the list of files in ui tests that are allowed to start with `issue-XXXX`
@@ -55,7 +20,7 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
     let mut prev_line = "";
     let mut is_sorted = true;
     let allowed_issue_names: BTreeSet<_> = include_str!("issues.txt")
-        .strip_prefix(issues_txt_header)
+        .strip_prefix(ISSUES_TXT_HEADER)
         .unwrap()
         .lines()
         .inspect(|&line| {
@@ -75,73 +40,9 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
         );
     }
 
-    let mut remaining_issue_names: BTreeSet<&str> = allowed_issue_names.clone();
-
-    let (ui, ui_fulldeps) = (path.join("ui"), path.join("ui-fulldeps"));
-    let paths = [ui.as_path(), ui_fulldeps.as_path()];
-    crate::walk::walk_no_read(&paths, |_, _| false, &mut |entry| {
-        let file_path = entry.path();
-        if let Some(ext) = file_path.extension().and_then(OsStr::to_str) {
-            // files that are neither an expected extension or an exception should not exist
-            // they're probably typos or not meant to exist
-            if !(EXPECTED_TEST_FILE_EXTENSIONS.contains(&ext)
-                || EXTENSION_EXCEPTION_PATHS.iter().any(|path| file_path.ends_with(path)))
-            {
-                tidy_error!(bad, "file {} has unexpected extension {}", file_path.display(), ext);
-            }
-
-            // NB: We do not use file_stem() as some file names have multiple `.`s and we
-            // must strip all of them.
-            let testname =
-                file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0;
-            if ext == "stderr" || ext == "stdout" || ext == "fixed" {
-                // Test output filenames have one of the formats:
-                // ```
-                // $testname.stderr
-                // $testname.$mode.stderr
-                // $testname.$revision.stderr
-                // $testname.$revision.$mode.stderr
-                // ```
-                //
-                // For now, just make sure that there is a corresponding
-                // `$testname.rs` file.
-
-                if !file_path.with_file_name(testname).with_extension("rs").exists()
-                    && !testname.contains("ignore-tidy")
-                {
-                    tidy_error!(bad, "Stray file with UI testing output: {:?}", file_path);
-                }
-
-                if let Ok(metadata) = fs::metadata(file_path)
-                    && metadata.len() == 0
-                {
-                    tidy_error!(bad, "Empty file with UI testing output: {:?}", file_path);
-                }
-            }
+    deny_new_top_level_ui_tests(bad, &path.join("ui"));
 
-            if ext == "rs"
-                && let Some(test_name) = static_regex!(r"^issues?[-_]?(\d{3,})").captures(testname)
-            {
-                // these paths are always relative to the passed `path` and always UTF8
-                let stripped_path = file_path
-                    .strip_prefix(path)
-                    .unwrap()
-                    .to_str()
-                    .unwrap()
-                    .replace(std::path::MAIN_SEPARATOR_STR, "/");
-
-                if !remaining_issue_names.remove(stripped_path.as_str())
-                    && !stripped_path.starts_with("ui/issues/")
-                {
-                    tidy_error!(
-                        bad,
-                        "file `tests/{stripped_path}` must begin with a descriptive name, consider `{{reason}}-issue-{issue_n}.rs`",
-                        issue_n = &test_name[1],
-                    );
-                }
-            }
-        }
-    });
+    let remaining_issue_names = recursively_check_ui_tests(bad, path, &allowed_issue_names);
 
     // if there are any file names remaining, they were moved on the fs.
     // our data must remain up to date, so it must be removed from issues.txt
@@ -152,7 +53,7 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
         // so we don't bork things on panic or a contributor using Ctrl+C
         let blessed_issues_path = tidy_src.join("issues_blessed.txt");
         let mut blessed_issues_txt = fs::File::create(&blessed_issues_path).unwrap();
-        blessed_issues_txt.write_all(issues_txt_header.as_bytes()).unwrap();
+        blessed_issues_txt.write_all(ISSUES_TXT_HEADER.as_bytes()).unwrap();
         // If we changed paths to use the OS separator, reassert Unix chauvinism for blessing.
         for filename in allowed_issue_names.difference(&remaining_issue_names) {
             writeln!(blessed_issues_txt, "{filename}").unwrap();
@@ -171,3 +72,170 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
         }
     }
 }
+
+fn deny_new_top_level_ui_tests(bad: &mut bool, tests_path: &Path) {
+    // See <https://github.com/rust-lang/compiler-team/issues/902> where we propose banning adding
+    // new ui tests *directly* under `tests/ui/`. For more context, see:
+    //
+    // - <https://github.com/rust-lang/rust/issues/73494>
+    // - <https://github.com/rust-lang/rust/issues/133895>
+
+    let top_level_ui_tests = walkdir::WalkDir::new(tests_path)
+        .min_depth(1)
+        .max_depth(1)
+        .follow_links(false)
+        .same_file_system(true)
+        .into_iter()
+        .flatten()
+        .filter(|e| {
+            let file_name = e.file_name();
+            file_name != ".gitattributes" && file_name != "README.md"
+        })
+        .filter(|e| !e.file_type().is_dir());
+    for entry in top_level_ui_tests {
+        tidy_error!(
+            bad,
+            "ui tests should be added under meaningful subdirectories: `{}`",
+            entry.path().display()
+        )
+    }
+}
+
+fn recursively_check_ui_tests<'issues>(
+    bad: &mut bool,
+    path: &Path,
+    allowed_issue_names: &'issues BTreeSet<&'issues str>,
+) -> BTreeSet<&'issues str> {
+    let mut remaining_issue_names: BTreeSet<&str> = allowed_issue_names.clone();
+
+    let (ui, ui_fulldeps) = (path.join("ui"), path.join("ui-fulldeps"));
+    let paths = [ui.as_path(), ui_fulldeps.as_path()];
+    crate::walk::walk_no_read(&paths, |_, _| false, &mut |entry| {
+        let file_path = entry.path();
+        if let Some(ext) = file_path.extension().and_then(OsStr::to_str) {
+            check_unexpected_extension(bad, file_path, ext);
+
+            // NB: We do not use file_stem() as some file names have multiple `.`s and we
+            // must strip all of them.
+            let testname =
+                file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0;
+            if ext == "stderr" || ext == "stdout" || ext == "fixed" {
+                check_stray_output_snapshot(bad, file_path, testname);
+                check_empty_output_snapshot(bad, file_path);
+            }
+
+            deny_new_nondescriptive_test_names(
+                bad,
+                path,
+                &mut remaining_issue_names,
+                file_path,
+                testname,
+                ext,
+            );
+        }
+    });
+    remaining_issue_names
+}
+
+fn check_unexpected_extension(bad: &mut bool, file_path: &Path, ext: &str) {
+    const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
+        "rs",     // test source files
+        "stderr", // expected stderr file, corresponds to a rs file
+        "svg",    // expected svg file, corresponds to a rs file, equivalent to stderr
+        "stdout", // expected stdout file, corresponds to a rs file
+        "fixed",  // expected source file after applying fixes
+        "md",     // test directory descriptions
+        "ftl",    // translation tests
+    ];
+
+    const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
+        "tests/ui/asm/named-asm-labels.s", // loading an external asm file to test named labels lint
+        "tests/ui/codegen/mismatched-data-layout.json", // testing mismatched data layout w/ custom targets
+        "tests/ui/check-cfg/my-awesome-platform.json",  // testing custom targets with cfgs
+        "tests/ui/argfile/commandline-argfile-badutf8.args", // passing args via a file
+        "tests/ui/argfile/commandline-argfile.args",    // passing args via a file
+        "tests/ui/crate-loading/auxiliary/libfoo.rlib", // testing loading a manually created rlib
+        "tests/ui/include-macros/data.bin", // testing including data with the include macros
+        "tests/ui/include-macros/file.txt", // testing including data with the include macros
+        "tests/ui/macros/macro-expanded-include/file.txt", // testing including data with the include macros
+        "tests/ui/macros/not-utf8.bin", // testing including data with the include macros
+        "tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include
+        "tests/ui/proc-macro/auxiliary/included-file.txt", // more include
+        "tests/ui/unpretty/auxiliary/data.txt", // more include
+        "tests/ui/invalid/foo.natvis.xml", // sample debugger visualizer
+        "tests/ui/sanitizer/dataflow-abilist.txt", // dataflow sanitizer ABI list file
+        "tests/ui/shell-argfiles/shell-argfiles.args", // passing args via a file
+        "tests/ui/shell-argfiles/shell-argfiles-badquotes.args", // passing args via a file
+        "tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args", // passing args via a file
+        "tests/ui/shell-argfiles/shell-argfiles-via-argfile.args", // passing args via a file
+        "tests/ui/std/windows-bat-args1.bat", // tests escaping arguments through batch files
+        "tests/ui/std/windows-bat-args2.bat", // tests escaping arguments through batch files
+        "tests/ui/std/windows-bat-args3.bat", // tests escaping arguments through batch files
+    ];
+
+    // files that are neither an expected extension or an exception should not exist
+    // they're probably typos or not meant to exist
+    if !(EXPECTED_TEST_FILE_EXTENSIONS.contains(&ext)
+        || EXTENSION_EXCEPTION_PATHS.iter().any(|path| file_path.ends_with(path)))
+    {
+        tidy_error!(bad, "file {} has unexpected extension {}", file_path.display(), ext);
+    }
+}
+
+fn check_stray_output_snapshot(bad: &mut bool, file_path: &Path, testname: &str) {
+    // Test output filenames have one of the formats:
+    // ```
+    // $testname.stderr
+    // $testname.$mode.stderr
+    // $testname.$revision.stderr
+    // $testname.$revision.$mode.stderr
+    // ```
+    //
+    // For now, just make sure that there is a corresponding
+    // `$testname.rs` file.
+
+    if !file_path.with_file_name(testname).with_extension("rs").exists()
+        && !testname.contains("ignore-tidy")
+    {
+        tidy_error!(bad, "Stray file with UI testing output: {:?}", file_path);
+    }
+}
+
+fn check_empty_output_snapshot(bad: &mut bool, file_path: &Path) {
+    if let Ok(metadata) = fs::metadata(file_path)
+        && metadata.len() == 0
+    {
+        tidy_error!(bad, "Empty file with UI testing output: {:?}", file_path);
+    }
+}
+
+fn deny_new_nondescriptive_test_names(
+    bad: &mut bool,
+    path: &Path,
+    remaining_issue_names: &mut BTreeSet<&str>,
+    file_path: &Path,
+    testname: &str,
+    ext: &str,
+) {
+    if ext == "rs"
+        && let Some(test_name) = static_regex!(r"^issues?[-_]?(\d{3,})").captures(testname)
+    {
+        // these paths are always relative to the passed `path` and always UTF8
+        let stripped_path = file_path
+            .strip_prefix(path)
+            .unwrap()
+            .to_str()
+            .unwrap()
+            .replace(std::path::MAIN_SEPARATOR_STR, "/");
+
+        if !remaining_issue_names.remove(stripped_path.as_str())
+            && !stripped_path.starts_with("ui/issues/")
+        {
+            tidy_error!(
+                bad,
+                "file `tests/{stripped_path}` must begin with a descriptive name, consider `{{reason}}-issue-{issue_n}.rs`",
+                issue_n = &test_name[1],
+            );
+        }
+    }
+}
diff --git a/src/version b/src/version
index 82e24bf241e..6979a6c0661 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.90.0
+1.91.0
diff --git a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs
index f5e2f18e68e..2892ff2882a 100644
--- a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs
+++ b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs
@@ -1,17 +1,24 @@
-// Test LVI load hardening on SGX enclave code
+// Test LVI load hardening on SGX enclave code, specifically that `ret` is rewritten.
 
+//@ add-core-stubs
 //@ assembly-output: emit-asm
-//@ compile-flags: --crate-type staticlib
-//@ only-x86_64-fortanix-unknown-sgx
+//@ compile-flags: --target x86_64-fortanix-unknown-sgx -Copt-level=0
+//@ needs-llvm-components: x86
+
+#![feature(no_core, lang_items, f16)]
+#![crate_type = "lib"]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
 
 #[no_mangle]
-pub extern "C" fn plus_one(r: &mut u64) {
-    *r = *r + 1;
+pub extern "C" fn dereference(a: &mut u64) -> u64 {
+    // CHECK-LABEL: dereference
+    // CHECK: lfence
+    // CHECK: mov
+    // CHECK: popq [[REGISTER:%[a-z]+]]
+    // CHECK-NEXT: lfence
+    // CHECK-NEXT: jmpq *[[REGISTER]]
+    *a
 }
-
-// CHECK: plus_one
-// CHECK: lfence
-// CHECK-NEXT: incq
-// CHECK: popq [[REGISTER:%[a-z]+]]
-// CHECK-NEXT: lfence
-// CHECK-NEXT: jmpq *[[REGISTER]]
diff --git a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs
index f16d68fa255..a0cedc3bc2d 100644
--- a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs
+++ b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs
@@ -1,12 +1,20 @@
 // Test LVI ret hardening on generic rust code
 
+//@ add-core-stubs
 //@ assembly-output: emit-asm
-//@ compile-flags: --crate-type staticlib
-//@ only-x86_64-fortanix-unknown-sgx
+//@ compile-flags: --target x86_64-fortanix-unknown-sgx
+//@ needs-llvm-components: x86
+
+#![feature(no_core, lang_items, f16)]
+#![crate_type = "lib"]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
 
 #[no_mangle]
 pub extern "C" fn myret() {}
-// CHECK: myret:
+// CHECK-LABEL: myret:
 // CHECK: popq [[REGISTER:%[a-z]+]]
 // CHECK-NEXT: lfence
 // CHECK-NEXT: jmpq *[[REGISTER]]
diff --git a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs
index a729df8e166..215fb4b804a 100644
--- a/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs
+++ b/tests/assembly-llvm/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs
@@ -1,13 +1,22 @@
 // Test LVI load hardening on SGX inline assembly code
 
+//@ add-core-stubs
 //@ assembly-output: emit-asm
-//@ compile-flags: --crate-type staticlib
-//@ only-x86_64-fortanix-unknown-sgx
+//@ compile-flags: --target x86_64-fortanix-unknown-sgx
+//@ needs-llvm-components: x86
 
-use std::arch::asm;
+#![feature(no_core, lang_items, f16)]
+#![crate_type = "lib"]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
 
 #[no_mangle]
 pub extern "C" fn get(ptr: *const u64) -> u64 {
+    // CHECK-LABEL: get
+    // CHECK: movq
+    // CHECK-NEXT: lfence
     let value: u64;
     unsafe {
         asm!("mov {}, [{}]",
@@ -17,18 +26,13 @@ pub extern "C" fn get(ptr: *const u64) -> u64 {
     value
 }
 
-// CHECK: get
-// CHECK: movq
-// CHECK-NEXT: lfence
-
 #[no_mangle]
 pub extern "C" fn myret() {
+    // CHECK-LABEL: myret
+    // CHECK: shlq $0, (%rsp)
+    // CHECK-NEXT: lfence
+    // CHECK-NEXT: retq
     unsafe {
         asm!("ret");
     }
 }
-
-// CHECK: myret
-// CHECK: shlq $0, (%rsp)
-// CHECK-NEXT: lfence
-// CHECK-NEXT: retq
diff --git a/tests/codegen-llvm/bounds-check-elision-slice-min.rs b/tests/codegen-llvm/bounds-check-elision-slice-min.rs
new file mode 100644
index 00000000000..e160e5da50f
--- /dev/null
+++ b/tests/codegen-llvm/bounds-check-elision-slice-min.rs
@@ -0,0 +1,19 @@
+//! Regression test for #<https://github.com/rust-lang/rust/issues/120433>:
+//! Multiple bounds checking elision failures
+//! (ensures bounds checks are properly elided,
+//! with no calls to panic_bounds_check in the LLVM IR).
+
+//@ compile-flags: -C opt-level=3
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @foo
+// CHECK-NOT: panic_bounds_check
+#[no_mangle]
+pub fn foo(buf: &[u8], alloced_size: usize) -> &[u8] {
+    if alloced_size.checked_add(1).map(|total| buf.len() < total).unwrap_or(true) {
+        return &[];
+    }
+    let size = buf[0];
+    &buf[1..1 + usize::min(alloced_size, usize::from(size))]
+}
diff --git a/tests/codegen-llvm/simd/extract-insert-dyn.rs b/tests/codegen-llvm/simd/extract-insert-dyn.rs
index 729f0145314..9c17b82e553 100644
--- a/tests/codegen-llvm/simd/extract-insert-dyn.rs
+++ b/tests/codegen-llvm/simd/extract-insert-dyn.rs
@@ -5,7 +5,8 @@
     repr_simd,
     arm_target_feature,
     mips_target_feature,
-    s390x_target_feature
+    s390x_target_feature,
+    riscv_target_feature
 )]
 #![no_std]
 #![crate_type = "lib"]
@@ -25,97 +26,105 @@ pub struct u32x16([u32; 16]);
 pub struct i8x16([i8; 16]);
 
 // CHECK-LABEL: dyn_simd_extract
-// CHECK: extractelement <16 x i8> %x, i32 %idx
+// CHECK: extractelement <16 x i8> %[[TEMP:.+]], i32 %idx
 #[no_mangle]
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 #[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+#[cfg_attr(target_arch = "riscv64", target_feature(enable = "v"))]
 unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 {
     simd_extract_dyn(x, idx)
 }
 
 // CHECK-LABEL: literal_dyn_simd_extract
-// CHECK: extractelement <16 x i8> %x, i32 7
+// CHECK: extractelement <16 x i8> %[[TEMP:.+]], i32 7
 #[no_mangle]
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 #[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+#[cfg_attr(target_arch = "riscv64", target_feature(enable = "v"))]
 unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 {
     simd_extract_dyn(x, 7)
 }
 
 // CHECK-LABEL: const_dyn_simd_extract
-// CHECK: extractelement <16 x i8> %x, i32 7
+// CHECK: extractelement <16 x i8> %[[TEMP:.+]], i32 7
 #[no_mangle]
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 #[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+#[cfg_attr(target_arch = "riscv64", target_feature(enable = "v"))]
 unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 {
     simd_extract_dyn(x, const { 3 + 4 })
 }
 
 // CHECK-LABEL: const_simd_extract
-// CHECK: extractelement <16 x i8> %x, i32 7
+// CHECK: extractelement <16 x i8> %[[TEMP:.+]], i32 7
 #[no_mangle]
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 #[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+#[cfg_attr(target_arch = "riscv64", target_feature(enable = "v"))]
 unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 {
     simd_extract(x, const { 3 + 4 })
 }
 
 // CHECK-LABEL: dyn_simd_insert
-// CHECK: insertelement <16 x i8> %x, i8 %e, i32 %idx
+// CHECK: insertelement <16 x i8> %[[TEMP:.+]], i8 %e, i32 %idx
 #[no_mangle]
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 #[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+#[cfg_attr(target_arch = "riscv64", target_feature(enable = "v"))]
 unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 {
     simd_insert_dyn(x, idx, e)
 }
 
 // CHECK-LABEL: literal_dyn_simd_insert
-// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
+// CHECK: insertelement <16 x i8> %[[TEMP:.+]], i8 %e, i32 7
 #[no_mangle]
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 #[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+#[cfg_attr(target_arch = "riscv64", target_feature(enable = "v"))]
 unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert_dyn(x, 7, e)
 }
 
 // CHECK-LABEL: const_dyn_simd_insert
-// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
+// CHECK: insertelement <16 x i8> %[[TEMP:.+]], i8 %e, i32 7
 #[no_mangle]
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 #[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+#[cfg_attr(target_arch = "riscv64", target_feature(enable = "v"))]
 unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert_dyn(x, const { 3 + 4 }, e)
 }
 
 // CHECK-LABEL: const_simd_insert
-// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
+// CHECK: insertelement <16 x i8> %[[TEMP:.+]], i8 %e, i32 7
 #[no_mangle]
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 #[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+#[cfg_attr(target_arch = "riscv64", target_feature(enable = "v"))]
 unsafe extern "C" fn const_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert(x, const { 3 + 4 }, e)
 }
diff --git a/tests/coverage/branch/no-mir-spans.cov-map b/tests/coverage/branch/no-mir-spans.cov-map
deleted file mode 100644
index 4f893cba1f8..00000000000
--- a/tests/coverage/branch/no-mir-spans.cov-map
+++ /dev/null
@@ -1,63 +0,0 @@
-Function name: no_mir_spans::while_cond
-Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 10, 20, 02, 01, 04, 0b, 00, 10]
-Number of files: 1
-- file 0 => $DIR/no-mir-spans.rs
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 16)
-- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 16)
-    true  = (c1 - c0)
-    false = c0
-Highest counter ID seen: c0
-
-Function name: no_mir_spans::while_cond_not
-Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 14, 20, 02, 01, 04, 0b, 00, 14]
-Number of files: 1
-- file 0 => $DIR/no-mir-spans.rs
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 25, 1) to (start + 0, 20)
-- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 20)
-    true  = (c1 - c0)
-    false = c0
-Highest counter ID seen: c0
-
-Function name: no_mir_spans::while_op_and
-Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19]
-Number of files: 1
-- file 0 => $DIR/no-mir-spans.rs
-Number of expressions: 4
-- expression 0 operands: lhs = Counter(2), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(2), rhs = Counter(0)
-- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 18)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16)
-    true  = c1
-    false = (c2 - c1)
-- Branch { true: Expression(1, Sub), false: Expression(2, Sub) } at (prev + 0, 20) to (start + 0, 25)
-    true  = (c2 - c0)
-    false = ((c0 + c1) - c2)
-Highest counter ID seen: c1
-
-Function name: no_mir_spans::while_op_or
-Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 11, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19]
-Number of files: 1
-- file 0 => $DIR/no-mir-spans.rs
-Number of expressions: 3
-- expression 0 operands: lhs = Counter(2), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(2), rhs = Expression(2, Add)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 45, 1) to (start + 0, 17)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16)
-    true  = c1
-    false = (c2 - c1)
-- Branch { true: Expression(1, Sub), false: Counter(0) } at (prev + 0, 20) to (start + 0, 25)
-    true  = (c2 - (c0 + c1))
-    false = c0
-Highest counter ID seen: c1
-
diff --git a/tests/coverage/branch/no-mir-spans.coverage b/tests/coverage/branch/no-mir-spans.coverage
deleted file mode 100644
index 2cae98ed3ff..00000000000
--- a/tests/coverage/branch/no-mir-spans.coverage
+++ /dev/null
@@ -1,77 +0,0 @@
-   LL|       |#![feature(coverage_attribute)]
-   LL|       |//@ edition: 2021
-   LL|       |//@ compile-flags: -Zcoverage-options=branch,no-mir-spans
-   LL|       |//@ llvm-cov-flags: --show-branches=count
-   LL|       |
-   LL|       |// Tests the behaviour of the `-Zcoverage-options=no-mir-spans` debugging flag.
-   LL|       |// The actual code below is just some non-trivial code copied from another test
-   LL|       |// (`while.rs`), and has no particular significance.
-   LL|       |
-   LL|       |macro_rules! no_merge {
-   LL|       |    () => {
-   LL|       |        for _ in 0..1 {}
-   LL|       |    };
-   LL|       |}
-   LL|       |
-   LL|      1|fn while_cond() {
-   LL|       |    no_merge!();
-   LL|       |
-   LL|       |    let mut a = 8;
-   LL|       |    while a > 0 {
-  ------------------
-  |  Branch (LL:11): [True: 8, False: 1]
-  ------------------
-   LL|       |        a -= 1;
-   LL|       |    }
-   LL|       |}
-   LL|       |
-   LL|      1|fn while_cond_not() {
-   LL|       |    no_merge!();
-   LL|       |
-   LL|       |    let mut a = 8;
-   LL|       |    while !(a == 0) {
-  ------------------
-  |  Branch (LL:11): [True: 8, False: 1]
-  ------------------
-   LL|       |        a -= 1;
-   LL|       |    }
-   LL|       |}
-   LL|       |
-   LL|      1|fn while_op_and() {
-   LL|       |    no_merge!();
-   LL|       |
-   LL|       |    let mut a = 8;
-   LL|       |    let mut b = 4;
-   LL|       |    while a > 0 && b > 0 {
-  ------------------
-  |  Branch (LL:11): [True: 5, False: 0]
-  |  Branch (LL:20): [True: 4, False: 1]
-  ------------------
-   LL|       |        a -= 1;
-   LL|       |        b -= 1;
-   LL|       |    }
-   LL|       |}
-   LL|       |
-   LL|      1|fn while_op_or() {
-   LL|       |    no_merge!();
-   LL|       |
-   LL|       |    let mut a = 4;
-   LL|       |    let mut b = 8;
-   LL|       |    while a > 0 || b > 0 {
-  ------------------
-  |  Branch (LL:11): [True: 4, False: 5]
-  |  Branch (LL:20): [True: 4, False: 1]
-  ------------------
-   LL|       |        a -= 1;
-   LL|       |        b -= 1;
-   LL|       |    }
-   LL|       |}
-   LL|       |
-   LL|       |#[coverage(off)]
-   LL|       |fn main() {
-   LL|       |    while_cond();
-   LL|       |    while_cond_not();
-   LL|       |    while_op_and();
-   LL|       |    while_op_or();
-   LL|       |}
-
diff --git a/tests/coverage/branch/no-mir-spans.rs b/tests/coverage/branch/no-mir-spans.rs
deleted file mode 100644
index acb268f2d45..00000000000
--- a/tests/coverage/branch/no-mir-spans.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-#![feature(coverage_attribute)]
-//@ edition: 2021
-//@ compile-flags: -Zcoverage-options=branch,no-mir-spans
-//@ llvm-cov-flags: --show-branches=count
-
-// Tests the behaviour of the `-Zcoverage-options=no-mir-spans` debugging flag.
-// The actual code below is just some non-trivial code copied from another test
-// (`while.rs`), and has no particular significance.
-
-macro_rules! no_merge {
-    () => {
-        for _ in 0..1 {}
-    };
-}
-
-fn while_cond() {
-    no_merge!();
-
-    let mut a = 8;
-    while a > 0 {
-        a -= 1;
-    }
-}
-
-fn while_cond_not() {
-    no_merge!();
-
-    let mut a = 8;
-    while !(a == 0) {
-        a -= 1;
-    }
-}
-
-fn while_op_and() {
-    no_merge!();
-
-    let mut a = 8;
-    let mut b = 4;
-    while a > 0 && b > 0 {
-        a -= 1;
-        b -= 1;
-    }
-}
-
-fn while_op_or() {
-    no_merge!();
-
-    let mut a = 4;
-    let mut b = 8;
-    while a > 0 || b > 0 {
-        a -= 1;
-        b -= 1;
-    }
-}
-
-#[coverage(off)]
-fn main() {
-    while_cond();
-    while_cond_not();
-    while_op_and();
-    while_op_or();
-}
diff --git a/tests/debuginfo/associated-types.rs b/tests/debuginfo/associated-types.rs
index b20bd520936..7c2a793c8cd 100644
--- a/tests/debuginfo/associated-types.rs
+++ b/tests/debuginfo/associated-types.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 // gdb-command:run
@@ -68,8 +69,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 trait TraitWithAssocType {
     type Type;
diff --git a/tests/debuginfo/auxiliary/cross_crate_spans.rs b/tests/debuginfo/auxiliary/cross_crate_spans.rs
index af853ee0b00..d0d32c2cbe3 100644
--- a/tests/debuginfo/auxiliary/cross_crate_spans.rs
+++ b/tests/debuginfo/auxiliary/cross_crate_spans.rs
@@ -1,8 +1,6 @@
 #![crate_type = "rlib"]
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 //@ no-prefer-dynamic
 //@ compile-flags:-g
diff --git a/tests/debuginfo/basic-stepping.rs b/tests/debuginfo/basic-stepping.rs
new file mode 100644
index 00000000000..6e1344d22a5
--- /dev/null
+++ b/tests/debuginfo/basic-stepping.rs
@@ -0,0 +1,47 @@
+//! Test that stepping through a simple program with a debugger one line at a
+//! time works intuitively, e.g. that `next` takes you to the next source line.
+//! Regression test for <https://github.com/rust-lang/rust/issues/33013>.
+
+//@ ignore-aarch64: Doesn't work yet.
+//@ compile-flags: -g
+
+// gdb-command: run
+// FIXME(#97083): Should we be able to break on initialization of zero-sized types?
+// FIXME(#97083): Right now the first breakable line is:
+// gdb-check:   let mut c = 27;
+// gdb-command: next
+// gdb-check:   let d = c = 99;
+// gdb-command: next
+// FIXME(#33013): gdb-check:   let e = "hi bob";
+// FIXME(#33013): gdb-command: next
+// FIXME(#33013): gdb-check:   let f = b"hi bob";
+// FIXME(#33013): gdb-command: next
+// FIXME(#33013): gdb-check:   let g = b'9';
+// FIXME(#33013): gdb-command: next
+// FIXME(#33013): gdb-check:   let h = ["whatever"; 8];
+// FIXME(#33013): gdb-command: next
+// gdb-check:   let i = [1,2,3,4];
+// gdb-command: next
+// gdb-check:   let j = (23, "hi");
+// gdb-command: next
+// gdb-check:   let k = 2..3;
+// gdb-command: next
+// gdb-check:   let l = &i[k];
+// gdb-command: next
+// gdb-check:   let m: *const() = &a;
+
+fn main () {
+    let a = (); // #break
+    let b : [i32; 0] = [];
+    let mut c = 27;
+    let d = c = 99;
+    let e = "hi bob";
+    let f = b"hi bob";
+    let g = b'9';
+    let h = ["whatever"; 8];
+    let i = [1,2,3,4];
+    let j = (23, "hi");
+    let k = 2..3;
+    let l = &i[k];
+    let m: *const() = &a;
+}
diff --git a/tests/debuginfo/basic-types-globals-metadata.rs b/tests/debuginfo/basic-types-globals-metadata.rs
index aec8ff183ad..fc8f6dc173f 100644
--- a/tests/debuginfo/basic-types-globals-metadata.rs
+++ b/tests/debuginfo/basic-types-globals-metadata.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // gdb-command:run
 // gdb-command:whatis basic_types_globals_metadata::B
@@ -35,8 +36,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(f16)]
 
 // N.B. These are `mut` only so they don't constant fold away.
diff --git a/tests/debuginfo/basic-types-globals.rs b/tests/debuginfo/basic-types-globals.rs
index 15a0deb64c1..9d28820ce68 100644
--- a/tests/debuginfo/basic-types-globals.rs
+++ b/tests/debuginfo/basic-types-globals.rs
@@ -1,6 +1,7 @@
 //@ revisions: lto no-lto
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 //@ [lto] compile-flags:-C lto
 //@ [lto] no-prefer-dynamic
@@ -39,8 +40,6 @@
 // gdb-command:continue
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(f16)]
 
 // N.B. These are `mut` only so they don't constant fold away.
diff --git a/tests/debuginfo/basic-types-metadata.rs b/tests/debuginfo/basic-types-metadata.rs
index 6b7cfbdebca..941db81a4de 100644
--- a/tests/debuginfo/basic-types-metadata.rs
+++ b/tests/debuginfo/basic-types-metadata.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // gdb-command:run
 // gdb-command:whatis unit
@@ -53,8 +54,6 @@
 // gdb-command:continue
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(f16)]
 
 fn main() {
diff --git a/tests/debuginfo/basic-types-mut-globals.rs b/tests/debuginfo/basic-types-mut-globals.rs
index f6a2399d230..e979d82b55c 100644
--- a/tests/debuginfo/basic-types-mut-globals.rs
+++ b/tests/debuginfo/basic-types-mut-globals.rs
@@ -5,6 +5,7 @@
 // its numerical value.
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // gdb-command:run
 
@@ -74,8 +75,6 @@
 // gdb-check:$30 = 9.25
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(f16)]
 
 static mut B: bool = false;
diff --git a/tests/debuginfo/basic-types.rs b/tests/debuginfo/basic-types.rs
index fea5262bc41..7862f45b3c4 100644
--- a/tests/debuginfo/basic-types.rs
+++ b/tests/debuginfo/basic-types.rs
@@ -5,6 +5,7 @@
 // its numerical value.
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -112,8 +113,6 @@
 // cdb-check:s                : [...] [Type: ref$<str$>]
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(f16)]
 
 fn main() {
diff --git a/tests/debuginfo/borrowed-basic.rs b/tests/debuginfo/borrowed-basic.rs
index 91de691e78e..334eae38318 100644
--- a/tests/debuginfo/borrowed-basic.rs
+++ b/tests/debuginfo/borrowed-basic.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -96,8 +97,6 @@
 // lldb-check:[...] 3.5
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(f16)]
 
 fn main() {
diff --git a/tests/debuginfo/borrowed-c-style-enum.rs b/tests/debuginfo/borrowed-c-style-enum.rs
index 6a91d4f9650..d382a389fe4 100644
--- a/tests/debuginfo/borrowed-c-style-enum.rs
+++ b/tests/debuginfo/borrowed-c-style-enum.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -28,8 +29,6 @@
 // lldb-check:[...] TheC
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 enum ABC { TheA, TheB, TheC }
 
diff --git a/tests/debuginfo/borrowed-enum.rs b/tests/debuginfo/borrowed-enum.rs
index c5a795fdede..517b439ff15 100644
--- a/tests/debuginfo/borrowed-enum.rs
+++ b/tests/debuginfo/borrowed-enum.rs
@@ -1,6 +1,7 @@
 //@ min-lldb-version: 1800
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -28,8 +29,6 @@
 // lldb-check:(borrowed_enum::Univariant) *univariant_ref = { value = { 0 = 4820353753753434 } }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
diff --git a/tests/debuginfo/borrowed-struct.rs b/tests/debuginfo/borrowed-struct.rs
index 245af35f505..5d64ba3cbef 100644
--- a/tests/debuginfo/borrowed-struct.rs
+++ b/tests/debuginfo/borrowed-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -52,8 +53,6 @@
 // lldb-check:[...] 26.5
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct SomeStruct {
     x: isize,
diff --git a/tests/debuginfo/borrowed-tuple.rs b/tests/debuginfo/borrowed-tuple.rs
index 9e4ceec033e..fd4e22feb06 100644
--- a/tests/debuginfo/borrowed-tuple.rs
+++ b/tests/debuginfo/borrowed-tuple.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -29,8 +30,6 @@
 
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let stack_val: (i16, f32) = (-14, -19f32);
diff --git a/tests/debuginfo/borrowed-unique-basic.rs b/tests/debuginfo/borrowed-unique-basic.rs
index 7a9b4d1df82..54d7f27bb0c 100644
--- a/tests/debuginfo/borrowed-unique-basic.rs
+++ b/tests/debuginfo/borrowed-unique-basic.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -100,8 +101,6 @@
 // lldb-check:[...] 3.5
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(f16)]
 
 fn main() {
diff --git a/tests/debuginfo/box.rs b/tests/debuginfo/box.rs
index d22566c0b17..d4612f98a5f 100644
--- a/tests/debuginfo/box.rs
+++ b/tests/debuginfo/box.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -19,8 +20,6 @@
 // lldb-check:[...] { 0 = 2 1 = 3.5 }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let a = Box::new(1);
diff --git a/tests/debuginfo/boxed-struct.rs b/tests/debuginfo/boxed-struct.rs
index 158609fb2ed..ca072693cdc 100644
--- a/tests/debuginfo/boxed-struct.rs
+++ b/tests/debuginfo/boxed-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -22,8 +23,6 @@
 // lldb-check:[...] { x = 77 y = 777 z = 7777 w = 77777 }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct StructWithSomePadding {
     x: i16,
diff --git a/tests/debuginfo/by-value-non-immediate-argument.rs b/tests/debuginfo/by-value-non-immediate-argument.rs
index deacea5f6cc..b5b0df73a68 100644
--- a/tests/debuginfo/by-value-non-immediate-argument.rs
+++ b/tests/debuginfo/by-value-non-immediate-argument.rs
@@ -1,6 +1,7 @@
 //@ min-lldb-version: 1800
 //@ min-gdb-version: 13.0
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 //@ ignore-windows-gnu: #128973
 //@ ignore-aarch64-unknown-linux-gnu (gdb tries to read from 0x0; FIXME: #128973)
 //@ ignore-powerpc64: #128973 on both -gnu and -musl
@@ -62,9 +63,6 @@
 // lldb-check:[...] Case1 { x: 0, y: 8970181431921507452 }
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Clone)]
 struct Struct {
     a: isize,
diff --git a/tests/debuginfo/by-value-self-argument-in-trait-impl.rs b/tests/debuginfo/by-value-self-argument-in-trait-impl.rs
index 6981fdfc9e1..a49a375569b 100644
--- a/tests/debuginfo/by-value-self-argument-in-trait-impl.rs
+++ b/tests/debuginfo/by-value-self-argument-in-trait-impl.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -33,9 +34,6 @@
 // lldb-check:[...] { 0 = 4444.5 1 = 5555 2 = 6666 3 = 7777.5 }
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 trait Trait {
     fn method(self) -> Self;
 }
diff --git a/tests/debuginfo/c-style-enum-in-composite.rs b/tests/debuginfo/c-style-enum-in-composite.rs
index 642879cf3b6..47b4b980f9c 100644
--- a/tests/debuginfo/c-style-enum-in-composite.rs
+++ b/tests/debuginfo/c-style-enum-in-composite.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -51,8 +52,6 @@
 // lldb-check:[...] { 0 = { a = OneHundred b = Vienna } 1 = 9 }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::AnEnum::{OneHundred, OneThousand, OneMillion};
 use self::AnotherEnum::{MountainView, Toronto, Vienna};
diff --git a/tests/debuginfo/c-style-enum.rs b/tests/debuginfo/c-style-enum.rs
index 08378f7af18..d5455be0cb5 100644
--- a/tests/debuginfo/c-style-enum.rs
+++ b/tests/debuginfo/c-style-enum.rs
@@ -1,6 +1,7 @@
 //@ ignore-aarch64
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -88,8 +89,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::AutoDiscriminant::{One, Two, Three};
 use self::ManualDiscriminant::{OneHundred, OneThousand, OneMillion};
diff --git a/tests/debuginfo/closure-in-generic-function.rs b/tests/debuginfo/closure-in-generic-function.rs
index 0c6a6fdfca1..0bb72209cc8 100644
--- a/tests/debuginfo/closure-in-generic-function.rs
+++ b/tests/debuginfo/closure-in-generic-function.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -33,9 +34,6 @@
 // lldb-check:[...] 110
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn some_generic_fun<T1, T2>(a: T1, b: T2) -> (T2, T1) {
 
     let closure = |x, y| {
diff --git a/tests/debuginfo/constant-debug-locs.rs b/tests/debuginfo/constant-debug-locs.rs
index 81115fc3c38..d13b8648b18 100644
--- a/tests/debuginfo/constant-debug-locs.rs
+++ b/tests/debuginfo/constant-debug-locs.rs
@@ -1,8 +1,7 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 #![allow(dead_code, unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // This test makes sure that the compiler doesn't crash when trying to assign
 // debug locations to const-expressions.
diff --git a/tests/debuginfo/constant-in-match-pattern.rs b/tests/debuginfo/constant-in-match-pattern.rs
index 952db216deb..922e0a5d8da 100644
--- a/tests/debuginfo/constant-in-match-pattern.rs
+++ b/tests/debuginfo/constant-in-match-pattern.rs
@@ -1,8 +1,7 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 #![allow(dead_code, unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // This test makes sure that the compiler doesn't crash when trying to assign
 // debug locations to 'constant' patterns in match expressions.
diff --git a/tests/debuginfo/coroutine-locals.rs b/tests/debuginfo/coroutine-locals.rs
index f3593adc945..c2b8aef8a67 100644
--- a/tests/debuginfo/coroutine-locals.rs
+++ b/tests/debuginfo/coroutine-locals.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -44,8 +45,7 @@
 // lldb-command:v c
 // lldb-check:(int) c = 6
 
-#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait, stmt_expr_attributes)]
-#![omit_gdb_pretty_printer_section]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
diff --git a/tests/debuginfo/coroutine-objects.rs b/tests/debuginfo/coroutine-objects.rs
index 242c76c2989..7ead154cbdb 100644
--- a/tests/debuginfo/coroutine-objects.rs
+++ b/tests/debuginfo/coroutine-objects.rs
@@ -5,6 +5,7 @@
 // ensure that LLDB won't crash at least (like #57822).
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -53,8 +54,7 @@
 // cdb-check: b                : Returned [Type: enum2$<coroutine_objects::main::coroutine_env$0>]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 6 [Type: int *]
 
-#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait, stmt_expr_attributes)]
-#![omit_gdb_pretty_printer_section]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
diff --git a/tests/debuginfo/cross-crate-spans.rs b/tests/debuginfo/cross-crate-spans.rs
index e337aaf5a6c..38176e46909 100644
--- a/tests/debuginfo/cross-crate-spans.rs
+++ b/tests/debuginfo/cross-crate-spans.rs
@@ -1,15 +1,13 @@
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 //@ aux-build:cross_crate_spans.rs
 extern crate cross_crate_spans;
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 
 // === GDB TESTS ===================================================================================
 
-// gdb-command:break cross_crate_spans.rs:14
+// gdb-command:break cross_crate_spans.rs:12
 // gdb-command:run
 
 // gdb-command:print result
@@ -32,7 +30,7 @@ extern crate cross_crate_spans;
 
 // === LLDB TESTS ==================================================================================
 
-// lldb-command:b cross_crate_spans.rs:14
+// lldb-command:b cross_crate_spans.rs:12
 // lldb-command:run
 
 // lldb-command:v result
diff --git a/tests/debuginfo/destructured-fn-argument.rs b/tests/debuginfo/destructured-fn-argument.rs
index 37a7bb2b778..fe8f91588e0 100644
--- a/tests/debuginfo/destructured-fn-argument.rs
+++ b/tests/debuginfo/destructured-fn-argument.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -299,8 +300,6 @@
 
 #![allow(unused_variables)]
 #![feature(box_patterns)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::Univariant::Unit;
 
diff --git a/tests/debuginfo/destructured-for-loop-variable.rs b/tests/debuginfo/destructured-for-loop-variable.rs
index cc16be1268a..01c524083da 100644
--- a/tests/debuginfo/destructured-for-loop-variable.rs
+++ b/tests/debuginfo/destructured-for-loop-variable.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -141,8 +142,6 @@
 
 #![allow(unused_variables)]
 #![feature(box_patterns)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     x: i16,
diff --git a/tests/debuginfo/destructured-local.rs b/tests/debuginfo/destructured-local.rs
index fad96ca7d4b..ff24c924aad 100644
--- a/tests/debuginfo/destructured-local.rs
+++ b/tests/debuginfo/destructured-local.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -232,8 +233,6 @@
 
 #![allow(unused_variables)]
 #![feature(box_patterns)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::Univariant::Unit;
 
diff --git a/tests/debuginfo/enum-thinlto.rs b/tests/debuginfo/enum-thinlto.rs
index af77145c312..6eb33b2ef46 100644
--- a/tests/debuginfo/enum-thinlto.rs
+++ b/tests/debuginfo/enum-thinlto.rs
@@ -1,5 +1,6 @@
 //@ min-lldb-version: 1800
 //@ compile-flags:-g -Z thinlto
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -16,8 +17,6 @@
 // lldb-check:(enum_thinlto::ABC) *abc = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
diff --git a/tests/debuginfo/evec-in-struct.rs b/tests/debuginfo/evec-in-struct.rs
index 303669cf06c..f08c436bbe3 100644
--- a/tests/debuginfo/evec-in-struct.rs
+++ b/tests/debuginfo/evec-in-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -38,8 +39,6 @@
 // lldb-check:[...] { x = { [0] = 22 [1] = 23 } y = { [0] = 24 [1] = 25 } }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct NoPadding1 {
     x: [u32; 3],
diff --git a/tests/debuginfo/extern-c-fn.rs b/tests/debuginfo/extern-c-fn.rs
index 4642073faab..7130658f2d8 100644
--- a/tests/debuginfo/extern-c-fn.rs
+++ b/tests/debuginfo/extern-c-fn.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 // gdb-command:run
@@ -32,9 +33,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 
 #[no_mangle]
 pub unsafe extern "C" fn fn_with_c_abi(s: *const u8, len: i32) -> i32 {
diff --git a/tests/debuginfo/function-arg-initialization.rs b/tests/debuginfo/function-arg-initialization.rs
index ae54d56623c..03fb1e2d062 100644
--- a/tests/debuginfo/function-arg-initialization.rs
+++ b/tests/debuginfo/function-arg-initialization.rs
@@ -8,6 +8,7 @@
 //@ min-lldb-version: 1800
 //@ compile-flags:-g -Zmir-enable-passes=-SingleUseConsts
 // SingleUseConsts shouldn't need to be disabled, see #128945
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -214,8 +215,6 @@
 
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 fn immediate_args(a: isize, b: bool, c: f64) {
     zzz(); // #break
diff --git a/tests/debuginfo/function-arguments.rs b/tests/debuginfo/function-arguments.rs
index 21c0c7d859c..64d026a705b 100644
--- a/tests/debuginfo/function-arguments.rs
+++ b/tests/debuginfo/function-arguments.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -32,10 +33,6 @@
 // lldb-check:[...] 3000
 // lldb-command:continue
 
-
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
 
     fun(111102, true);
diff --git a/tests/debuginfo/function-names.rs b/tests/debuginfo/function-names.rs
index c51884451e5..b5aec5c595e 100644
--- a/tests/debuginfo/function-names.rs
+++ b/tests/debuginfo/function-names.rs
@@ -2,6 +2,7 @@
 //@ min-gdb-version: 10.1
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -78,8 +79,6 @@
 // cdb-check:[...] a!function_names::const_generic_fn_bool<false> (void)
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(adt_const_params, coroutines, coroutine_trait, stmt_expr_attributes)]
 #![allow(incomplete_features)]
 
diff --git a/tests/debuginfo/function-prologue-stepping-regular.rs b/tests/debuginfo/function-prologue-stepping-regular.rs
index 07b9356fb50..f61128ca2df 100644
--- a/tests/debuginfo/function-prologue-stepping-regular.rs
+++ b/tests/debuginfo/function-prologue-stepping-regular.rs
@@ -4,6 +4,7 @@
 //@ min-lldb-version: 1800
 //@ ignore-gdb
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // lldb-command:breakpoint set --name immediate_args
 // lldb-command:breakpoint set --name non_immediate_args
@@ -116,8 +117,6 @@
 // lldb-command:continue
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 fn immediate_args(a: isize, b: bool, c: f64) {
     ()
diff --git a/tests/debuginfo/gdb-char.rs b/tests/debuginfo/gdb-char.rs
index 7d8608d4f51..d296e675fa3 100644
--- a/tests/debuginfo/gdb-char.rs
+++ b/tests/debuginfo/gdb-char.rs
@@ -3,6 +3,7 @@
 
 //@ min-gdb-version: 11.2
 //@ compile-flags: -g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -11,8 +12,6 @@
 // gdb-check:$1 = 97 'a'
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let ch: char = 'a';
diff --git a/tests/debuginfo/generic-enum-with-different-disr-sizes.rs b/tests/debuginfo/generic-enum-with-different-disr-sizes.rs
index e723543a37b..5c5f05d9c4b 100644
--- a/tests/debuginfo/generic-enum-with-different-disr-sizes.rs
+++ b/tests/debuginfo/generic-enum-with-different-disr-sizes.rs
@@ -1,6 +1,7 @@
 //@ ignore-lldb: FIXME(#27089)
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 // gdb-command:run
@@ -57,8 +58,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // This test case makes sure that we get correct type descriptions for the enum
 // discriminant of different instantiations of the same generic enum type where,
diff --git a/tests/debuginfo/generic-function.rs b/tests/debuginfo/generic-function.rs
index 4be8d5ad45a..ab3cb6953ac 100644
--- a/tests/debuginfo/generic-function.rs
+++ b/tests/debuginfo/generic-function.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -44,9 +45,6 @@
 // lldb-check:[...] { a = 6 b = 7.5 }
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Clone)]
 struct Struct {
     a: isize,
diff --git a/tests/debuginfo/generic-functions-nested.rs b/tests/debuginfo/generic-functions-nested.rs
index 7e0c20f8903..8ac2b8b9d7a 100644
--- a/tests/debuginfo/generic-functions-nested.rs
+++ b/tests/debuginfo/generic-functions-nested.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -57,10 +58,6 @@
 // lldb-check:[...] 2.5
 // lldb-command:continue
 
-
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn outer<TA: Clone>(a: TA) {
     inner(a.clone(), 1);
     inner(a.clone(), 2.5f64);
diff --git a/tests/debuginfo/generic-method-on-generic-struct.rs b/tests/debuginfo/generic-method-on-generic-struct.rs
index 9c587ca2839..36a94f2999d 100644
--- a/tests/debuginfo/generic-method-on-generic-struct.rs
+++ b/tests/debuginfo/generic-method-on-generic-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -99,9 +100,6 @@
 // lldb-check:[...] -10.5
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Copy, Clone)]
 struct Struct<T> {
     x: T
diff --git a/tests/debuginfo/generic-static-method-on-struct-and-enum.rs b/tests/debuginfo/generic-static-method-on-struct-and-enum.rs
index 79fe2144cf4..09b515d69e4 100644
--- a/tests/debuginfo/generic-static-method-on-struct-and-enum.rs
+++ b/tests/debuginfo/generic-static-method-on-struct-and-enum.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // gdb-command:run
 
@@ -19,9 +20,6 @@
 // gdb-command:continue
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 struct Struct {
     x: isize
 }
diff --git a/tests/debuginfo/generic-struct-style-enum.rs b/tests/debuginfo/generic-struct-style-enum.rs
index a5529ab8027..4f580f8c515 100644
--- a/tests/debuginfo/generic-struct-style-enum.rs
+++ b/tests/debuginfo/generic-struct-style-enum.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // gdb-command:set print union on
 // gdb-command:run
@@ -16,9 +17,6 @@
 // gdb-check:$4 = generic_struct_style_enum::Univariant<i32>::TheOnlyCase{a: -1}
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 use self::Regular::{Case1, Case2, Case3};
 use self::Univariant::TheOnlyCase;
 
diff --git a/tests/debuginfo/generic-struct.rs b/tests/debuginfo/generic-struct.rs
index f26d823d4f2..0196ca43544 100644
--- a/tests/debuginfo/generic-struct.rs
+++ b/tests/debuginfo/generic-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -49,9 +50,6 @@
 // cdb-check:[...]value            [Type: generic_struct::AGenericStruct<i32,f64>]
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 struct AGenericStruct<TKey, TValue> {
     key: TKey,
     value: TValue
diff --git a/tests/debuginfo/generic-tuple-style-enum.rs b/tests/debuginfo/generic-tuple-style-enum.rs
index 4a5996645cb..719b5c6161f 100644
--- a/tests/debuginfo/generic-tuple-style-enum.rs
+++ b/tests/debuginfo/generic-tuple-style-enum.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -30,8 +31,6 @@
 
 // lldb-command:v univariant
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::Regular::{Case1, Case2, Case3};
 use self::Univariant::TheOnlyCase;
diff --git a/tests/debuginfo/include_string.rs b/tests/debuginfo/include_string.rs
index 704b85e1ac2..4ec23b68262 100644
--- a/tests/debuginfo/include_string.rs
+++ b/tests/debuginfo/include_string.rs
@@ -2,6 +2,7 @@
 // ^ test temporarily disabled as it fails under gdb 15
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 // gdb-command:run
 // gdb-command:print string1.length
 // gdb-check:$1 = 48
@@ -26,8 +27,6 @@
 // lldb-command:continue
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // This test case makes sure that debug info does not ICE when include_str is
 // used multiple times (see issue #11322).
diff --git a/tests/debuginfo/issue-12886.rs b/tests/debuginfo/issue-12886.rs
index 48250e88537..5574294cd57 100644
--- a/tests/debuginfo/issue-12886.rs
+++ b/tests/debuginfo/issue-12886.rs
@@ -2,14 +2,13 @@
 //@ ignore-aarch64
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // gdb-command:run
 // gdb-command:next
-// gdb-check:[...]23[...]let s = Some(5).unwrap(); // #break
+// gdb-check:[...]22[...]let s = Some(5).unwrap(); // #break
 // gdb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // IF YOU MODIFY THIS FILE, BE CAREFUL TO ADAPT THE LINE NUMBERS IN THE DEBUGGER COMMANDS
 
diff --git a/tests/debuginfo/issue-22656.rs b/tests/debuginfo/issue-22656.rs
index eb0b38cfa4d..3407c0524eb 100644
--- a/tests/debuginfo/issue-22656.rs
+++ b/tests/debuginfo/issue-22656.rs
@@ -5,6 +5,7 @@
 //@ ignore-gdb
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === LLDB TESTS ==================================================================================
 // lldb-command:run
@@ -16,8 +17,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct ZeroSizedStruct;
 
diff --git a/tests/debuginfo/issue-57822.rs b/tests/debuginfo/issue-57822.rs
index 7abac1c14d3..ba4e01196a4 100644
--- a/tests/debuginfo/issue-57822.rs
+++ b/tests/debuginfo/issue-57822.rs
@@ -3,6 +3,7 @@
 
 //@ min-lldb-version: 1800
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -24,8 +25,7 @@
 // lldb-command:v b
 // lldb-check:(issue_57822::main::{coroutine_env#3}) b = { value = { a = { value = { y = 2 } $discr$ = '\x02' } } $discr$ = '\x02' }
 
-#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait, stmt_expr_attributes)]
-#![omit_gdb_pretty_printer_section]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
diff --git a/tests/debuginfo/lexical-scope-in-for-loop.rs b/tests/debuginfo/lexical-scope-in-for-loop.rs
index 08f244f89a0..f591f48ad59 100644
--- a/tests/debuginfo/lexical-scope-in-for-loop.rs
+++ b/tests/debuginfo/lexical-scope-in-for-loop.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -73,9 +74,6 @@
 // lldb-check:[...] 1000000
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
 
     let range = [1, 2, 3];
diff --git a/tests/debuginfo/lexical-scope-in-if.rs b/tests/debuginfo/lexical-scope-in-if.rs
index c0e1f2f3e05..2b3a4ee5fc4 100644
--- a/tests/debuginfo/lexical-scope-in-if.rs
+++ b/tests/debuginfo/lexical-scope-in-if.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -121,9 +122,6 @@
 // lldb-check:[...] -1
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
 
     let x = 999;
diff --git a/tests/debuginfo/lexical-scope-in-match.rs b/tests/debuginfo/lexical-scope-in-match.rs
index 9169c19c6a3..0e369c6ca16 100644
--- a/tests/debuginfo/lexical-scope-in-match.rs
+++ b/tests/debuginfo/lexical-scope-in-match.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -113,9 +114,6 @@
 // lldb-check:[...] 232
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 struct Struct {
     x: isize,
     y: isize
diff --git a/tests/debuginfo/lexical-scope-in-stack-closure.rs b/tests/debuginfo/lexical-scope-in-stack-closure.rs
index d01162c39d6..483d5dda86c 100644
--- a/tests/debuginfo/lexical-scope-in-stack-closure.rs
+++ b/tests/debuginfo/lexical-scope-in-stack-closure.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -57,9 +58,6 @@
 // lldb-check:[...] false
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
 
     let x = false;
diff --git a/tests/debuginfo/lexical-scope-in-unconditional-loop.rs b/tests/debuginfo/lexical-scope-in-unconditional-loop.rs
index dfec570218f..129d0b8c83d 100644
--- a/tests/debuginfo/lexical-scope-in-unconditional-loop.rs
+++ b/tests/debuginfo/lexical-scope-in-unconditional-loop.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -119,9 +120,6 @@
 // lldb-check:[...] 2
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
 
     let mut x = 0;
diff --git a/tests/debuginfo/lexical-scope-in-unique-closure.rs b/tests/debuginfo/lexical-scope-in-unique-closure.rs
index db84005121a..93bea18d7cd 100644
--- a/tests/debuginfo/lexical-scope-in-unique-closure.rs
+++ b/tests/debuginfo/lexical-scope-in-unique-closure.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -58,9 +59,6 @@
 // lldb-command:continue
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
 
     let x = false;
diff --git a/tests/debuginfo/lexical-scope-in-while.rs b/tests/debuginfo/lexical-scope-in-while.rs
index d6536d77545..5fe76851bd7 100644
--- a/tests/debuginfo/lexical-scope-in-while.rs
+++ b/tests/debuginfo/lexical-scope-in-while.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -119,9 +120,6 @@
 // lldb-check:[...] 2
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
 
     let mut x = 0;
diff --git a/tests/debuginfo/lexical-scope-with-macro.rs b/tests/debuginfo/lexical-scope-with-macro.rs
index 6e8fef201ea..efec9a3b1ce 100644
--- a/tests/debuginfo/lexical-scope-with-macro.rs
+++ b/tests/debuginfo/lexical-scope-with-macro.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -97,9 +98,6 @@
 // lldb-check:[...] 400
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 macro_rules! trivial {
     ($e1:expr) => ($e1)
 }
diff --git a/tests/debuginfo/lexical-scopes-in-block-expression.rs b/tests/debuginfo/lexical-scopes-in-block-expression.rs
index cd27c88db58..bec69ec87e8 100644
--- a/tests/debuginfo/lexical-scopes-in-block-expression.rs
+++ b/tests/debuginfo/lexical-scopes-in-block-expression.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -336,8 +337,6 @@
 
 #![allow(unused_variables)]
 #![allow(unused_assignments)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 static mut MUT_INT: isize = 0;
 
diff --git a/tests/debuginfo/limited-debuginfo.rs b/tests/debuginfo/limited-debuginfo.rs
index fb453d8078c..c3b516460aa 100644
--- a/tests/debuginfo/limited-debuginfo.rs
+++ b/tests/debuginfo/limited-debuginfo.rs
@@ -1,6 +1,7 @@
 //@ ignore-lldb
 
 //@ compile-flags:-C debuginfo=1
+//@ disable-gdb-pretty-printers
 
 // Make sure functions have proper names
 // gdb-command:info functions
@@ -18,8 +19,6 @@
 
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     a: i64,
diff --git a/tests/debuginfo/method-on-enum.rs b/tests/debuginfo/method-on-enum.rs
index 754b4a2dc26..f86cf8ccfdf 100644
--- a/tests/debuginfo/method-on-enum.rs
+++ b/tests/debuginfo/method-on-enum.rs
@@ -2,6 +2,7 @@
 //@ min-gdb-version: 13.0
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 //@ ignore-windows-gnu: #128973
 
@@ -104,9 +105,6 @@
 // lldb-check:[...] -10
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Copy, Clone)]
 enum Enum {
     Variant1 { x: u16, y: u16 },
diff --git a/tests/debuginfo/method-on-generic-struct.rs b/tests/debuginfo/method-on-generic-struct.rs
index 1e6c9d66178..5da952fa4e1 100644
--- a/tests/debuginfo/method-on-generic-struct.rs
+++ b/tests/debuginfo/method-on-generic-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -99,9 +100,6 @@
 // lldb-check:[...] -10
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Copy, Clone)]
 struct Struct<T> {
     x: T
diff --git a/tests/debuginfo/method-on-struct.rs b/tests/debuginfo/method-on-struct.rs
index 91f609365e9..83badd8dbf0 100644
--- a/tests/debuginfo/method-on-struct.rs
+++ b/tests/debuginfo/method-on-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -99,9 +100,6 @@
 // lldb-check:[...] -10
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Copy, Clone)]
 struct Struct {
     x: isize
diff --git a/tests/debuginfo/method-on-trait.rs b/tests/debuginfo/method-on-trait.rs
index 7b95e1f81c7..c91b255bd6a 100644
--- a/tests/debuginfo/method-on-trait.rs
+++ b/tests/debuginfo/method-on-trait.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -99,9 +100,6 @@
 // lldb-check:[...] -10
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Copy, Clone)]
 struct Struct {
     x: isize
diff --git a/tests/debuginfo/method-on-tuple-struct.rs b/tests/debuginfo/method-on-tuple-struct.rs
index 04c00d88302..7e6e724d42e 100644
--- a/tests/debuginfo/method-on-tuple-struct.rs
+++ b/tests/debuginfo/method-on-tuple-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -99,9 +100,6 @@
 // lldb-check:[...] -10
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Copy, Clone)]
 struct TupleStruct(isize, f64);
 
diff --git a/tests/debuginfo/multi-cgu.rs b/tests/debuginfo/multi-cgu.rs
index 3bb5269adea..ca4146da405 100644
--- a/tests/debuginfo/multi-cgu.rs
+++ b/tests/debuginfo/multi-cgu.rs
@@ -2,6 +2,7 @@
 // compiled with multiple codegen units. (see #39160)
 
 //@ compile-flags:-g -Ccodegen-units=2
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===============================================================
 
@@ -29,9 +30,6 @@
 // lldb-command:continue
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 mod a {
     pub fn foo(xxx: u32) {
         super::_zzz(); // #break
diff --git a/tests/debuginfo/multiple-functions-equal-var-names.rs b/tests/debuginfo/multiple-functions-equal-var-names.rs
index 6ae9225d55c..2bc40b87e6f 100644
--- a/tests/debuginfo/multiple-functions-equal-var-names.rs
+++ b/tests/debuginfo/multiple-functions-equal-var-names.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -32,8 +33,6 @@
 // lldb-check:[...] 30303
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 fn function_one() {
     let abc = 10101;
diff --git a/tests/debuginfo/multiple-functions.rs b/tests/debuginfo/multiple-functions.rs
index 3f7a0ded91b..5469408c78f 100644
--- a/tests/debuginfo/multiple-functions.rs
+++ b/tests/debuginfo/multiple-functions.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -32,8 +33,6 @@
 // lldb-check:[...] 30303
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 fn function_one() {
     let a = 10101;
diff --git a/tests/debuginfo/name-shadowing-and-scope-nesting.rs b/tests/debuginfo/name-shadowing-and-scope-nesting.rs
index d3829b60713..e8d85473d86 100644
--- a/tests/debuginfo/name-shadowing-and-scope-nesting.rs
+++ b/tests/debuginfo/name-shadowing-and-scope-nesting.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -81,9 +82,6 @@
 // lldb-check:[...] 20
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
     let x = false;
     let y = true;
diff --git a/tests/debuginfo/option-like-enum.rs b/tests/debuginfo/option-like-enum.rs
index 72a41986dce..5a55b143fbb 100644
--- a/tests/debuginfo/option-like-enum.rs
+++ b/tests/debuginfo/option-like-enum.rs
@@ -2,6 +2,7 @@
 //@ min-gdb-version: 13.0
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -69,9 +70,6 @@
 // lldb-check:[...] Nope
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 // If a struct has exactly two variants, one of them is empty, and the other one
 // contains a non-nullable pointer, then this value is used as the discriminator.
 // The test cases in this file make sure that something readable is generated for
diff --git a/tests/debuginfo/packed-struct-with-destructor.rs b/tests/debuginfo/packed-struct-with-destructor.rs
index f923d36953c..0c5725ca25c 100644
--- a/tests/debuginfo/packed-struct-with-destructor.rs
+++ b/tests/debuginfo/packed-struct-with-destructor.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -60,8 +61,6 @@
 
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 #[repr(packed)]
 struct Packed {
diff --git a/tests/debuginfo/packed-struct.rs b/tests/debuginfo/packed-struct.rs
index 2b3652fe861..3bc39adee83 100644
--- a/tests/debuginfo/packed-struct.rs
+++ b/tests/debuginfo/packed-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -46,8 +47,6 @@
 // lldb-check:[...] 40
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 #[repr(packed)]
 struct Packed {
diff --git a/tests/debuginfo/recursive-enum.rs b/tests/debuginfo/recursive-enum.rs
index b861e6d617c..5fb339f54f3 100644
--- a/tests/debuginfo/recursive-enum.rs
+++ b/tests/debuginfo/recursive-enum.rs
@@ -1,14 +1,13 @@
 //@ ignore-lldb
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 // gdb-command:run
 
 // Test whether compiling a recursive enum definition crashes debug info generation. The test case
 // is taken from issue #11083 and #135093.
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 pub struct Window<'a> {
     callbacks: WindowCallbacks<'a>
diff --git a/tests/debuginfo/recursive-struct.rs b/tests/debuginfo/recursive-struct.rs
index a97eb295eb4..5be90992848 100644
--- a/tests/debuginfo/recursive-struct.rs
+++ b/tests/debuginfo/recursive-struct.rs
@@ -1,6 +1,7 @@
 //@ ignore-lldb
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // gdb-command:run
 
@@ -58,8 +59,6 @@
 // gdb-command:continue
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::Opt::{Empty, Val};
 use std::boxed::Box as B;
diff --git a/tests/debuginfo/reference-debuginfo.rs b/tests/debuginfo/reference-debuginfo.rs
index 773c3ae4bc3..242da1dd654 100644
--- a/tests/debuginfo/reference-debuginfo.rs
+++ b/tests/debuginfo/reference-debuginfo.rs
@@ -3,6 +3,7 @@
 // and leaves codegen to create a ladder of allocations so as `*a == b`.
 //
 //@ compile-flags:-g -Zmir-enable-passes=+ReferencePropagation,-ConstDebugInfo
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -106,8 +107,6 @@
 // lldb-check:[...] 3.5
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(f16)]
 
 fn main() {
diff --git a/tests/debuginfo/self-in-default-method.rs b/tests/debuginfo/self-in-default-method.rs
index 02fc01d96eb..4297129e0cf 100644
--- a/tests/debuginfo/self-in-default-method.rs
+++ b/tests/debuginfo/self-in-default-method.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -99,9 +100,6 @@
 // lldb-check:[...] -10
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Copy, Clone)]
 struct Struct {
     x: isize
diff --git a/tests/debuginfo/self-in-generic-default-method.rs b/tests/debuginfo/self-in-generic-default-method.rs
index 65018e549ee..e7ffa05f418 100644
--- a/tests/debuginfo/self-in-generic-default-method.rs
+++ b/tests/debuginfo/self-in-generic-default-method.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -99,9 +100,6 @@
 // lldb-check:[...] -10.5
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 #[derive(Copy, Clone)]
 struct Struct {
     x: isize
diff --git a/tests/debuginfo/shadowed-argument.rs b/tests/debuginfo/shadowed-argument.rs
index 3a575b4addf..3a0f0ad17a8 100644
--- a/tests/debuginfo/shadowed-argument.rs
+++ b/tests/debuginfo/shadowed-argument.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -46,9 +47,6 @@
 // lldb-command:continue
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn a_function(x: bool, y: bool) {
     zzz(); // #break
     sentinel();
diff --git a/tests/debuginfo/shadowed-variable.rs b/tests/debuginfo/shadowed-variable.rs
index 752e4c233f1..6a658a7c494 100644
--- a/tests/debuginfo/shadowed-variable.rs
+++ b/tests/debuginfo/shadowed-variable.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -68,9 +69,6 @@
 // lldb-check:[...] 20
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
     let x = false;
     let y = true;
diff --git a/tests/debuginfo/simd.rs b/tests/debuginfo/simd.rs
index 12675a71a57..43cd7130b25 100644
--- a/tests/debuginfo/simd.rs
+++ b/tests/debuginfo/simd.rs
@@ -7,6 +7,7 @@
 //@ ignore-s390x
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 // gdb-command:run
 
 // gdb-command:print vi8x16
@@ -35,8 +36,6 @@
 // gdb-command:continue
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(repr_simd)]
 
 #[repr(simd)]
diff --git a/tests/debuginfo/simple-lexical-scope.rs b/tests/debuginfo/simple-lexical-scope.rs
index 6008489bd65..64afcf8d61d 100644
--- a/tests/debuginfo/simple-lexical-scope.rs
+++ b/tests/debuginfo/simple-lexical-scope.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -66,9 +67,6 @@
 // lldb-command:continue
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 fn main() {
     let x = false;
 
diff --git a/tests/debuginfo/simple-struct.rs b/tests/debuginfo/simple-struct.rs
index bb6b2b79810..da09a8a3ce0 100644
--- a/tests/debuginfo/simple-struct.rs
+++ b/tests/debuginfo/simple-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: -g -Zmir-enable-passes=-CheckAlignment
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -84,8 +85,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct NoPadding16 {
     x: u16,
diff --git a/tests/debuginfo/simple-tuple.rs b/tests/debuginfo/simple-tuple.rs
index 82467ef3bcf..f086472d725 100644
--- a/tests/debuginfo/simple-tuple.rs
+++ b/tests/debuginfo/simple-tuple.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -121,8 +122,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 static mut NO_PADDING_8: (i8, u8) = (-50, 50);
 static mut NO_PADDING_16: (i16, i16, u16) = (-1, 2, 3);
diff --git a/tests/debuginfo/static-method-on-struct-and-enum.rs b/tests/debuginfo/static-method-on-struct-and-enum.rs
index b487512a52f..2a3502712de 100644
--- a/tests/debuginfo/static-method-on-struct-and-enum.rs
+++ b/tests/debuginfo/static-method-on-struct-and-enum.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -41,9 +42,6 @@
 // lldb-check:[...] 5
 // lldb-command:continue
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 struct Struct {
     x: isize
 }
diff --git a/tests/debuginfo/strings-and-strs.rs b/tests/debuginfo/strings-and-strs.rs
index 7d550408bec..392cf697e11 100644
--- a/tests/debuginfo/strings-and-strs.rs
+++ b/tests/debuginfo/strings-and-strs.rs
@@ -2,6 +2,7 @@
 //@ min-lldb-version: 1800
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 // gdb-command:run
@@ -40,8 +41,6 @@
 
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 pub struct Foo<'a> {
     inner: &'a str,
diff --git a/tests/debuginfo/struct-in-enum.rs b/tests/debuginfo/struct-in-enum.rs
index bc2c59fe4aa..c5a7fb95e1e 100644
--- a/tests/debuginfo/struct-in-enum.rs
+++ b/tests/debuginfo/struct-in-enum.rs
@@ -1,6 +1,7 @@
 //@ min-lldb-version: 1800
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -30,8 +31,6 @@
 // lldb-check:[...] TheOnlyCase(Struct { x: 123, y: 456, z: 789 })
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::Regular::{Case1, Case2};
 use self::Univariant::TheOnlyCase;
diff --git a/tests/debuginfo/struct-in-struct.rs b/tests/debuginfo/struct-in-struct.rs
index 3cf48470391..c818df31b4b 100644
--- a/tests/debuginfo/struct-in-struct.rs
+++ b/tests/debuginfo/struct-in-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -43,8 +44,6 @@
 // lldb-check:[...] { x = { x = 25 } y = { x = { x = 26 y = 27 } y = { x = 28 y = 29 } z = { x = 30 y = 31 } } z = { x = { x = { x = 32 } } } }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct Simple {
     x: i32
diff --git a/tests/debuginfo/struct-namespace.rs b/tests/debuginfo/struct-namespace.rs
index 95788419100..d56c84c4f13 100644
--- a/tests/debuginfo/struct-namespace.rs
+++ b/tests/debuginfo/struct-namespace.rs
@@ -1,5 +1,6 @@
 //@ ignore-gdb
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // Check that structs get placed in the correct namespace
 
@@ -16,8 +17,6 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct Struct1 {
     a: u32,
diff --git a/tests/debuginfo/struct-style-enum.rs b/tests/debuginfo/struct-style-enum.rs
index cea9f3def8b..1f28fe4fea1 100644
--- a/tests/debuginfo/struct-style-enum.rs
+++ b/tests/debuginfo/struct-style-enum.rs
@@ -1,5 +1,6 @@
 //@ min-lldb-version: 1800
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -36,8 +37,6 @@
 // lldb-check:(struct_style_enum::Univariant) univariant = { value = { a = -1 } }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::Regular::{Case1, Case2, Case3};
 use self::Univariant::TheOnlyCase;
diff --git a/tests/debuginfo/struct-with-destructor.rs b/tests/debuginfo/struct-with-destructor.rs
index c159824980a..4d2ce8ff79d 100644
--- a/tests/debuginfo/struct-with-destructor.rs
+++ b/tests/debuginfo/struct-with-destructor.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -32,8 +33,6 @@
 // lldb-check:[...] { a = { a = { x = 7890 y = 9870 } } }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct NoDestructor {
     x: i32,
diff --git a/tests/debuginfo/trait-pointers.rs b/tests/debuginfo/trait-pointers.rs
index 71da71b897a..5cdefe94e50 100644
--- a/tests/debuginfo/trait-pointers.rs
+++ b/tests/debuginfo/trait-pointers.rs
@@ -1,10 +1,9 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 // gdb-command:run
 // lldb-command:run
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 trait Trait {
     fn method(&self) -> isize { 0 }
diff --git a/tests/debuginfo/tuple-in-struct.rs b/tests/debuginfo/tuple-in-struct.rs
index a74d6203f5f..bef96fad50c 100644
--- a/tests/debuginfo/tuple-in-struct.rs
+++ b/tests/debuginfo/tuple-in-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // gdb-command:run
 
@@ -28,8 +29,6 @@
 // gdb-check:$10 = tuple_in_struct::MixedPadding {x: ((40, 41, 42), (43, 44)), y: (45, 46, 47, 48)}
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct NoPadding1 {
     x: (i32, i32),
diff --git a/tests/debuginfo/tuple-in-tuple.rs b/tests/debuginfo/tuple-in-tuple.rs
index d4388095ad7..7bf97764c5c 100644
--- a/tests/debuginfo/tuple-in-tuple.rs
+++ b/tests/debuginfo/tuple-in-tuple.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -111,8 +112,6 @@
 // cdb-check:[...][1]              : 22 [Type: [...]]
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let no_padding1: ((u32, u32), u32, u32) = ((0, 1), 2, 3);
diff --git a/tests/debuginfo/tuple-struct.rs b/tests/debuginfo/tuple-struct.rs
index 0110203a7c7..a1bdaf1f3bb 100644
--- a/tests/debuginfo/tuple-struct.rs
+++ b/tests/debuginfo/tuple-struct.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -50,9 +51,6 @@
 // structs.
 
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 struct NoPadding16(u16, i16);
 struct NoPadding32(i32, f32, u32);
 struct NoPadding64(f64, i64, u64);
diff --git a/tests/debuginfo/tuple-style-enum.rs b/tests/debuginfo/tuple-style-enum.rs
index a759ad61c05..6113ccc10a1 100644
--- a/tests/debuginfo/tuple-style-enum.rs
+++ b/tests/debuginfo/tuple-style-enum.rs
@@ -1,6 +1,7 @@
 //@ min-lldb-version: 1800
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -37,8 +38,6 @@
 // lldb-check:(tuple_style_enum::Univariant) univariant = { value = { 0 = -1 } }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 use self::Regular::{Case1, Case2, Case3};
 use self::Univariant::TheOnlyCase;
diff --git a/tests/debuginfo/type-names.rs b/tests/debuginfo/type-names.rs
index ac61fef48fe..ecf7c597c0c 100644
--- a/tests/debuginfo/type-names.rs
+++ b/tests/debuginfo/type-names.rs
@@ -6,6 +6,7 @@
 //@ min-gdb-version: 9.2
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ==================================================================================
 
@@ -271,8 +272,6 @@
 // cdb-check:struct type_names::mod1::extern$0::ForeignType2 * foreign2 = [...]
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 #![feature(extern_types)]
 
 use std::marker::PhantomData;
diff --git a/tests/debuginfo/union-smoke.rs b/tests/debuginfo/union-smoke.rs
index 6043240069e..bd253794bd8 100644
--- a/tests/debuginfo/union-smoke.rs
+++ b/tests/debuginfo/union-smoke.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -18,8 +19,6 @@
 // lldb-check:[...] { a = { 0 = '\x01' 1 = '\x01' } b = 257 }
 
 #![allow(unused)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 union U {
     a: (u8, u8),
diff --git a/tests/debuginfo/unique-enum.rs b/tests/debuginfo/unique-enum.rs
index 230429278aa..e5a9c550135 100644
--- a/tests/debuginfo/unique-enum.rs
+++ b/tests/debuginfo/unique-enum.rs
@@ -1,6 +1,7 @@
 //@ min-lldb-version: 1800
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -30,8 +31,6 @@
 // lldb-check:(unique_enum::Univariant) *univariant = { value = { 0 = 123234 } }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
diff --git a/tests/debuginfo/unreachable-locals.rs b/tests/debuginfo/unreachable-locals.rs
index d4416387e0b..4d3f01fe423 100644
--- a/tests/debuginfo/unreachable-locals.rs
+++ b/tests/debuginfo/unreachable-locals.rs
@@ -1,8 +1,7 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 // No need to actually run the debugger, just make sure that the compiler can
 // handle locals in unreachable code.
diff --git a/tests/debuginfo/unsized.rs b/tests/debuginfo/unsized.rs
index edd9f5af557..e34eaaaacb9 100644
--- a/tests/debuginfo/unsized.rs
+++ b/tests/debuginfo/unsized.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 //@ ignore-gdb-version: 13.1 - 99.0
 // ^ https://sourceware.org/bugzilla/show_bug.cgi?id=30330
 
@@ -41,9 +42,6 @@
 // cdb-check:[+0x000] pointer          : 0x[...] [Type: unsized::Foo<dyn$<core::fmt::Debug> > *]
 // cdb-check:[...] vtable           : 0x[...] [Type: unsigned [...]int[...] (*)[4]]
 
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
-
 struct Foo<T: ?Sized> {
     value: T,
 }
diff --git a/tests/debuginfo/var-captured-in-nested-closure.rs b/tests/debuginfo/var-captured-in-nested-closure.rs
index 4e8700015ba..1795a352802 100644
--- a/tests/debuginfo/var-captured-in-nested-closure.rs
+++ b/tests/debuginfo/var-captured-in-nested-closure.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -115,8 +116,6 @@
 // cdb-check:closure_local    : 8 [Type: [...]]
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     a: isize,
diff --git a/tests/debuginfo/var-captured-in-sendable-closure.rs b/tests/debuginfo/var-captured-in-sendable-closure.rs
index cbb09daeb5f..2b0d4bb430a 100644
--- a/tests/debuginfo/var-captured-in-sendable-closure.rs
+++ b/tests/debuginfo/var-captured-in-sendable-closure.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -28,8 +29,6 @@
 // lldb-check:[...] 5
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     a: isize,
diff --git a/tests/debuginfo/var-captured-in-stack-closure.rs b/tests/debuginfo/var-captured-in-stack-closure.rs
index 0f84ea57b00..7fda71c2297 100644
--- a/tests/debuginfo/var-captured-in-stack-closure.rs
+++ b/tests/debuginfo/var-captured-in-stack-closure.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -100,8 +101,6 @@
 // cdb-check:owned            : 0x[...] : 6 [Type: [...] *]
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     a: isize,
diff --git a/tests/debuginfo/vec-slices.rs b/tests/debuginfo/vec-slices.rs
index 2b4d624976a..2a4e413612f 100644
--- a/tests/debuginfo/vec-slices.rs
+++ b/tests/debuginfo/vec-slices.rs
@@ -2,6 +2,7 @@
 // ^ test temporarily disabled as it fails under gdb 15
 
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -71,8 +72,6 @@
 // lldb-check:[...] size=2 { [0] = { x = 10 y = 11 z = 12 } [1] = { x = 13 y = 14 z = 15 } }
 
 #![allow(dead_code, unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 struct AStruct {
     x: i16,
diff --git a/tests/debuginfo/vec.rs b/tests/debuginfo/vec.rs
index 1093e38d878..fd75e7005af 100644
--- a/tests/debuginfo/vec.rs
+++ b/tests/debuginfo/vec.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-g
+//@ disable-gdb-pretty-printers
 
 // === GDB TESTS ===================================================================================
 
@@ -16,8 +17,6 @@
 // lldb-check:[...] { [0] = 1 [1] = 2 [2] = 3 }
 
 #![allow(unused_variables)]
-#![feature(omit_gdb_pretty_printer_section)]
-#![omit_gdb_pretty_printer_section]
 
 static mut VECT: [i32; 3] = [1, 2, 3];
 
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
index 109a41d1ef9..9bff257e063 100644
--- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
@@ -9,10 +9,6 @@
                     std::future::ResumeTy,
                     (),
                     (),
-                    CoroutineWitness(
-                        DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
-                        [],
-                    ),
                     (),
                 ],
             ),
@@ -30,10 +26,6 @@
                     std::future::ResumeTy,
                     (),
                     (),
-                    CoroutineWitness(
-                        DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
-                        [],
-                    ),
                     (),
                 ],
             ),
diff --git a/tests/mir-opt/building/custom/terminators.tail_call.built.after.mir b/tests/mir-opt/building/custom/terminators.tail_call.built.after.mir
index ab3925dae1c..feec68d3b0d 100644
--- a/tests/mir-opt/building/custom/terminators.tail_call.built.after.mir
+++ b/tests/mir-opt/building/custom/terminators.tail_call.built.after.mir
@@ -6,6 +6,6 @@ fn tail_call(_1: i32) -> i32 {
 
     bb0: {
         _2 = Add(copy _1, const 42_i32);
-        tailcall ident::<i32>(Spanned { node: copy _2, span: $DIR/terminators.rs:32:28: 32:29 (#0) });
+        tailcall ident::<i32>(copy _2);
     }
 }
diff --git a/tests/mir-opt/pre-codegen/derived_ord_debug.rs b/tests/mir-opt/pre-codegen/derived_ord_debug.rs
new file mode 100644
index 00000000000..1d6a884cee4
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/derived_ord_debug.rs
@@ -0,0 +1,18 @@
+//@ compile-flags: -Copt-level=0 -Zmir-opt-level=1 -Cdebuginfo=limited
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+#![crate_type = "lib"]
+
+#[derive(PartialOrd, Ord, PartialEq, Eq)]
+pub struct MultiField(char, i16);
+
+// EMIT_MIR derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.mir
+// EMIT_MIR derived_ord_debug.{impl#1}-cmp.PreCodegen.after.mir
+
+// CHECK-LABEL: partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering>
+// CHECK: = <char as PartialOrd>::partial_cmp(
+// CHECK: = <i16 as PartialOrd>::partial_cmp(
+
+// CHECK-LABEL: cmp(_1: &MultiField, _2: &MultiField) -> std::cmp::Ordering
+// CHECK: = <char as Ord>::cmp(
+// CHECK: = <i16 as Ord>::cmp(
diff --git a/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..9fc8da3a112
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,52 @@
+// MIR for `<impl at $DIR/derived_ord_debug.rs:6:10: 6:20>::partial_cmp` after PreCodegen
+
+fn <impl at $DIR/derived_ord_debug.rs:6:10: 6:20>::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering> {
+    debug self => _1;
+    debug other => _2;
+    let mut _0: std::option::Option<std::cmp::Ordering>;
+    let _3: &char;
+    let _4: &char;
+    let mut _5: std::option::Option<std::cmp::Ordering>;
+    let mut _6: isize;
+    let mut _7: i8;
+    let _8: &i16;
+    let _9: &i16;
+    scope 1 {
+        debug cmp => _5;
+    }
+
+    bb0: {
+        _3 = &((*_1).0: char);
+        _4 = &((*_2).0: char);
+        _5 = <char as PartialOrd>::partial_cmp(copy _3, copy _4) -> [return: bb1, unwind unreachable];
+    }
+
+    bb1: {
+        _6 = discriminant(_5);
+        switchInt(move _6) -> [1: bb2, 0: bb4, otherwise: bb6];
+    }
+
+    bb2: {
+        _7 = discriminant(((_5 as Some).0: std::cmp::Ordering));
+        switchInt(move _7) -> [0: bb3, otherwise: bb4];
+    }
+
+    bb3: {
+        _8 = &((*_1).1: i16);
+        _9 = &((*_2).1: i16);
+        _0 = <i16 as PartialOrd>::partial_cmp(copy _8, copy _9) -> [return: bb5, unwind unreachable];
+    }
+
+    bb4: {
+        _0 = copy _5;
+        goto -> bb5;
+    }
+
+    bb5: {
+        return;
+    }
+
+    bb6: {
+        unreachable;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..29cc5415076
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#0}-partial_cmp.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,52 @@
+// MIR for `<impl at $DIR/derived_ord_debug.rs:6:10: 6:20>::partial_cmp` after PreCodegen
+
+fn <impl at $DIR/derived_ord_debug.rs:6:10: 6:20>::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering> {
+    debug self => _1;
+    debug other => _2;
+    let mut _0: std::option::Option<std::cmp::Ordering>;
+    let _3: &char;
+    let _4: &char;
+    let mut _5: std::option::Option<std::cmp::Ordering>;
+    let mut _6: isize;
+    let mut _7: i8;
+    let _8: &i16;
+    let _9: &i16;
+    scope 1 {
+        debug cmp => _5;
+    }
+
+    bb0: {
+        _3 = &((*_1).0: char);
+        _4 = &((*_2).0: char);
+        _5 = <char as PartialOrd>::partial_cmp(copy _3, copy _4) -> [return: bb1, unwind continue];
+    }
+
+    bb1: {
+        _6 = discriminant(_5);
+        switchInt(move _6) -> [1: bb2, 0: bb4, otherwise: bb6];
+    }
+
+    bb2: {
+        _7 = discriminant(((_5 as Some).0: std::cmp::Ordering));
+        switchInt(move _7) -> [0: bb3, otherwise: bb4];
+    }
+
+    bb3: {
+        _8 = &((*_1).1: i16);
+        _9 = &((*_2).1: i16);
+        _0 = <i16 as PartialOrd>::partial_cmp(copy _8, copy _9) -> [return: bb5, unwind continue];
+    }
+
+    bb4: {
+        _0 = copy _5;
+        goto -> bb5;
+    }
+
+    bb5: {
+        return;
+    }
+
+    bb6: {
+        unreachable;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..66d96021aa9
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,42 @@
+// MIR for `<impl at $DIR/derived_ord_debug.rs:6:22: 6:25>::cmp` after PreCodegen
+
+fn <impl at $DIR/derived_ord_debug.rs:6:22: 6:25>::cmp(_1: &MultiField, _2: &MultiField) -> std::cmp::Ordering {
+    debug self => _1;
+    debug other => _2;
+    let mut _0: std::cmp::Ordering;
+    let _3: &char;
+    let _4: &char;
+    let mut _5: std::cmp::Ordering;
+    let mut _6: i8;
+    let _7: &i16;
+    let _8: &i16;
+    scope 1 {
+        debug cmp => _5;
+    }
+
+    bb0: {
+        _3 = &((*_1).0: char);
+        _4 = &((*_2).0: char);
+        _5 = <char as Ord>::cmp(copy _3, copy _4) -> [return: bb1, unwind unreachable];
+    }
+
+    bb1: {
+        _6 = discriminant(_5);
+        switchInt(move _6) -> [0: bb2, otherwise: bb3];
+    }
+
+    bb2: {
+        _7 = &((*_1).1: i16);
+        _8 = &((*_2).1: i16);
+        _0 = <i16 as Ord>::cmp(copy _7, copy _8) -> [return: bb4, unwind unreachable];
+    }
+
+    bb3: {
+        _0 = copy _5;
+        goto -> bb4;
+    }
+
+    bb4: {
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..2dcba6195f7
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,42 @@
+// MIR for `<impl at $DIR/derived_ord_debug.rs:6:22: 6:25>::cmp` after PreCodegen
+
+fn <impl at $DIR/derived_ord_debug.rs:6:22: 6:25>::cmp(_1: &MultiField, _2: &MultiField) -> std::cmp::Ordering {
+    debug self => _1;
+    debug other => _2;
+    let mut _0: std::cmp::Ordering;
+    let _3: &char;
+    let _4: &char;
+    let mut _5: std::cmp::Ordering;
+    let mut _6: i8;
+    let _7: &i16;
+    let _8: &i16;
+    scope 1 {
+        debug cmp => _5;
+    }
+
+    bb0: {
+        _3 = &((*_1).0: char);
+        _4 = &((*_2).0: char);
+        _5 = <char as Ord>::cmp(copy _3, copy _4) -> [return: bb1, unwind continue];
+    }
+
+    bb1: {
+        _6 = discriminant(_5);
+        switchInt(move _6) -> [0: bb2, otherwise: bb3];
+    }
+
+    bb2: {
+        _7 = &((*_1).1: i16);
+        _8 = &((*_2).1: i16);
+        _0 = <i16 as Ord>::cmp(copy _7, copy _8) -> [return: bb4, unwind continue];
+    }
+
+    bb3: {
+        _0 = copy _5;
+        goto -> bb4;
+    }
+
+    bb4: {
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir
index 2777bba893b..ba6ce0ee528 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir
@@ -8,7 +8,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
             let _2: std::ptr::NonNull<[T]>;
             let mut _3: *mut [T];
             let mut _4: *const [T];
-            let _12: ();
+            let _11: ();
             scope 3 {
                 let _8: std::ptr::alignment::AlignmentEnum;
                 scope 4 {
@@ -31,12 +31,11 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
                         scope 20 (inlined NonNull::<u8>::as_ptr) {
                         }
                         scope 21 (inlined std::alloc::dealloc) {
-                            let mut _11: usize;
+                            let mut _10: usize;
                             scope 22 (inlined Layout::size) {
                             }
                             scope 23 (inlined Layout::align) {
                                 scope 24 (inlined std::ptr::Alignment::as_usize) {
-                                    let mut _10: u32;
                                 }
                             }
                         }
@@ -87,16 +86,13 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
     bb2: {
         StorageLive(_9);
         _9 = copy _3 as *mut u8 (PtrToPtr);
-        StorageLive(_11);
         StorageLive(_10);
         _10 = discriminant(_8);
-        _11 = move _10 as usize (IntToInt);
-        StorageDead(_10);
-        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
+        _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable];
     }
 
     bb3: {
-        StorageDead(_11);
+        StorageDead(_10);
         StorageDead(_9);
         goto -> bb4;
     }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir
index 2777bba893b..ba6ce0ee528 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir
@@ -8,7 +8,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
             let _2: std::ptr::NonNull<[T]>;
             let mut _3: *mut [T];
             let mut _4: *const [T];
-            let _12: ();
+            let _11: ();
             scope 3 {
                 let _8: std::ptr::alignment::AlignmentEnum;
                 scope 4 {
@@ -31,12 +31,11 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
                         scope 20 (inlined NonNull::<u8>::as_ptr) {
                         }
                         scope 21 (inlined std::alloc::dealloc) {
-                            let mut _11: usize;
+                            let mut _10: usize;
                             scope 22 (inlined Layout::size) {
                             }
                             scope 23 (inlined Layout::align) {
                                 scope 24 (inlined std::ptr::Alignment::as_usize) {
-                                    let mut _10: u32;
                                 }
                             }
                         }
@@ -87,16 +86,13 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
     bb2: {
         StorageLive(_9);
         _9 = copy _3 as *mut u8 (PtrToPtr);
-        StorageLive(_11);
         StorageLive(_10);
         _10 = discriminant(_8);
-        _11 = move _10 as usize (IntToInt);
-        StorageDead(_10);
-        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
+        _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable];
     }
 
     bb3: {
-        StorageDead(_11);
+        StorageDead(_10);
         StorageDead(_9);
         goto -> bb4;
     }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir
index 2be0a478c85..ba6ce0ee528 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir
@@ -8,7 +8,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
             let _2: std::ptr::NonNull<[T]>;
             let mut _3: *mut [T];
             let mut _4: *const [T];
-            let _12: ();
+            let _11: ();
             scope 3 {
                 let _8: std::ptr::alignment::AlignmentEnum;
                 scope 4 {
@@ -31,12 +31,11 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
                         scope 20 (inlined NonNull::<u8>::as_ptr) {
                         }
                         scope 21 (inlined std::alloc::dealloc) {
-                            let mut _11: usize;
+                            let mut _10: usize;
                             scope 22 (inlined Layout::size) {
                             }
                             scope 23 (inlined Layout::align) {
                                 scope 24 (inlined std::ptr::Alignment::as_usize) {
-                                    let mut _10: u64;
                                 }
                             }
                         }
@@ -87,16 +86,13 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
     bb2: {
         StorageLive(_9);
         _9 = copy _3 as *mut u8 (PtrToPtr);
-        StorageLive(_11);
         StorageLive(_10);
         _10 = discriminant(_8);
-        _11 = move _10 as usize (IntToInt);
-        StorageDead(_10);
-        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
+        _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable];
     }
 
     bb3: {
-        StorageDead(_11);
+        StorageDead(_10);
         StorageDead(_9);
         goto -> bb4;
     }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir
index 2be0a478c85..ba6ce0ee528 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir
@@ -8,7 +8,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
             let _2: std::ptr::NonNull<[T]>;
             let mut _3: *mut [T];
             let mut _4: *const [T];
-            let _12: ();
+            let _11: ();
             scope 3 {
                 let _8: std::ptr::alignment::AlignmentEnum;
                 scope 4 {
@@ -31,12 +31,11 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
                         scope 20 (inlined NonNull::<u8>::as_ptr) {
                         }
                         scope 21 (inlined std::alloc::dealloc) {
-                            let mut _11: usize;
+                            let mut _10: usize;
                             scope 22 (inlined Layout::size) {
                             }
                             scope 23 (inlined Layout::align) {
                                 scope 24 (inlined std::ptr::Alignment::as_usize) {
-                                    let mut _10: u64;
                                 }
                             }
                         }
@@ -87,16 +86,13 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
     bb2: {
         StorageLive(_9);
         _9 = copy _3 as *mut u8 (PtrToPtr);
-        StorageLive(_11);
         StorageLive(_10);
         _10 = discriminant(_8);
-        _11 = move _10 as usize (IntToInt);
-        StorageDead(_10);
-        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
+        _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable];
     }
 
     bb3: {
-        StorageDead(_11);
+        StorageDead(_10);
         StorageDead(_9);
         goto -> bb4;
     }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs
index 11fb7afef0f..9ceba9444b8 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs
@@ -13,7 +13,6 @@ pub unsafe fn generic_in_place<T: Copy>(ptr: *mut Box<[T]>) {
     // CHECK: [[B:_.+]] = copy [[ALIGN]] as std::ptr::Alignment (Transmute);
     // CHECK: [[C:_.+]] = move ([[B]].0: std::ptr::alignment::AlignmentEnum);
     // CHECK: [[D:_.+]] = discriminant([[C]]);
-    // CHECK: [[E:_.+]] = move [[D]] as usize (IntToInt);
-    // CHECK: = alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[E]]) ->
+    // CHECK: = alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[D]]) ->
     std::ptr::drop_in_place(ptr)
 }
diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.option_direct.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/option_bubble_debug.option_direct.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..b29662dfa61
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/option_bubble_debug.option_direct.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,37 @@
+// MIR for `option_direct` after PreCodegen
+
+fn option_direct(_1: Option<u32>) -> Option<u32> {
+    debug x => _1;
+    let mut _0: std::option::Option<u32>;
+    let mut _2: isize;
+    let _3: u32;
+    let mut _4: u32;
+    scope 1 {
+        debug x => _3;
+    }
+
+    bb0: {
+        _2 = discriminant(_1);
+        switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4];
+    }
+
+    bb1: {
+        _0 = Option::<u32>::None;
+        goto -> bb3;
+    }
+
+    bb2: {
+        _3 = copy ((_1 as Some).0: u32);
+        _4 = Not(copy _3);
+        _0 = Option::<u32>::Some(move _4);
+        goto -> bb3;
+    }
+
+    bb3: {
+        return;
+    }
+
+    bb4: {
+        unreachable;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.option_direct.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/option_bubble_debug.option_direct.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..b29662dfa61
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/option_bubble_debug.option_direct.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,37 @@
+// MIR for `option_direct` after PreCodegen
+
+fn option_direct(_1: Option<u32>) -> Option<u32> {
+    debug x => _1;
+    let mut _0: std::option::Option<u32>;
+    let mut _2: isize;
+    let _3: u32;
+    let mut _4: u32;
+    scope 1 {
+        debug x => _3;
+    }
+
+    bb0: {
+        _2 = discriminant(_1);
+        switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4];
+    }
+
+    bb1: {
+        _0 = Option::<u32>::None;
+        goto -> bb3;
+    }
+
+    bb2: {
+        _3 = copy ((_1 as Some).0: u32);
+        _4 = Not(copy _3);
+        _0 = Option::<u32>::Some(move _4);
+        goto -> bb3;
+    }
+
+    bb3: {
+        return;
+    }
+
+    bb4: {
+        unreachable;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..5b401064dd0
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,47 @@
+// MIR for `option_traits` after PreCodegen
+
+fn option_traits(_1: Option<u32>) -> Option<u32> {
+    debug x => _1;
+    let mut _0: std::option::Option<u32>;
+    let mut _2: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
+    let mut _3: isize;
+    let _4: u32;
+    let mut _5: u32;
+    scope 1 {
+        debug residual => const Option::<Infallible>::None;
+        scope 2 {
+        }
+    }
+    scope 3 {
+        debug val => _4;
+        scope 4 {
+        }
+    }
+
+    bb0: {
+        _2 = <Option<u32> as Try>::branch(copy _1) -> [return: bb1, unwind unreachable];
+    }
+
+    bb1: {
+        _3 = discriminant(_2);
+        switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb5];
+    }
+
+    bb2: {
+        _4 = copy ((_2 as Continue).0: u32);
+        _5 = Not(copy _4);
+        _0 = <Option<u32> as Try>::from_output(move _5) -> [return: bb4, unwind unreachable];
+    }
+
+    bb3: {
+        _0 = <Option<u32> as FromResidual<Option<Infallible>>>::from_residual(const Option::<Infallible>::None) -> [return: bb4, unwind unreachable];
+    }
+
+    bb4: {
+        return;
+    }
+
+    bb5: {
+        unreachable;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..bda9e9d8e60
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,47 @@
+// MIR for `option_traits` after PreCodegen
+
+fn option_traits(_1: Option<u32>) -> Option<u32> {
+    debug x => _1;
+    let mut _0: std::option::Option<u32>;
+    let mut _2: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
+    let mut _3: isize;
+    let _4: u32;
+    let mut _5: u32;
+    scope 1 {
+        debug residual => const Option::<Infallible>::None;
+        scope 2 {
+        }
+    }
+    scope 3 {
+        debug val => _4;
+        scope 4 {
+        }
+    }
+
+    bb0: {
+        _2 = <Option<u32> as Try>::branch(copy _1) -> [return: bb1, unwind continue];
+    }
+
+    bb1: {
+        _3 = discriminant(_2);
+        switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb5];
+    }
+
+    bb2: {
+        _4 = copy ((_2 as Continue).0: u32);
+        _5 = Not(copy _4);
+        _0 = <Option<u32> as Try>::from_output(move _5) -> [return: bb4, unwind continue];
+    }
+
+    bb3: {
+        _0 = <Option<u32> as FromResidual<Option<Infallible>>>::from_residual(const Option::<Infallible>::None) -> [return: bb4, unwind continue];
+    }
+
+    bb4: {
+        return;
+    }
+
+    bb5: {
+        unreachable;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.rs b/tests/mir-opt/pre-codegen/option_bubble_debug.rs
new file mode 100644
index 00000000000..b9bf78a1d6e
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/option_bubble_debug.rs
@@ -0,0 +1,29 @@
+//@ compile-flags: -Copt-level=0 -Zmir-opt-level=1 -Cdebuginfo=limited
+//@ edition: 2024
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+#![crate_type = "lib"]
+#![feature(try_blocks)]
+
+// EMIT_MIR option_bubble_debug.option_direct.PreCodegen.after.mir
+pub fn option_direct(x: Option<u32>) -> Option<u32> {
+    // CHECK-LABEL: fn option_direct(_1: Option<u32>) -> Option<u32>
+    // CHECK: = discriminant(_1);
+    // CHECK: [[TEMP:_.+]] = Not({{.+}});
+    // CHECK: _0 = Option::<u32>::Some(move [[TEMP]]);
+
+    match x {
+        Some(x) => Some(!x),
+        None => None,
+    }
+}
+
+// EMIT_MIR option_bubble_debug.option_traits.PreCodegen.after.mir
+pub fn option_traits(x: Option<u32>) -> Option<u32> {
+    // CHECK-LABEL: fn option_traits(_1: Option<u32>) -> Option<u32>
+    // CHECK: = <Option<u32> as Try>::branch(copy _1)
+    // CHECK: [[TEMP:_.+]] = Not({{.+}});
+    // CHECK: _0 = <Option<u32> as Try>::from_output(move [[TEMP]])
+
+    try { !(x?) }
+}
diff --git a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff
new file mode 100644
index 00000000000..52832e73905
--- /dev/null
+++ b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff
@@ -0,0 +1,15 @@
+- // MIR for `cannot_opt_generic` before RemoveUnneededDrops
++ // MIR for `cannot_opt_generic` after RemoveUnneededDrops
+  
+  fn cannot_opt_generic(_1: T) -> () {
+      let mut _0: ();
+  
+      bb0: {
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff
deleted file mode 100644
index 0c73602bec8..00000000000
--- a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-- // MIR for `cannot_opt_generic` before RemoveUnneededDrops
-+ // MIR for `cannot_opt_generic` after RemoveUnneededDrops
-  
-  fn cannot_opt_generic(_1: T) -> () {
-      debug x => _1;
-      let mut _0: ();
-      let _2: ();
-      let mut _3: T;
-      scope 1 (inlined std::mem::drop::<T>) {
-      }
-  
-      bb0: {
-          nop;
-          StorageLive(_3);
-          _3 = move _1;
-          drop(_3) -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          StorageDead(_3);
-          nop;
-          nop;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff
deleted file mode 100644
index 59cce9fbcdd..00000000000
--- a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff
+++ /dev/null
@@ -1,30 +0,0 @@
-- // MIR for `cannot_opt_generic` before RemoveUnneededDrops
-+ // MIR for `cannot_opt_generic` after RemoveUnneededDrops
-  
-  fn cannot_opt_generic(_1: T) -> () {
-      debug x => _1;
-      let mut _0: ();
-      let _2: ();
-      let mut _3: T;
-      scope 1 (inlined std::mem::drop::<T>) {
-      }
-  
-      bb0: {
-          nop;
-          StorageLive(_3);
-          _3 = move _1;
-          drop(_3) -> [return: bb2, unwind: bb1];
-      }
-  
-      bb1 (cleanup): {
-          resume;
-      }
-  
-      bb2: {
-          StorageDead(_3);
-          nop;
-          nop;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff
new file mode 100644
index 00000000000..3d67cada5dd
--- /dev/null
+++ b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff
@@ -0,0 +1,15 @@
+- // MIR for `dont_opt` before RemoveUnneededDrops
++ // MIR for `dont_opt` after RemoveUnneededDrops
+  
+  fn dont_opt(_1: Vec<bool>) -> () {
+      let mut _0: ();
+  
+      bb0: {
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff
deleted file mode 100644
index 428b366b5a6..00000000000
--- a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-- // MIR for `dont_opt` before RemoveUnneededDrops
-+ // MIR for `dont_opt` after RemoveUnneededDrops
-  
-  fn dont_opt(_1: Vec<bool>) -> () {
-      debug x => _1;
-      let mut _0: ();
-      let _2: ();
-      let mut _3: std::vec::Vec<bool>;
-      scope 1 (inlined std::mem::drop::<Vec<bool>>) {
-      }
-  
-      bb0: {
-          nop;
-          StorageLive(_3);
-          _3 = move _1;
-          drop(_3) -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          StorageDead(_3);
-          nop;
-          nop;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff
deleted file mode 100644
index 445c1f82a96..00000000000
--- a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff
+++ /dev/null
@@ -1,30 +0,0 @@
-- // MIR for `dont_opt` before RemoveUnneededDrops
-+ // MIR for `dont_opt` after RemoveUnneededDrops
-  
-  fn dont_opt(_1: Vec<bool>) -> () {
-      debug x => _1;
-      let mut _0: ();
-      let _2: ();
-      let mut _3: std::vec::Vec<bool>;
-      scope 1 (inlined std::mem::drop::<Vec<bool>>) {
-      }
-  
-      bb0: {
-          nop;
-          StorageLive(_3);
-          _3 = move _1;
-          drop(_3) -> [return: bb2, unwind: bb1];
-      }
-  
-      bb1 (cleanup): {
-          resume;
-      }
-  
-      bb2: {
-          StorageDead(_3);
-          nop;
-          nop;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff
new file mode 100644
index 00000000000..cb7e58ca1a1
--- /dev/null
+++ b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff
@@ -0,0 +1,15 @@
+- // MIR for `opt` before RemoveUnneededDrops
++ // MIR for `opt` after RemoveUnneededDrops
+  
+  fn opt(_1: bool) -> () {
+      let mut _0: ();
+  
+      bb0: {
+-         drop(_1) -> [return: bb1, unwind unreachable];
+-     }
+- 
+-     bb1: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff
deleted file mode 100644
index 01eb6d4901f..00000000000
--- a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-- // MIR for `opt` before RemoveUnneededDrops
-+ // MIR for `opt` after RemoveUnneededDrops
-  
-  fn opt(_1: bool) -> () {
-      debug x => _1;
-      let mut _0: ();
-      let _2: ();
-      let mut _3: bool;
-      scope 1 (inlined std::mem::drop::<bool>) {
-      }
-  
-      bb0: {
--         nop;
-          StorageLive(_3);
-          _3 = copy _1;
--         drop(_3) -> [return: bb1, unwind unreachable];
--     }
-- 
--     bb1: {
-          StorageDead(_3);
--         nop;
--         nop;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff
deleted file mode 100644
index c2c3cb76e83..00000000000
--- a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-- // MIR for `opt` before RemoveUnneededDrops
-+ // MIR for `opt` after RemoveUnneededDrops
-  
-  fn opt(_1: bool) -> () {
-      debug x => _1;
-      let mut _0: ();
-      let _2: ();
-      let mut _3: bool;
-      scope 1 (inlined std::mem::drop::<bool>) {
-      }
-  
-      bb0: {
--         nop;
-          StorageLive(_3);
-          _3 = copy _1;
--         drop(_3) -> [return: bb1, unwind continue];
--     }
-- 
--     bb1: {
-          StorageDead(_3);
--         nop;
--         nop;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff
new file mode 100644
index 00000000000..1e166eee9fb
--- /dev/null
+++ b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff
@@ -0,0 +1,15 @@
+- // MIR for `opt_generic_copy` before RemoveUnneededDrops
++ // MIR for `opt_generic_copy` after RemoveUnneededDrops
+  
+  fn opt_generic_copy(_1: T) -> () {
+      let mut _0: ();
+  
+      bb0: {
+-         drop(_1) -> [return: bb1, unwind unreachable];
+-     }
+- 
+-     bb1: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff
deleted file mode 100644
index a82ede6196e..00000000000
--- a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-- // MIR for `opt_generic_copy` before RemoveUnneededDrops
-+ // MIR for `opt_generic_copy` after RemoveUnneededDrops
-  
-  fn opt_generic_copy(_1: T) -> () {
-      debug x => _1;
-      let mut _0: ();
-      let _2: ();
-      let mut _3: T;
-      scope 1 (inlined std::mem::drop::<T>) {
-      }
-  
-      bb0: {
--         nop;
-          StorageLive(_3);
-          _3 = copy _1;
--         drop(_3) -> [return: bb1, unwind unreachable];
--     }
-- 
--     bb1: {
-          StorageDead(_3);
--         nop;
--         nop;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff
deleted file mode 100644
index 6e7c9ead740..00000000000
--- a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-- // MIR for `opt_generic_copy` before RemoveUnneededDrops
-+ // MIR for `opt_generic_copy` after RemoveUnneededDrops
-  
-  fn opt_generic_copy(_1: T) -> () {
-      debug x => _1;
-      let mut _0: ();
-      let _2: ();
-      let mut _3: T;
-      scope 1 (inlined std::mem::drop::<T>) {
-      }
-  
-      bb0: {
--         nop;
-          StorageLive(_3);
-          _3 = copy _1;
--         drop(_3) -> [return: bb1, unwind continue];
--     }
-- 
--     bb1: {
-          StorageDead(_3);
--         nop;
--         nop;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/remove_unneeded_drops.rs b/tests/mir-opt/remove_unneeded_drops.rs
index cad79e0aa0c..49dc611838e 100644
--- a/tests/mir-opt/remove_unneeded_drops.rs
+++ b/tests/mir-opt/remove_unneeded_drops.rs
@@ -1,28 +1,56 @@
-// skip-filecheck
-// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+//@ test-mir-pass: RemoveUnneededDrops
+
+#![feature(custom_mir, core_intrinsics)]
+use std::intrinsics::mir::*;
+
 // EMIT_MIR remove_unneeded_drops.opt.RemoveUnneededDrops.diff
+#[custom_mir(dialect = "runtime")]
 fn opt(x: bool) {
-    drop(x);
+    // CHECK-LABEL: fn opt(
+    // CHECK-NOT: drop(
+    mir! {
+        { Drop(x, ReturnTo(bb1), UnwindUnreachable()) }
+        bb1 = { Return() }
+    }
 }
 
 // EMIT_MIR remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff
+#[custom_mir(dialect = "runtime")]
 fn dont_opt(x: Vec<bool>) {
-    drop(x);
+    // CHECK-LABEL: fn dont_opt(
+    // CHECK: drop(
+    mir! {
+        { Drop(x, ReturnTo(bb1), UnwindUnreachable()) }
+        bb1 = { Return() }
+    }
 }
 
 // EMIT_MIR remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff
+#[custom_mir(dialect = "runtime")]
 fn opt_generic_copy<T: Copy>(x: T) {
-    drop(x);
+    // CHECK-LABEL: fn opt_generic_copy(
+    // CHECK-NOT: drop(
+    mir! {
+        { Drop(x, ReturnTo(bb1), UnwindUnreachable()) }
+        bb1 = { Return() }
+    }
 }
 
 // EMIT_MIR remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff
 // since the pass is not running on monomorphisized code,
 // we can't (but probably should) optimize this
+#[custom_mir(dialect = "runtime")]
 fn cannot_opt_generic<T>(x: T) {
-    drop(x);
+    // CHECK-LABEL: fn cannot_opt_generic(
+    // CHECK: drop(
+    mir! {
+        { Drop(x, ReturnTo(bb1), UnwindUnreachable()) }
+        bb1 = { Return() }
+    }
 }
 
 fn main() {
+    // CHECK-LABEL: fn main(
     opt(true);
     opt_generic_copy(42);
     cannot_opt_generic(42);
diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff
index a8c57d2cfe0..4fba0032729 100644
--- a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff
+++ b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff
@@ -93,7 +93,7 @@
       }
   
       bb11: {
-          tailcall g_with_arg(Spanned { node: move _10, span: $DIR/tail_call_drops.rs:36:23: 36:36 (#0) }, Spanned { node: move _11, span: $DIR/tail_call_drops.rs:36:38: 36:51 (#0) });
+          tailcall g_with_arg(move _10, move _11);
       }
   
       bb12 (cleanup): {
diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff
index a8c57d2cfe0..4fba0032729 100644
--- a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff
+++ b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff
@@ -93,7 +93,7 @@
       }
   
       bb11: {
-          tailcall g_with_arg(Spanned { node: move _10, span: $DIR/tail_call_drops.rs:36:23: 36:36 (#0) }, Spanned { node: move _11, span: $DIR/tail_call_drops.rs:36:38: 36:51 (#0) });
+          tailcall g_with_arg(move _10, move _11);
       }
   
       bb12 (cleanup): {
diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir
index f89b98a3205..9ec358ec189 100644
--- a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir
+++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir
@@ -90,7 +90,7 @@ fn f_with_arg(_1: String, _2: String) -> () {
     }
 
     bb11: {
-        tailcall g_with_arg(Spanned { node: move _10, span: $DIR/tail_call_drops.rs:36:23: 36:36 (#0) }, Spanned { node: move _11, span: $DIR/tail_call_drops.rs:36:38: 36:51 (#0) });
+        tailcall g_with_arg(move _10, move _11);
     }
 
     bb12: {
diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir
index f89b98a3205..9ec358ec189 100644
--- a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir
+++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir
@@ -90,7 +90,7 @@ fn f_with_arg(_1: String, _2: String) -> () {
     }
 
     bb11: {
-        tailcall g_with_arg(Spanned { node: move _10, span: $DIR/tail_call_drops.rs:36:23: 36:36 (#0) }, Spanned { node: move _11, span: $DIR/tail_call_drops.rs:36:38: 36:51 (#0) });
+        tailcall g_with_arg(move _10, move _11);
     }
 
     bb12: {
diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
index e58762aeb6d..89754cdaf90 100644
--- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
+++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
@@ -13,42 +13,56 @@
 
 //@ only-x86_64-fortanix-unknown-sgx
 
-use run_make_support::{cmd, cwd, llvm_filecheck, llvm_objdump, regex, set_current_dir, target};
+use run_make_support::{
+    cargo, cwd, llvm_filecheck, llvm_objdump, regex, run, set_current_dir, target,
+};
 
 fn main() {
-    let main_dir = cwd();
-    set_current_dir("enclave");
-    // HACK(eddyb) sets `RUSTC_BOOTSTRAP=1` so Cargo can accept nightly features.
-    // These come from the top-level Rust workspace, that this crate is not a
-    // member of, but Cargo tries to load the workspace `Cargo.toml` anyway.
-    cmd("cargo")
-        .env("RUSTC_BOOTSTRAP", "1")
+    cargo()
         .arg("-v")
-        .arg("run")
+        .arg("build")
         .arg("--target")
         .arg(target())
+        .current_dir("enclave")
+        .env("CC_x86_64_fortanix_unknown_sgx", "clang")
+        .env(
+            "CFLAGS_x86_64_fortanix_unknown_sgx",
+            "-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening",
+        )
+        .env("CXX_x86_64_fortanix_unknown_sgx", "clang++")
+        .env(
+            "CXXFLAGS_x86_64_fortanix_unknown_sgx",
+            "-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening",
+        )
         .run();
-    set_current_dir(&main_dir);
-    // Rust has various ways of adding code to a binary:
+
+    // Rust has several ways of including machine code into a binary:
+    //
     // - Rust code
     // - Inline assembly
     // - Global assembly
     // - C/C++ code compiled as part of Rust crates
-    // For those different kinds, we do have very small code examples that should be
-    // mitigated in some way. Mostly we check that ret instructions should no longer be present.
+    //
+    // For each of those, check that the mitigations are applied. Mostly we check
+    // that ret instructions are no longer present.
+
+    // Check that normal rust code has the right mitigations.
     check("unw_getcontext", "unw_getcontext.checks");
     check("__libunwind_Registers_x86_64_jumpto", "jumpto.checks");
 
     check("std::io::stdio::_print::[[:alnum:]]+", "print.with_frame_pointers.checks");
 
+    // Check that rust global assembly has the right mitigations.
     check("rust_plus_one_global_asm", "rust_plus_one_global_asm.checks");
 
+    // Check that C code compiled using the `cc` crate has the right mitigations.
     check("cc_plus_one_c", "cc_plus_one_c.checks");
     check("cc_plus_one_c_asm", "cc_plus_one_c_asm.checks");
     check("cc_plus_one_cxx", "cc_plus_one_cxx.checks");
     check("cc_plus_one_cxx_asm", "cc_plus_one_cxx_asm.checks");
     check("cc_plus_one_asm", "cc_plus_one_asm.checks");
 
+    // Check that C++ code compiled using the `cc` crate has the right mitigations.
     check("cmake_plus_one_c", "cmake_plus_one_c.checks");
     check("cmake_plus_one_c_asm", "cmake_plus_one_c_asm.checks");
     check("cmake_plus_one_c_global_asm", "cmake_plus_one_c_global_asm.checks");
@@ -71,8 +85,7 @@ fn check(func_re: &str, mut checks: &str) {
         .input("enclave/target/x86_64-fortanix-unknown-sgx/debug/enclave")
         .args(&["--demangle", &format!("--disassemble-symbols={func}")])
         .run()
-        .stdout_utf8();
-    let dump = dump.as_bytes();
+        .stdout();
 
     // Unique case, must succeed at one of two possible tests.
     // This is because frame pointers are optional, and them being enabled requires
diff --git a/tests/rustdoc-json/attrs/macro_export.rs b/tests/rustdoc-json/attrs/macro_export.rs
new file mode 100644
index 00000000000..5d487cf6a56
--- /dev/null
+++ b/tests/rustdoc-json/attrs/macro_export.rs
@@ -0,0 +1,40 @@
+//@ compile-flags: --document-private-items
+
+//@ set exported_id = "$.index[?(@.name=='exported')].id"
+//@ is "$.index[?(@.name=='exported')].attrs" '["macro_export"]'
+//@ is "$.index[?(@.name=='exported')].visibility" '"public"'
+
+#[macro_export]
+macro_rules! exported {
+    () => {};
+}
+
+//@ set not_exported_id = "$.index[?(@.name=='not_exported')].id"
+//@ is "$.index[?(@.name=='not_exported')].attrs" []
+//@ is "$.index[?(@.name=='not_exported')].visibility" '"crate"'
+macro_rules! not_exported {
+    () => {};
+}
+
+//@ set module_id = "$.index[?(@.name=='module')].id"
+pub mod module {
+    //@ set exported_from_mod_id = "$.index[?(@.name=='exported_from_mod')].id"
+    //@ is "$.index[?(@.name=='exported_from_mod')].attrs" '["macro_export"]'
+    //@ is "$.index[?(@.name=='exported_from_mod')].visibility" '"public"'
+    #[macro_export]
+    macro_rules! exported_from_mod {
+        () => {};
+    }
+
+    //@ set not_exported_from_mod_id = "$.index[?(@.name=='not_exported_from_mod')].id"
+    //@ is "$.index[?(@.name=='not_exported_from_mod')].attrs" []
+    //@ is "$.index[?(@.name=='not_exported_from_mod')].visibility" '"crate"'
+    macro_rules! not_exported_from_mod {
+        () => {};
+    }
+}
+// The non-exported macro's are left in place, but the #[macro_export]'d ones
+// are moved to the crate root.
+
+//@ is "$.index[?(@.name=='module')].inner.module.items[*]" $not_exported_from_mod_id
+//@ ismany "$.index[?(@.name=='macro_export')].inner.module.items[*]" $exported_id $not_exported_id $module_id $exported_from_mod_id
diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs
index 1174e16dd53..cb277d529ce 100644
--- a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs
+++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs
@@ -2,67 +2,67 @@
 //@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
 
 //! [struct@m!()]   //~ WARN: unmatched disambiguator `struct` and suffix `!()`
-//! [struct@m!{}]
+//! [struct@m!{}]   //~ WARN: unmatched disambiguator `struct` and suffix `!{}`
 //! [struct@m![]]
 //! [struct@f()]    //~ WARN: unmatched disambiguator `struct` and suffix `()`
 //! [struct@m!]     //~ WARN: unmatched disambiguator `struct` and suffix `!`
 //!
 //! [enum@m!()]     //~ WARN: unmatched disambiguator `enum` and suffix `!()`
-//! [enum@m!{}]
+//! [enum@m!{}]     //~ WARN: unmatched disambiguator `enum` and suffix `!{}`
 //! [enum@m![]]
 //! [enum@f()]      //~ WARN: unmatched disambiguator `enum` and suffix `()`
 //! [enum@m!]       //~ WARN: unmatched disambiguator `enum` and suffix `!`
 //!
 //! [trait@m!()]    //~ WARN: unmatched disambiguator `trait` and suffix `!()`
-//! [trait@m!{}]
+//! [trait@m!{}]    //~ WARN: unmatched disambiguator `trait` and suffix `!{}`
 //! [trait@m![]]
 //! [trait@f()]     //~ WARN: unmatched disambiguator `trait` and suffix `()`
 //! [trait@m!]      //~ WARN: unmatched disambiguator `trait` and suffix `!`
 //!
 //! [module@m!()]   //~ WARN: unmatched disambiguator `module` and suffix `!()`
-//! [module@m!{}]
+//! [module@m!{}]   //~ WARN: unmatched disambiguator `module` and suffix `!{}`
 //! [module@m![]]
 //! [module@f()]    //~ WARN: unmatched disambiguator `module` and suffix `()`
 //! [module@m!]     //~ WARN: unmatched disambiguator `module` and suffix `!`
 //!
 //! [mod@m!()]      //~ WARN: unmatched disambiguator `mod` and suffix `!()`
-//! [mod@m!{}]
+//! [mod@m!{}]      //~ WARN: unmatched disambiguator `mod` and suffix `!{}`
 //! [mod@m![]]
 //! [mod@f()]       //~ WARN: unmatched disambiguator `mod` and suffix `()`
 //! [mod@m!]        //~ WARN: unmatched disambiguator `mod` and suffix `!`
 //!
 //! [const@m!()]    //~ WARN: unmatched disambiguator `const` and suffix `!()`
-//! [const@m!{}]
+//! [const@m!{}]    //~ WARN: unmatched disambiguator `const` and suffix `!{}`
 //! [const@m![]]
 //! [const@f()]     //~ WARN: incompatible link kind for `f`
 //! [const@m!]      //~ WARN: unmatched disambiguator `const` and suffix `!`
 //!
 //! [constant@m!()]   //~ WARN: unmatched disambiguator `constant` and suffix `!()`
-//! [constant@m!{}]
+//! [constant@m!{}]   //~ WARN:  unmatched disambiguator `constant` and suffix `!{}`
 //! [constant@m![]]
 //! [constant@f()]    //~ WARN: incompatible link kind for `f`
 //! [constant@m!]     //~ WARN: unmatched disambiguator `constant` and suffix `!`
 //!
 //! [static@m!()]   //~ WARN: unmatched disambiguator `static` and suffix `!()`
-//! [static@m!{}]
+//! [static@m!{}]   //~ WARN: unmatched disambiguator `static` and suffix `!{}`
 //! [static@m![]]
 //! [static@f()]    //~ WARN: incompatible link kind for `f`
 //! [static@m!]     //~ WARN: unmatched disambiguator `static` and suffix `!`
 //!
 //! [function@m!()]   //~ WARN: unmatched disambiguator `function` and suffix `!()`
-//! [function@m!{}]
+//! [function@m!{}]   //~ WARN: unmatched disambiguator `function` and suffix `!{}`
 //! [function@m![]]
 //! [function@f()]
 //! [function@m!]     //~ WARN: unmatched disambiguator `function` and suffix `!`
 //!
 //! [fn@m!()]   //~ WARN: unmatched disambiguator `fn` and suffix `!()`
-//! [fn@m!{}]
+//! [fn@m!{}]   //~ WARN: unmatched disambiguator `fn` and suffix `!{}`
 //! [fn@m![]]
 //! [fn@f()]
 //! [fn@m!]     //~ WARN: unmatched disambiguator `fn` and suffix `!`
 //!
 //! [method@m!()]   //~ WARN: unmatched disambiguator `method` and suffix `!()`
-//! [method@m!{}]
+//! [method@m!{}]   //~ WARN: unmatched disambiguator `method` and suffix `!{}`
 //! [method@m![]]
 //! [method@f()]
 //! [method@m!]     //~ WARN: unmatched disambiguator `method` and suffix `!`
@@ -74,13 +74,13 @@
 //! [derive@m!]     //~ WARN: incompatible link kind for `m`
 //!
 //! [type@m!()]   //~ WARN: unmatched disambiguator `type` and suffix `!()`
-//! [type@m!{}]
+//! [type@m!{}]   //~ WARN: unmatched disambiguator `type` and suffix `!{}`
 //! [type@m![]]
 //! [type@f()]    //~ WARN: unmatched disambiguator `type` and suffix `()`
 //! [type@m!]     //~ WARN: unmatched disambiguator `type` and suffix `!`
 //!
 //! [value@m!()]   //~ WARN: unmatched disambiguator `value` and suffix `!()`
-//! [value@m!{}]
+//! [value@m!{}]   //~ WARN: unmatched disambiguator `value` and suffix `!{}`
 //! [value@m![]]
 //! [value@f()]
 //! [value@m!]     //~ WARN: unmatched disambiguator `value` and suffix `!`
@@ -92,13 +92,13 @@
 //! [macro@m!]
 //!
 //! [prim@m!()]   //~ WARN: unmatched disambiguator `prim` and suffix `!()`
-//! [prim@m!{}]
+//! [prim@m!{}]   //~ WARN: unmatched disambiguator `prim` and suffix `!{}`
 //! [prim@m![]]
 //! [prim@f()]    //~ WARN: unmatched disambiguator `prim` and suffix `()`
 //! [prim@m!]     //~ WARN: unmatched disambiguator `prim` and suffix `!`
 //!
 //! [primitive@m!()]   //~ WARN: unmatched disambiguator `primitive` and suffix `!()`
-//! [primitive@m!{}]
+//! [primitive@m!{}]   //~ WARN: unmatched disambiguator `primitive` and suffix `!{}`
 //! [primitive@m![]]
 //! [primitive@f()]    //~ WARN: unmatched disambiguator `primitive` and suffix `()`
 //! [primitive@m!]     //~ WARN: unmatched disambiguator `primitive` and suffix `!`
diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr
index f4e40a48873..18403385968 100644
--- a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr
+++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr
@@ -7,6 +7,14 @@ LL | //! [struct@m!()]
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
    = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
 
+warning: unmatched disambiguator `struct` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:5:6
+   |
+LL | //! [struct@m!{}]
+   |      ^^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `struct` and suffix `()`
   --> $DIR/disambiguator-endswith-named-suffix.rs:7:6
    |
@@ -31,6 +39,14 @@ LL | //! [enum@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `enum` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:11:6
+   |
+LL | //! [enum@m!{}]
+   |      ^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `enum` and suffix `()`
   --> $DIR/disambiguator-endswith-named-suffix.rs:13:6
    |
@@ -55,6 +71,14 @@ LL | //! [trait@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `trait` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:17:6
+   |
+LL | //! [trait@m!{}]
+   |      ^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `trait` and suffix `()`
   --> $DIR/disambiguator-endswith-named-suffix.rs:19:6
    |
@@ -79,6 +103,14 @@ LL | //! [module@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `module` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:23:6
+   |
+LL | //! [module@m!{}]
+   |      ^^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `module` and suffix `()`
   --> $DIR/disambiguator-endswith-named-suffix.rs:25:6
    |
@@ -103,6 +135,14 @@ LL | //! [mod@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `mod` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:29:6
+   |
+LL | //! [mod@m!{}]
+   |      ^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `mod` and suffix `()`
   --> $DIR/disambiguator-endswith-named-suffix.rs:31:6
    |
@@ -127,6 +167,14 @@ LL | //! [const@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `const` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:35:6
+   |
+LL | //! [const@m!{}]
+   |      ^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: incompatible link kind for `f`
   --> $DIR/disambiguator-endswith-named-suffix.rs:37:6
    |
@@ -155,6 +203,14 @@ LL | //! [constant@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `constant` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:41:6
+   |
+LL | //! [constant@m!{}]
+   |      ^^^^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: incompatible link kind for `f`
   --> $DIR/disambiguator-endswith-named-suffix.rs:43:6
    |
@@ -183,6 +239,14 @@ LL | //! [static@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `static` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:47:6
+   |
+LL | //! [static@m!{}]
+   |      ^^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: incompatible link kind for `f`
   --> $DIR/disambiguator-endswith-named-suffix.rs:49:6
    |
@@ -211,6 +275,14 @@ LL | //! [function@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `function` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:53:6
+   |
+LL | //! [function@m!{}]
+   |      ^^^^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `function` and suffix `!`
   --> $DIR/disambiguator-endswith-named-suffix.rs:56:6
    |
@@ -227,6 +299,14 @@ LL | //! [fn@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `fn` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:59:6
+   |
+LL | //! [fn@m!{}]
+   |      ^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `fn` and suffix `!`
   --> $DIR/disambiguator-endswith-named-suffix.rs:62:6
    |
@@ -243,6 +323,14 @@ LL | //! [method@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `method` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:65:6
+   |
+LL | //! [method@m!{}]
+   |      ^^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `method` and suffix `!`
   --> $DIR/disambiguator-endswith-named-suffix.rs:68:6
    |
@@ -303,6 +391,14 @@ LL | //! [type@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `type` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:77:6
+   |
+LL | //! [type@m!{}]
+   |      ^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `type` and suffix `()`
   --> $DIR/disambiguator-endswith-named-suffix.rs:79:6
    |
@@ -327,6 +423,14 @@ LL | //! [value@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `value` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:83:6
+   |
+LL | //! [value@m!{}]
+   |      ^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `value` and suffix `!`
   --> $DIR/disambiguator-endswith-named-suffix.rs:86:6
    |
@@ -351,6 +455,14 @@ LL | //! [prim@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `prim` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:95:6
+   |
+LL | //! [prim@m!{}]
+   |      ^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `prim` and suffix `()`
   --> $DIR/disambiguator-endswith-named-suffix.rs:97:6
    |
@@ -375,6 +487,14 @@ LL | //! [primitive@m!()]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
+warning: unmatched disambiguator `primitive` and suffix `!{}`
+  --> $DIR/disambiguator-endswith-named-suffix.rs:101:6
+   |
+LL | //! [primitive@m!{}]
+   |      ^^^^^^^^^
+   |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+
 warning: unmatched disambiguator `primitive` and suffix `()`
   --> $DIR/disambiguator-endswith-named-suffix.rs:103:6
    |
@@ -391,5 +511,5 @@ LL | //! [primitive@m!]
    |
    = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
-warning: 46 warnings emitted
+warning: 61 warnings emitted
 
diff --git a/tests/rustdoc-ui/intra-doc/bad-intra-doc.rs b/tests/rustdoc-ui/intra-doc/bad-intra-doc.rs
new file mode 100644
index 00000000000..c24a848d898
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/bad-intra-doc.rs
@@ -0,0 +1,15 @@
+#![no_std]
+#![deny(rustdoc::broken_intra_doc_links)]
+
+// regression test for https://github.com/rust-lang/rust/issues/54191
+
+/// this is not a link to [`example.com`] //~ERROR unresolved link
+///
+/// this link [`has spaces in it`].
+///
+/// attempted link to method: [`Foo.bar()`] //~ERROR unresolved link
+///
+/// classic broken intra-doc link: [`Bar`] //~ERROR unresolved link
+///
+/// no backticks, so we let this one slide: [Foo.bar()]
+pub struct Foo;
diff --git a/tests/rustdoc-ui/intra-doc/bad-intra-doc.stderr b/tests/rustdoc-ui/intra-doc/bad-intra-doc.stderr
new file mode 100644
index 00000000000..9533792b35b
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/bad-intra-doc.stderr
@@ -0,0 +1,31 @@
+error: unresolved link to `example.com`
+  --> $DIR/bad-intra-doc.rs:6:29
+   |
+LL | /// this is not a link to [`example.com`]
+   |                             ^^^^^^^^^^^ no item named `example.com` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+note: the lint level is defined here
+  --> $DIR/bad-intra-doc.rs:2:9
+   |
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unresolved link to `Foo.bar`
+  --> $DIR/bad-intra-doc.rs:10:33
+   |
+LL | /// attempted link to method: [`Foo.bar()`]
+   |                                 ^^^^^^^^^ no item named `Foo.bar` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+error: unresolved link to `Bar`
+  --> $DIR/bad-intra-doc.rs:12:38
+   |
+LL | /// classic broken intra-doc link: [`Bar`]
+   |                                      ^^^ no item named `Bar` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.rs b/tests/rustdoc-ui/intra-doc/weird-syntax.rs
index d2a922b2b62..1c5977b1bc3 100644
--- a/tests/rustdoc-ui/intra-doc/weird-syntax.rs
+++ b/tests/rustdoc-ui/intra-doc/weird-syntax.rs
@@ -65,7 +65,7 @@ pub struct XLinkToCloneWithStartSpace;
 /// [x][struct@Clone ] //~ERROR link
 pub struct XLinkToCloneWithEndSpace;
 
-/// [x][Clone\(\)] not URL-shaped enough
+/// [x][Clone\(\)] //~ERROR link
 pub struct XLinkToCloneWithEscapedParens;
 
 /// [x][`Clone`] not URL-shaped enough
diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr
index ad813f0f9b6..7f2fc1fe625 100644
--- a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr
+++ b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr
@@ -123,6 +123,14 @@ LL - /// [x][struct@Clone ]
 LL + /// [x][trait@Clone ]
    |
 
+error: unresolved link to `Clone\(\)`
+  --> $DIR/weird-syntax.rs:68:9
+   |
+LL | /// [x][Clone\(\)]
+   |         ^^^^^^^^^ no item named `Clone\(\)` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
 error: unresolved link to `Clone`
   --> $DIR/weird-syntax.rs:74:9
    |
@@ -299,5 +307,5 @@ LL | /// - [`SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER`]: the
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-error: aborting due to 27 previous errors
+error: aborting due to 28 previous errors
 
diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs
index 4f4590d45fc..81cd6c73d1c 100644
--- a/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs
+++ b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs
@@ -1,18 +1,24 @@
 //@ check-pass
 
-/// [`…foo`] [`…bar`] [`Err`]
+/// [`…foo`] //~ WARN: unresolved link
+/// [`…bar`] //~ WARN: unresolved link
+/// [`Err`]
 pub struct Broken {}
 
-/// [`…`] [`…`] [`Err`]
+/// [`…`] //~ WARN: unresolved link
+/// [`…`] //~ WARN: unresolved link
+/// [`Err`]
 pub struct Broken2 {}
 
-/// [`…`][…] [`…`][…] [`Err`]
+/// [`…`][…] //~ WARN: unresolved link
+/// [`…`][…] //~ WARN: unresolved link
+/// [`Err`]
 pub struct Broken3 {}
 
 /// […………………………][Broken3]
 pub struct Broken4 {}
 
-/// [Broken3][…………………………]
+/// [Broken3][…………………………] //~ WARN: unresolved link
 pub struct Broken5 {}
 
 pub struct Err;
diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.stderr b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.stderr
new file mode 100644
index 00000000000..0a5ff68b908
--- /dev/null
+++ b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.stderr
@@ -0,0 +1,59 @@
+warning: unresolved link to `…foo`
+  --> $DIR/redundant_explicit_links-utf8.rs:3:7
+   |
+LL | /// [`…foo`]
+   |       ^^^^ no item named `…foo` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
+
+warning: unresolved link to `…bar`
+  --> $DIR/redundant_explicit_links-utf8.rs:4:7
+   |
+LL | /// [`…bar`]
+   |       ^^^^ no item named `…bar` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+warning: unresolved link to `…`
+  --> $DIR/redundant_explicit_links-utf8.rs:8:7
+   |
+LL | /// [`…`]
+   |       ^ no item named `…` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+warning: unresolved link to `…`
+  --> $DIR/redundant_explicit_links-utf8.rs:9:7
+   |
+LL | /// [`…`]
+   |       ^ no item named `…` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+warning: unresolved link to `…`
+  --> $DIR/redundant_explicit_links-utf8.rs:13:11
+   |
+LL | /// [`…`][…]
+   |           ^ no item named `…` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+warning: unresolved link to `…`
+  --> $DIR/redundant_explicit_links-utf8.rs:14:11
+   |
+LL | /// [`…`][…]
+   |           ^ no item named `…` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+warning: unresolved link to `…………………………`
+  --> $DIR/redundant_explicit_links-utf8.rs:21:15
+   |
+LL | /// [Broken3][…………………………]
+   |               ^^^^^^^^^^ no item named `…………………………` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+warning: 7 warnings emitted
+
diff --git a/tests/rustdoc/attribute-rendering.rs b/tests/rustdoc/attribute-rendering.rs
index 841533814c3..bf9b81077f3 100644
--- a/tests/rustdoc/attribute-rendering.rs
+++ b/tests/rustdoc/attribute-rendering.rs
@@ -1,7 +1,7 @@
 #![crate_name = "foo"]
 
 //@ has 'foo/fn.f.html'
-//@ has - //*[@'class="rust item-decl"]' '#[export_name = "f"] pub fn f()'
-#[export_name = "\
-f"]
+//@ has - //*[@'class="rust item-decl"]' '#[unsafe(export_name = "f")] pub fn f()'
+#[unsafe(export_name = "\
+f")]
 pub fn f() {}
diff --git a/tests/rustdoc/attributes-2021-edition.rs b/tests/rustdoc/attributes-2021-edition.rs
new file mode 100644
index 00000000000..b5028d8c852
--- /dev/null
+++ b/tests/rustdoc/attributes-2021-edition.rs
@@ -0,0 +1,14 @@
+//@ edition: 2021
+#![crate_name = "foo"]
+
+//@ has foo/fn.f.html '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]'
+#[no_mangle]
+pub extern "C" fn f() {}
+
+//@ has foo/fn.g.html '//pre[@class="rust item-decl"]' '#[unsafe(export_name = "bar")]'
+#[export_name = "bar"]
+pub extern "C" fn g() {}
+
+//@ has foo/fn.example.html '//pre[@class="rust item-decl"]' '#[unsafe(link_section = ".text")]'
+#[link_section = ".text"]
+pub extern "C" fn example() {}
diff --git a/tests/rustdoc/attributes-re-export-2021-edition.rs b/tests/rustdoc/attributes-re-export-2021-edition.rs
new file mode 100644
index 00000000000..04ee6c273dd
--- /dev/null
+++ b/tests/rustdoc/attributes-re-export-2021-edition.rs
@@ -0,0 +1,13 @@
+// Tests that attributes are correctly copied onto a re-exported item.
+//@ edition:2024
+#![crate_name = "re_export"]
+
+//@ has 're_export/fn.thingy2.html' '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]'
+pub use thingymod::thingy as thingy2;
+
+mod thingymod {
+    #[unsafe(no_mangle)]
+    pub fn thingy() {
+
+    }
+}
diff --git a/tests/rustdoc/attributes-re-export.rs b/tests/rustdoc/attributes-re-export.rs
index 458826ea8a3..820276f83c0 100644
--- a/tests/rustdoc/attributes-re-export.rs
+++ b/tests/rustdoc/attributes-re-export.rs
@@ -2,7 +2,7 @@
 //@ edition:2021
 #![crate_name = "re_export"]
 
-//@ has 're_export/fn.thingy2.html' '//pre[@class="rust item-decl"]' '#[no_mangle]'
+//@ has 're_export/fn.thingy2.html' '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]'
 pub use thingymod::thingy as thingy2;
 
 mod thingymod {
diff --git a/tests/rustdoc/attributes.rs b/tests/rustdoc/attributes.rs
index e34468a88b1..34487a89127 100644
--- a/tests/rustdoc/attributes.rs
+++ b/tests/rustdoc/attributes.rs
@@ -1,13 +1,18 @@
+//@ edition: 2024
 #![crate_name = "foo"]
 
-//@ has foo/fn.f.html '//pre[@class="rust item-decl"]' '#[no_mangle]'
-#[no_mangle]
+//@ has foo/fn.f.html '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]'
+#[unsafe(no_mangle)]
 pub extern "C" fn f() {}
 
-//@ has foo/fn.g.html '//pre[@class="rust item-decl"]' '#[export_name = "bar"]'
-#[export_name = "bar"]
+//@ has foo/fn.g.html '//pre[@class="rust item-decl"]' '#[unsafe(export_name = "bar")]'
+#[unsafe(export_name = "bar")]
 pub extern "C" fn g() {}
 
+//@ has foo/fn.example.html '//pre[@class="rust item-decl"]' '#[unsafe(link_section = ".text")]'
+#[unsafe(link_section = ".text")]
+pub extern "C" fn example() {}
+
 //@ has foo/struct.Repr.html '//pre[@class="rust item-decl"]' '#[repr(C, align(8))]'
 #[repr(C, align(8))]
 pub struct Repr;
diff --git a/tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs b/tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs
new file mode 100644
index 00000000000..7f8e346c8be
--- /dev/null
+++ b/tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs
@@ -0,0 +1,12 @@
+pub trait Assoc {
+    type Ty;
+}
+
+pub struct Foo(<Foo as crate::Assoc>::Ty);
+
+const _X: () = {
+    impl crate::Assoc for Foo {
+        type Ty = Bar;
+    }
+    pub struct Bar;
+};
diff --git a/tests/rustdoc/reexport/reexport-attrs.rs b/tests/rustdoc/reexport/reexport-attrs.rs
index 0ec645841f0..aec0a11c0c6 100644
--- a/tests/rustdoc/reexport/reexport-attrs.rs
+++ b/tests/rustdoc/reexport/reexport-attrs.rs
@@ -4,13 +4,13 @@
 
 extern crate reexports_attrs;
 
-//@ has 'foo/fn.f0.html' '//pre[@class="rust item-decl"]' '#[no_mangle]'
+//@ has 'foo/fn.f0.html' '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]'
 pub use reexports_attrs::f0;
 
-//@ has 'foo/fn.f1.html' '//pre[@class="rust item-decl"]' '#[link_section = ".here"]'
+//@ has 'foo/fn.f1.html' '//pre[@class="rust item-decl"]' '#[unsafe(link_section = ".here")]'
 pub use reexports_attrs::f1;
 
-//@ has 'foo/fn.f2.html' '//pre[@class="rust item-decl"]' '#[export_name = "f2export"]'
+//@ has 'foo/fn.f2.html' '//pre[@class="rust item-decl"]' '#[unsafe(export_name = "f2export")]'
 pub use reexports_attrs::f2;
 
 //@ has 'foo/enum.T0.html' '//pre[@class="rust item-decl"]' '#[repr(u8)]'
diff --git a/tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs b/tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs
new file mode 100644
index 00000000000..9a8893786f5
--- /dev/null
+++ b/tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs
@@ -0,0 +1,16 @@
+//@ compile-flags: -Z normalize-docs --document-private-items -Zunstable-options --show-type-layout
+//@ aux-build:wrap-unnamable-type.rs
+//@ build-aux-docs
+
+// regression test for https://github.com/rust-lang/rust/issues/143222
+// makes sure normalizing docs does not cause us to link to unnamable types
+// in cross-crate reexports.
+
+#![crate_name = "foo"]
+
+extern crate wrap_unnamable_type as helper;
+
+//@ has 'foo/struct.Foo.html'
+//@ !hasraw - 'struct.Bar.html'
+#[doc(inline)]
+pub use helper::Foo;
diff --git a/tests/ui/issues/issue-26095.rs b/tests/ui/associated-consts/constant-trait-item-reference-selection-26095.rs
index 34c617dc495..f0fe2db432b 100644
--- a/tests/ui/issues/issue-26095.rs
+++ b/tests/ui/associated-consts/constant-trait-item-reference-selection-26095.rs
@@ -1,8 +1,8 @@
+// https://github.com/rust-lang/rust/issues/26095
 //@ check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
-
 trait HasNumber<T> {
     const Number: usize;
 }
diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr
index 58a5b0b79c4..a507fa69760 100644
--- a/tests/ui/async-await/async-closures/def-path.stderr
+++ b/tests/ui/async-await/async-closures/def-path.stderr
@@ -5,11 +5,11 @@ LL |     let x = async || {};
    |                      -- the expected `async` closure body
 LL |
 LL |     let () = x();
-   |         ^^   --- this expression has type `{static main::{closure#0}::{closure#0}<?16t> upvar_tys=?15t resume_ty=ResumeTy yield_ty=() return_ty=() witness={main::{closure#0}::{closure#0}}}`
+   |         ^^   --- this expression has type `{static main::{closure#0}::{closure#0}<?15t> upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}`
    |         |
    |         expected `async` closure body, found `()`
    |
-   = note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?16t> upvar_tys=?15t resume_ty=ResumeTy yield_ty=() return_ty=() witness={main::{closure#0}::{closure#0}}}`
+   = note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?15t> upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}`
                          found unit type `()`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr
index d1f2d9a0753..d1c88101618 100644
--- a/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr
+++ b/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr
@@ -21,30 +21,6 @@ LL |     Box::new(async { new(|| async { f().await }).await })
    = help: consider pinning your async block and casting it to a trait object
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-auto-trait-6.rs:16:5
-   |
-LL |     Box::new(async { new(|| async { f().await }).await })
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
-              found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
-   = note: no two async blocks, even if identical, have the same type
-   = help: consider pinning your async block and casting it to a trait object
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-auto-trait-6.rs:16:5
-   |
-LL |     Box::new(async { new(|| async { f().await }).await })
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
-              found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
-   = note: no two async blocks, even if identical, have the same type
-   = help: consider pinning your async block and casting it to a trait object
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/issue-70818.rs b/tests/ui/async-await/issue-70818.rs
index bc181de8d92..c11332fe7d8 100644
--- a/tests/ui/async-await/issue-70818.rs
+++ b/tests/ui/async-await/issue-70818.rs
@@ -4,6 +4,7 @@ use std::future::Future;
 fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
     //~^ ERROR future cannot be sent between threads safely
     async { (ty, ty1) }
+    //~^ ERROR future cannot be sent between threads safely
 }
 
 fn main() {}
diff --git a/tests/ui/async-await/issue-70818.stderr b/tests/ui/async-await/issue-70818.stderr
index 8de6a825042..07fd20cdd77 100644
--- a/tests/ui/async-await/issue-70818.stderr
+++ b/tests/ui/async-await/issue-70818.stderr
@@ -1,4 +1,25 @@
 error: future cannot be sent between threads safely
+  --> $DIR/issue-70818.rs:6:5
+   |
+LL |     async { (ty, ty1) }
+   |     ^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
+   |
+note: captured value is not `Send`
+  --> $DIR/issue-70818.rs:6:18
+   |
+LL |     async { (ty, ty1) }
+   |                  ^^^ has type `U` which is not `Send`
+note: required by a bound in an opaque type
+  --> $DIR/issue-70818.rs:4:69
+   |
+LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
+   |                                                                     ^^^^
+help: consider restricting type parameter `U` with trait `Send`
+   |
+LL | fn foo<T: Send, U: std::marker::Send>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
+   |                  +++++++++++++++++++
+
+error: future cannot be sent between threads safely
   --> $DIR/issue-70818.rs:4:38
    |
 LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
@@ -14,5 +35,5 @@ help: consider restricting type parameter `U` with trait `Send`
 LL | fn foo<T: Send, U: std::marker::Send>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
    |                  +++++++++++++++++++
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/async-await/issue-86507.stderr b/tests/ui/async-await/issue-86507.stderr
index 6385a8c975e..c71801dcfc8 100644
--- a/tests/ui/async-await/issue-86507.stderr
+++ b/tests/ui/async-await/issue-86507.stderr
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
    |
 LL |                     let x = x;
    |                             ^ has type `&T` which is not `Send`, because `T` is not `Sync`
-   = note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:18:17: 18:27}>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
+   = note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:18:17: 18:27}>>` to `Pin<Box<dyn Future<Output = ()> + Send>>`
 help: consider further restricting type parameter `T` with trait `Sync`
    |
 LL |     fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
diff --git a/tests/ui/issues/issue-54044.rs b/tests/ui/attributes/cold-attribute-application-54044.rs
index 809ea7a87db..2e644b91c07 100644
--- a/tests/ui/issues/issue-54044.rs
+++ b/tests/ui/attributes/cold-attribute-application-54044.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/54044
 #![deny(unused_attributes)] //~ NOTE lint level is defined here
 
 #[cold]
diff --git a/tests/ui/issues/issue-54044.stderr b/tests/ui/attributes/cold-attribute-application-54044.stderr
index 8bd94a041d0..efdf5e0de52 100644
--- a/tests/ui/issues/issue-54044.stderr
+++ b/tests/ui/attributes/cold-attribute-application-54044.stderr
@@ -1,5 +1,5 @@
 error: attribute should be applied to a function definition
-  --> $DIR/issue-54044.rs:3:1
+  --> $DIR/cold-attribute-application-54044.rs:4:1
    |
 LL | #[cold]
    | ^^^^^^^
@@ -9,13 +9,13 @@ LL | struct Foo;
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 note: the lint level is defined here
-  --> $DIR/issue-54044.rs:1:9
+  --> $DIR/cold-attribute-application-54044.rs:2:9
    |
 LL | #![deny(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
 
 error: attribute should be applied to a function definition
-  --> $DIR/issue-54044.rs:9:5
+  --> $DIR/cold-attribute-application-54044.rs:10:5
    |
 LL |     #[cold]
    |     ^^^^^^^
diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs
index 2a8b7b41e58..0d5bf69d548 100644
--- a/tests/ui/attributes/malformed-attrs.rs
+++ b/tests/ui/attributes/malformed-attrs.rs
@@ -20,13 +20,9 @@
 #![feature(linkage)]
 #![feature(cfi_encoding, extern_types)]
 #![feature(patchable_function_entry)]
-#![feature(omit_gdb_pretty_printer_section)]
 #![feature(fundamental)]
 
 
-#![omit_gdb_pretty_printer_section = 1]
-//~^ ERROR malformed `omit_gdb_pretty_printer_section` attribute input
-
 #![windows_subsystem]
 //~^ ERROR malformed
 
diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr
index 814a1e5f691..1b51075b4e8 100644
--- a/tests/ui/attributes/malformed-attrs.stderr
+++ b/tests/ui/attributes/malformed-attrs.stderr
@@ -1,5 +1,5 @@
 error[E0539]: malformed `cfg` attribute input
-  --> $DIR/malformed-attrs.rs:103:1
+  --> $DIR/malformed-attrs.rs:99:1
    |
 LL | #[cfg]
    | ^^^^^^
@@ -8,7 +8,7 @@ LL | #[cfg]
    | help: must be of the form: `#[cfg(predicate)]`
 
 error: malformed `cfg_attr` attribute input
-  --> $DIR/malformed-attrs.rs:105:1
+  --> $DIR/malformed-attrs.rs:101:1
    |
 LL | #[cfg_attr]
    | ^^^^^^^^^^^
@@ -20,49 +20,49 @@ LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
    |           ++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0463]: can't find crate for `wloop`
-  --> $DIR/malformed-attrs.rs:212:1
+  --> $DIR/malformed-attrs.rs:208:1
    |
 LL | extern crate wloop;
    | ^^^^^^^^^^^^^^^^^^^ can't find crate
 
 error: malformed `windows_subsystem` attribute input
-  --> $DIR/malformed-attrs.rs:30:1
+  --> $DIR/malformed-attrs.rs:26:1
    |
 LL | #![windows_subsystem]
    | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![windows_subsystem = "windows|console"]`
 
 error: malformed `crate_name` attribute input
-  --> $DIR/malformed-attrs.rs:75:1
+  --> $DIR/malformed-attrs.rs:71:1
    |
 LL | #[crate_name]
    | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]`
 
 error: malformed `no_sanitize` attribute input
-  --> $DIR/malformed-attrs.rs:93:1
+  --> $DIR/malformed-attrs.rs:89:1
    |
 LL | #[no_sanitize]
    | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]`
 
 error: malformed `instruction_set` attribute input
-  --> $DIR/malformed-attrs.rs:107:1
+  --> $DIR/malformed-attrs.rs:103:1
    |
 LL | #[instruction_set]
    | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]`
 
 error: malformed `patchable_function_entry` attribute input
-  --> $DIR/malformed-attrs.rs:109:1
+  --> $DIR/malformed-attrs.rs:105:1
    |
 LL | #[patchable_function_entry]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
 
 error: malformed `coroutine` attribute input
-  --> $DIR/malformed-attrs.rs:112:5
+  --> $DIR/malformed-attrs.rs:108:5
    |
 LL |     #[coroutine = 63] || {}
    |     ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]`
 
 error: malformed `must_not_suspend` attribute input
-  --> $DIR/malformed-attrs.rs:133:1
+  --> $DIR/malformed-attrs.rs:129:1
    |
 LL | #[must_not_suspend()]
    | ^^^^^^^^^^^^^^^^^^^^^
@@ -77,67 +77,67 @@ LL + #[must_not_suspend]
    |
 
 error: malformed `cfi_encoding` attribute input
-  --> $DIR/malformed-attrs.rs:135:1
+  --> $DIR/malformed-attrs.rs:131:1
    |
 LL | #[cfi_encoding]
    | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]`
 
 error: malformed `linkage` attribute input
-  --> $DIR/malformed-attrs.rs:174:5
+  --> $DIR/malformed-attrs.rs:170:5
    |
 LL |     #[linkage]
    |     ^^^^^^^^^^ help: must be of the form: `#[linkage = "external|internal|..."]`
 
 error: malformed `allow` attribute input
-  --> $DIR/malformed-attrs.rs:179:1
+  --> $DIR/malformed-attrs.rs:175:1
    |
 LL | #[allow]
    | ^^^^^^^^ help: must be of the form: `#[allow(lint1, lint2, ..., /*opt*/ reason = "...")]`
 
 error: malformed `expect` attribute input
-  --> $DIR/malformed-attrs.rs:181:1
+  --> $DIR/malformed-attrs.rs:177:1
    |
 LL | #[expect]
    | ^^^^^^^^^ help: must be of the form: `#[expect(lint1, lint2, ..., /*opt*/ reason = "...")]`
 
 error: malformed `warn` attribute input
-  --> $DIR/malformed-attrs.rs:183:1
+  --> $DIR/malformed-attrs.rs:179:1
    |
 LL | #[warn]
    | ^^^^^^^ help: must be of the form: `#[warn(lint1, lint2, ..., /*opt*/ reason = "...")]`
 
 error: malformed `deny` attribute input
-  --> $DIR/malformed-attrs.rs:185:1
+  --> $DIR/malformed-attrs.rs:181:1
    |
 LL | #[deny]
    | ^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]`
 
 error: malformed `forbid` attribute input
-  --> $DIR/malformed-attrs.rs:187:1
+  --> $DIR/malformed-attrs.rs:183:1
    |
 LL | #[forbid]
    | ^^^^^^^^^ help: must be of the form: `#[forbid(lint1, lint2, ..., /*opt*/ reason = "...")]`
 
 error: malformed `debugger_visualizer` attribute input
-  --> $DIR/malformed-attrs.rs:189:1
+  --> $DIR/malformed-attrs.rs:185:1
    |
 LL | #[debugger_visualizer]
    | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]`
 
 error: malformed `thread_local` attribute input
-  --> $DIR/malformed-attrs.rs:204:1
+  --> $DIR/malformed-attrs.rs:200:1
    |
 LL | #[thread_local()]
    | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]`
 
 error: malformed `no_link` attribute input
-  --> $DIR/malformed-attrs.rs:208:1
+  --> $DIR/malformed-attrs.rs:204:1
    |
 LL | #[no_link()]
    | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]`
 
 error: malformed `macro_export` attribute input
-  --> $DIR/malformed-attrs.rs:215:1
+  --> $DIR/malformed-attrs.rs:211:1
    |
 LL | #[macro_export = 18]
    | ^^^^^^^^^^^^^^^^^^^^
@@ -152,31 +152,31 @@ LL + #[macro_export]
    |
 
 error: malformed `allow_internal_unsafe` attribute input
-  --> $DIR/malformed-attrs.rs:217:1
+  --> $DIR/malformed-attrs.rs:213:1
    |
 LL | #[allow_internal_unsafe = 1]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]`
 
 error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type
-  --> $DIR/malformed-attrs.rs:100:1
+  --> $DIR/malformed-attrs.rs:96:1
    |
 LL | #[proc_macro = 18]
    | ^^^^^^^^^^^^^^^^^^
 
 error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type
-  --> $DIR/malformed-attrs.rs:117:1
+  --> $DIR/malformed-attrs.rs:113:1
    |
 LL | #[proc_macro_attribute = 19]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type
-  --> $DIR/malformed-attrs.rs:124:1
+  --> $DIR/malformed-attrs.rs:120:1
    |
 LL | #[proc_macro_derive]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint
-  --> $DIR/malformed-attrs.rs:217:1
+  --> $DIR/malformed-attrs.rs:213:1
    |
 LL | #[allow_internal_unsafe = 1]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -185,7 +185,7 @@ LL | #[allow_internal_unsafe = 1]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]`
-  --> $DIR/malformed-attrs.rs:44:1
+  --> $DIR/malformed-attrs.rs:40:1
    |
 LL | #[doc]
    | ^^^^^^
@@ -195,7 +195,7 @@ LL | #[doc]
    = note: `#[deny(ill_formed_attribute_input)]` on by default
 
 error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]`
-  --> $DIR/malformed-attrs.rs:77:1
+  --> $DIR/malformed-attrs.rs:73:1
    |
 LL | #[doc]
    | ^^^^^^
@@ -204,7 +204,7 @@ LL | #[doc]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
 error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/malformed-attrs.rs:84:1
+  --> $DIR/malformed-attrs.rs:80:1
    |
 LL | #[link]
    | ^^^^^^^
@@ -213,7 +213,7 @@ LL | #[link]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
 error: invalid argument
-  --> $DIR/malformed-attrs.rs:189:1
+  --> $DIR/malformed-attrs.rs:185:1
    |
 LL | #[debugger_visualizer]
    | ^^^^^^^^^^^^^^^^^^^^^^
@@ -222,35 +222,26 @@ LL | #[debugger_visualizer]
    = note: OR
    = note: expected: `gdb_script_file = "..."`
 
-error[E0565]: malformed `omit_gdb_pretty_printer_section` attribute input
-  --> $DIR/malformed-attrs.rs:27:1
-   |
-LL | #![omit_gdb_pretty_printer_section = 1]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^
-   | |                                  |
-   | |                                  didn't expect any arguments here
-   | help: must be of the form: `#[omit_gdb_pretty_printer_section]`
-
 error[E0539]: malformed `export_name` attribute input
-  --> $DIR/malformed-attrs.rs:33:1
+  --> $DIR/malformed-attrs.rs:29:1
    |
 LL | #[unsafe(export_name)]
    | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]`
 
 error: `rustc_allow_const_fn_unstable` expects a list of feature names
-  --> $DIR/malformed-attrs.rs:35:1
+  --> $DIR/malformed-attrs.rs:31:1
    |
 LL | #[rustc_allow_const_fn_unstable]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `allow_internal_unstable` expects a list of feature names
-  --> $DIR/malformed-attrs.rs:38:1
+  --> $DIR/malformed-attrs.rs:34:1
    |
 LL | #[allow_internal_unstable]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0539]: malformed `rustc_confusables` attribute input
-  --> $DIR/malformed-attrs.rs:40:1
+  --> $DIR/malformed-attrs.rs:36:1
    |
 LL | #[rustc_confusables]
    | ^^^^^^^^^^^^^^^^^^^^
@@ -259,7 +250,7 @@ LL | #[rustc_confusables]
    | help: must be of the form: `#[rustc_confusables("name1", "name2", ...)]`
 
 error[E0539]: malformed `deprecated` attribute input
-  --> $DIR/malformed-attrs.rs:42:1
+  --> $DIR/malformed-attrs.rs:38:1
    |
 LL | #[deprecated = 5]
    | ^^^^^^^^^^^^^^^-^
@@ -279,13 +270,13 @@ LL + #[deprecated]
    |
 
 error[E0539]: malformed `rustc_macro_transparency` attribute input
-  --> $DIR/malformed-attrs.rs:47:1
+  --> $DIR/malformed-attrs.rs:43:1
    |
 LL | #[rustc_macro_transparency]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_macro_transparency = "transparent|semitransparent|opaque"]`
 
 error[E0539]: malformed `repr` attribute input
-  --> $DIR/malformed-attrs.rs:49:1
+  --> $DIR/malformed-attrs.rs:45:1
    |
 LL | #[repr]
    | ^^^^^^^
@@ -294,7 +285,7 @@ LL | #[repr]
    | help: must be of the form: `#[repr(C | Rust | align(...) | packed(...) | <integer type> | transparent)]`
 
 error[E0565]: malformed `rustc_as_ptr` attribute input
-  --> $DIR/malformed-attrs.rs:52:1
+  --> $DIR/malformed-attrs.rs:48:1
    |
 LL | #[rustc_as_ptr = 5]
    | ^^^^^^^^^^^^^^^---^
@@ -303,7 +294,7 @@ LL | #[rustc_as_ptr = 5]
    | help: must be of the form: `#[rustc_as_ptr]`
 
 error[E0539]: malformed `rustc_align` attribute input
-  --> $DIR/malformed-attrs.rs:57:1
+  --> $DIR/malformed-attrs.rs:53:1
    |
 LL | #[rustc_align]
    | ^^^^^^^^^^^^^^
@@ -312,7 +303,7 @@ LL | #[rustc_align]
    | help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
 
 error[E0539]: malformed `optimize` attribute input
-  --> $DIR/malformed-attrs.rs:59:1
+  --> $DIR/malformed-attrs.rs:55:1
    |
 LL | #[optimize]
    | ^^^^^^^^^^^
@@ -321,7 +312,7 @@ LL | #[optimize]
    | help: must be of the form: `#[optimize(size|speed|none)]`
 
 error[E0565]: malformed `cold` attribute input
-  --> $DIR/malformed-attrs.rs:61:1
+  --> $DIR/malformed-attrs.rs:57:1
    |
 LL | #[cold = 1]
    | ^^^^^^^---^
@@ -330,13 +321,13 @@ LL | #[cold = 1]
    | help: must be of the form: `#[cold]`
 
 error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]`
-  --> $DIR/malformed-attrs.rs:63:1
+  --> $DIR/malformed-attrs.rs:59:1
    |
 LL | #[must_use()]
    | ^^^^^^^^^^^^^
 
 error[E0565]: malformed `no_mangle` attribute input
-  --> $DIR/malformed-attrs.rs:65:1
+  --> $DIR/malformed-attrs.rs:61:1
    |
 LL | #[no_mangle = 1]
    | ^^^^^^^^^^^^---^
@@ -345,7 +336,7 @@ LL | #[no_mangle = 1]
    | help: must be of the form: `#[no_mangle]`
 
 error[E0565]: malformed `naked` attribute input
-  --> $DIR/malformed-attrs.rs:67:1
+  --> $DIR/malformed-attrs.rs:63:1
    |
 LL | #[unsafe(naked())]
    | ^^^^^^^^^^^^^^--^^
@@ -354,7 +345,7 @@ LL | #[unsafe(naked())]
    | help: must be of the form: `#[naked]`
 
 error[E0565]: malformed `track_caller` attribute input
-  --> $DIR/malformed-attrs.rs:69:1
+  --> $DIR/malformed-attrs.rs:65:1
    |
 LL | #[track_caller()]
    | ^^^^^^^^^^^^^^--^
@@ -363,13 +354,13 @@ LL | #[track_caller()]
    | help: must be of the form: `#[track_caller]`
 
 error[E0539]: malformed `export_name` attribute input
-  --> $DIR/malformed-attrs.rs:71:1
+  --> $DIR/malformed-attrs.rs:67:1
    |
 LL | #[export_name()]
    | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]`
 
 error[E0805]: malformed `used` attribute input
-  --> $DIR/malformed-attrs.rs:73:1
+  --> $DIR/malformed-attrs.rs:69:1
    |
 LL | #[used()]
    | ^^^^^^--^
@@ -385,7 +376,7 @@ LL + #[used]
    |
 
 error[E0539]: malformed `target_feature` attribute input
-  --> $DIR/malformed-attrs.rs:80:1
+  --> $DIR/malformed-attrs.rs:76:1
    |
 LL | #[target_feature]
    | ^^^^^^^^^^^^^^^^^
@@ -394,7 +385,7 @@ LL | #[target_feature]
    | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`
 
 error[E0565]: malformed `export_stable` attribute input
-  --> $DIR/malformed-attrs.rs:82:1
+  --> $DIR/malformed-attrs.rs:78:1
    |
 LL | #[export_stable = 1]
    | ^^^^^^^^^^^^^^^^---^
@@ -403,19 +394,19 @@ LL | #[export_stable = 1]
    | help: must be of the form: `#[export_stable]`
 
 error[E0539]: malformed `link_name` attribute input
-  --> $DIR/malformed-attrs.rs:87:1
+  --> $DIR/malformed-attrs.rs:83:1
    |
 LL | #[link_name]
    | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]`
 
 error[E0539]: malformed `link_section` attribute input
-  --> $DIR/malformed-attrs.rs:89:1
+  --> $DIR/malformed-attrs.rs:85:1
    |
 LL | #[link_section]
    | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]`
 
 error[E0539]: malformed `coverage` attribute input
-  --> $DIR/malformed-attrs.rs:91:1
+  --> $DIR/malformed-attrs.rs:87:1
    |
 LL | #[coverage]
    | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument
@@ -428,7 +419,7 @@ LL | #[coverage(on)]
    |           ++++
 
 error[E0565]: malformed `no_implicit_prelude` attribute input
-  --> $DIR/malformed-attrs.rs:98:1
+  --> $DIR/malformed-attrs.rs:94:1
    |
 LL | #[no_implicit_prelude = 23]
    | ^^^^^^^^^^^^^^^^^^^^^^----^
@@ -437,7 +428,7 @@ LL | #[no_implicit_prelude = 23]
    | help: must be of the form: `#[no_implicit_prelude]`
 
 error[E0565]: malformed `proc_macro` attribute input
-  --> $DIR/malformed-attrs.rs:100:1
+  --> $DIR/malformed-attrs.rs:96:1
    |
 LL | #[proc_macro = 18]
    | ^^^^^^^^^^^^^----^
@@ -446,7 +437,7 @@ LL | #[proc_macro = 18]
    | help: must be of the form: `#[proc_macro]`
 
 error[E0565]: malformed `proc_macro_attribute` attribute input
-  --> $DIR/malformed-attrs.rs:117:1
+  --> $DIR/malformed-attrs.rs:113:1
    |
 LL | #[proc_macro_attribute = 19]
    | ^^^^^^^^^^^^^^^^^^^^^^^----^
@@ -455,7 +446,7 @@ LL | #[proc_macro_attribute = 19]
    | help: must be of the form: `#[proc_macro_attribute]`
 
 error[E0539]: malformed `must_use` attribute input
-  --> $DIR/malformed-attrs.rs:120:1
+  --> $DIR/malformed-attrs.rs:116:1
    |
 LL | #[must_use = 1]
    | ^^^^^^^^^^^^^-^
@@ -472,7 +463,7 @@ LL + #[must_use]
    |
 
 error[E0539]: malformed `proc_macro_derive` attribute input
-  --> $DIR/malformed-attrs.rs:124:1
+  --> $DIR/malformed-attrs.rs:120:1
    |
 LL | #[proc_macro_derive]
    | ^^^^^^^^^^^^^^^^^^^^
@@ -481,7 +472,7 @@ LL | #[proc_macro_derive]
    | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
 
 error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input
-  --> $DIR/malformed-attrs.rs:129:1
+  --> $DIR/malformed-attrs.rs:125:1
    |
 LL | #[rustc_layout_scalar_valid_range_start]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -490,7 +481,7 @@ LL | #[rustc_layout_scalar_valid_range_start]
    | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]`
 
 error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input
-  --> $DIR/malformed-attrs.rs:131:1
+  --> $DIR/malformed-attrs.rs:127:1
    |
 LL | #[rustc_layout_scalar_valid_range_end]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -499,7 +490,7 @@ LL | #[rustc_layout_scalar_valid_range_end]
    | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`
 
 error[E0565]: malformed `marker` attribute input
-  --> $DIR/malformed-attrs.rs:156:1
+  --> $DIR/malformed-attrs.rs:152:1
    |
 LL | #[marker = 3]
    | ^^^^^^^^^---^
@@ -508,7 +499,7 @@ LL | #[marker = 3]
    | help: must be of the form: `#[marker]`
 
 error[E0565]: malformed `fundamental` attribute input
-  --> $DIR/malformed-attrs.rs:158:1
+  --> $DIR/malformed-attrs.rs:154:1
    |
 LL | #[fundamental()]
    | ^^^^^^^^^^^^^--^
@@ -517,7 +508,7 @@ LL | #[fundamental()]
    | help: must be of the form: `#[fundamental]`
 
 error[E0565]: malformed `ffi_pure` attribute input
-  --> $DIR/malformed-attrs.rs:166:5
+  --> $DIR/malformed-attrs.rs:162:5
    |
 LL |     #[unsafe(ffi_pure = 1)]
    |     ^^^^^^^^^^^^^^^^^^---^^
@@ -526,7 +517,7 @@ LL |     #[unsafe(ffi_pure = 1)]
    |     help: must be of the form: `#[ffi_pure]`
 
 error[E0539]: malformed `link_ordinal` attribute input
-  --> $DIR/malformed-attrs.rs:168:5
+  --> $DIR/malformed-attrs.rs:164:5
    |
 LL |     #[link_ordinal]
    |     ^^^^^^^^^^^^^^^
@@ -535,7 +526,7 @@ LL |     #[link_ordinal]
    |     help: must be of the form: `#[link_ordinal(ordinal)]`
 
 error[E0565]: malformed `ffi_const` attribute input
-  --> $DIR/malformed-attrs.rs:172:5
+  --> $DIR/malformed-attrs.rs:168:5
    |
 LL |     #[unsafe(ffi_const = 1)]
    |     ^^^^^^^^^^^^^^^^^^^---^^
@@ -544,7 +535,7 @@ LL |     #[unsafe(ffi_const = 1)]
    |     help: must be of the form: `#[ffi_const]`
 
 error[E0565]: malformed `automatically_derived` attribute input
-  --> $DIR/malformed-attrs.rs:192:1
+  --> $DIR/malformed-attrs.rs:188:1
    |
 LL | #[automatically_derived = 18]
    | ^^^^^^^^^^^^^^^^^^^^^^^^----^
@@ -553,7 +544,7 @@ LL | #[automatically_derived = 18]
    | help: must be of the form: `#[automatically_derived]`
 
 error[E0565]: malformed `non_exhaustive` attribute input
-  --> $DIR/malformed-attrs.rs:198:1
+  --> $DIR/malformed-attrs.rs:194:1
    |
 LL | #[non_exhaustive = 1]
    | ^^^^^^^^^^^^^^^^^---^
@@ -562,13 +553,13 @@ LL | #[non_exhaustive = 1]
    | help: must be of the form: `#[non_exhaustive]`
 
 error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]`
-  --> $DIR/malformed-attrs.rs:210:1
+  --> $DIR/malformed-attrs.rs:206:1
    |
 LL | #[macro_use = 1]
    | ^^^^^^^^^^^^^^^^
 
 error[E0565]: malformed `type_const` attribute input
-  --> $DIR/malformed-attrs.rs:144:5
+  --> $DIR/malformed-attrs.rs:140:5
    |
 LL |     #[type_const = 1]
    |     ^^^^^^^^^^^^^---^
@@ -577,7 +568,7 @@ LL |     #[type_const = 1]
    |     help: must be of the form: `#[type_const]`
 
 error: attribute should be applied to `const fn`
-  --> $DIR/malformed-attrs.rs:35:1
+  --> $DIR/malformed-attrs.rs:31:1
    |
 LL |   #[rustc_allow_const_fn_unstable]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -589,19 +580,19 @@ LL | | }
    | |_- not a `const fn`
 
 error: `#[repr(align(...))]` is not supported on function items
-  --> $DIR/malformed-attrs.rs:49:1
+  --> $DIR/malformed-attrs.rs:45:1
    |
 LL | #[repr]
    | ^^^^^^^
    |
 help: use `#[rustc_align(...)]` instead
-  --> $DIR/malformed-attrs.rs:49:1
+  --> $DIR/malformed-attrs.rs:45:1
    |
 LL | #[repr]
    | ^^^^^^^
 
 warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
-  --> $DIR/malformed-attrs.rs:150:1
+  --> $DIR/malformed-attrs.rs:146:1
    |
 LL | #[diagnostic::do_not_recommend()]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -609,7 +600,7 @@ LL | #[diagnostic::do_not_recommend()]
    = note: `#[warn(malformed_diagnostic_attributes)]` on by default
 
 warning: missing options for `on_unimplemented` attribute
-  --> $DIR/malformed-attrs.rs:139:1
+  --> $DIR/malformed-attrs.rs:135:1
    |
 LL | #[diagnostic::on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -617,7 +608,7 @@ LL | #[diagnostic::on_unimplemented]
    = help: at least one of the `message`, `note` and `label` options are expected
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/malformed-attrs.rs:141:1
+  --> $DIR/malformed-attrs.rs:137:1
    |
 LL | #[diagnostic::on_unimplemented = 1]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -625,7 +616,7 @@ LL | #[diagnostic::on_unimplemented = 1]
    = help: only `message`, `note` and `label` are allowed as options
 
 error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]`
-  --> $DIR/malformed-attrs.rs:54:1
+  --> $DIR/malformed-attrs.rs:50:1
    |
 LL | #[inline = 5]
    | ^^^^^^^^^^^^^
@@ -634,7 +625,7 @@ LL | #[inline = 5]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
-  --> $DIR/malformed-attrs.rs:95:1
+  --> $DIR/malformed-attrs.rs:91:1
    |
 LL | #[ignore()]
    | ^^^^^^^^^^^
@@ -643,7 +634,7 @@ LL | #[ignore()]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
-  --> $DIR/malformed-attrs.rs:224:1
+  --> $DIR/malformed-attrs.rs:220:1
    |
 LL | #[ignore = 1]
    | ^^^^^^^^^^^^^
@@ -652,7 +643,7 @@ LL | #[ignore = 1]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
 error[E0308]: mismatched types
-  --> $DIR/malformed-attrs.rs:112:23
+  --> $DIR/malformed-attrs.rs:108:23
    |
 LL | fn test() {
    |          - help: a return type might be missing here: `-> _`
@@ -660,9 +651,9 @@ LL |     #[coroutine = 63] || {}
    |                       ^^^^^ expected `()`, found coroutine
    |
    = note: expected unit type `()`
-              found coroutine `{coroutine@$DIR/malformed-attrs.rs:112:23: 112:25}`
+              found coroutine `{coroutine@$DIR/malformed-attrs.rs:108:23: 108:25}`
 
-error: aborting due to 75 previous errors; 3 warnings emitted
+error: aborting due to 74 previous errors; 3 warnings emitted
 
 Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/issues/issue-36786-resolve-call.rs b/tests/ui/autoref-autoderef/autoderef-vec-box-fn-36786.rs
index de7b0e18d52..e16929bf48a 100644
--- a/tests/ui/issues/issue-36786-resolve-call.rs
+++ b/tests/ui/autoref-autoderef/autoderef-vec-box-fn-36786.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/36786
 //@ run-pass
 // Ensure that types that rely on obligations are autoderefed
 // correctly
diff --git a/tests/ui/issues/issue-13264.rs b/tests/ui/autoref-autoderef/deref-chain-method-calls-13264.rs
index bf4ec388c4f..f471c1c7eef 100644
--- a/tests/ui/issues/issue-13264.rs
+++ b/tests/ui/autoref-autoderef/deref-chain-method-calls-13264.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13264
+
 //@ run-pass
 #![allow(non_camel_case_types)]
 #![allow(non_snake_case)]
diff --git a/tests/ui/issues/issue-11709.rs b/tests/ui/block-result/blocks-without-results-11709.rs
index 8a11074eca8..97ea6f9e19e 100644
--- a/tests/ui/issues/issue-11709.rs
+++ b/tests/ui/block-result/blocks-without-results-11709.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/11709
+
 //@ run-pass
 #![allow(dead_code)]
 
diff --git a/tests/ui/issues/issue-46471-1.rs b/tests/ui/borrowck/borrow-checker-lifetime-error-46471.rs
index aa161d40f70..020b02aa34d 100644
--- a/tests/ui/issues/issue-46471-1.rs
+++ b/tests/ui/borrowck/borrow-checker-lifetime-error-46471.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/46471
 fn main() {
     let y = {
         let mut z = 0;
diff --git a/tests/ui/issues/issue-46471-1.stderr b/tests/ui/borrowck/borrow-checker-lifetime-error-46471.stderr
index d4517223982..c90da551620 100644
--- a/tests/ui/issues/issue-46471-1.stderr
+++ b/tests/ui/borrowck/borrow-checker-lifetime-error-46471.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `z` does not live long enough
-  --> $DIR/issue-46471-1.rs:4:9
+  --> $DIR/borrow-checker-lifetime-error-46471.rs:5:9
    |
 LL |         let mut z = 0;
    |             ----- binding `z` declared here
diff --git a/tests/ui/issues/issue-12041.rs b/tests/ui/borrowck/moved-value-in-thread-loop-12041.rs
index 091e8fe8b2a..98f9cdbdef7 100644
--- a/tests/ui/issues/issue-12041.rs
+++ b/tests/ui/borrowck/moved-value-in-thread-loop-12041.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12041
+
 use std::sync::mpsc::channel;
 use std::thread;
 
diff --git a/tests/ui/issues/issue-12041.stderr b/tests/ui/borrowck/moved-value-in-thread-loop-12041.stderr
index f2c10b83383..627dd193dad 100644
--- a/tests/ui/issues/issue-12041.stderr
+++ b/tests/ui/borrowck/moved-value-in-thread-loop-12041.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `tx`
-  --> $DIR/issue-12041.rs:8:22
+  --> $DIR/moved-value-in-thread-loop-12041.rs:10:22
    |
 LL |             let tx = tx;
    |                      ^^ value moved here, in previous iteration of loop
diff --git a/tests/ui/issues/issue-12033.rs b/tests/ui/borrowck/refcell-borrow-comparison-12033.rs
index 0bf6490bafe..de22cedd5b9 100644
--- a/tests/ui/issues/issue-12033.rs
+++ b/tests/ui/borrowck/refcell-borrow-comparison-12033.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12033
+
 //@ run-pass
 use std::cell::RefCell;
 
diff --git a/tests/ui/issues/issue-11869.rs b/tests/ui/borrowck/string-borrowing-pattern-matching-11869.rs
index dd752227bbe..fe3d1bf6e8a 100644
--- a/tests/ui/issues/issue-11869.rs
+++ b/tests/ui/borrowck/string-borrowing-pattern-matching-11869.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/11869
 //@ check-pass
 #![allow(dead_code)]
 
diff --git a/tests/ui/borrowck/string-literal-match-patterns-11869.rs b/tests/ui/borrowck/string-literal-match-patterns-11869.rs
new file mode 100644
index 00000000000..4c159e457cf
--- /dev/null
+++ b/tests/ui/borrowck/string-literal-match-patterns-11869.rs
@@ -0,0 +1,18 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/11869
+
+//@ check-pass
+#![allow(dead_code)]
+
+struct A {
+    a: String
+}
+
+fn borrow<'a>(binding: &'a A) -> &'a str {
+    match &*binding.a {
+        "in" => "in_",
+        "ref" => "ref_",
+        ident => ident
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/issues/issue-9918.rs b/tests/ui/cast/u8-to-char-cast-9918.rs
index 017e833aefb..2b8be1f0fc9 100644
--- a/tests/ui/issues/issue-9918.rs
+++ b/tests/ui/cast/u8-to-char-cast-9918.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/9918
 //@ run-pass
 
 pub fn main() {
diff --git a/tests/ui/cfg/both-true-false.stderr b/tests/ui/cfg/both-true-false.stderr
index 1526cc2b707..1a7c509aec0 100644
--- a/tests/ui/cfg/both-true-false.stderr
+++ b/tests/ui/cfg/both-true-false.stderr
@@ -3,6 +3,22 @@ error[E0425]: cannot find function `foo` in this scope
    |
 LL |     foo();
    |     ^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/both-true-false.rs:6:4
+   |
+LL | #[cfg(false)]
+   |       ----- the item is gated here
+LL | #[cfg(true)]
+LL | fn foo() {}
+   |    ^^^
+note: found an item that was configured out
+  --> $DIR/both-true-false.rs:10:4
+   |
+LL | #[cfg(false)]
+   |       ----- the item is gated here
+LL | fn foo() {}
+   |    ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/cfg/cfg-version/syntax.stderr b/tests/ui/cfg/cfg-version/syntax.stderr
index 188f6d7aa5d..34ddfff3e8e 100644
--- a/tests/ui/cfg/cfg-version/syntax.stderr
+++ b/tests/ui/cfg/cfg-version/syntax.stderr
@@ -128,60 +128,150 @@ error[E0425]: cannot find function `key_value_form` in this scope
    |
 LL |     key_value_form();
    |     ^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:32:4
+   |
+LL | #[cfg(version = "1.43")]
+   |       ---------------- the item is gated behind the `1.43` feature
+LL |
+LL | fn key_value_form() {}
+   |    ^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `not_numbers_or_periods` in this scope
   --> $DIR/syntax.rs:143:5
    |
 LL |     not_numbers_or_periods();
    |     ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:53:4
+   |
+LL | #[cfg(version("foo"))]
+   |              ------- the item is gated here
+LL |
+LL | fn not_numbers_or_periods() {}
+   |    ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `complex_semver_with_metadata` in this scope
   --> $DIR/syntax.rs:144:5
    |
 LL |     complex_semver_with_metadata();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:57:4
+   |
+LL | #[cfg(version("1.20.0-stable"))]
+   |              ----------------- the item is gated here
+LL |
+LL | fn complex_semver_with_metadata() {}
+   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `invalid_major_only` in this scope
   --> $DIR/syntax.rs:145:5
    |
 LL |     invalid_major_only();
    |     ^^^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:80:4
+   |
+LL | #[cfg(version("1"))]
+   |              ----- the item is gated here
+LL |
+LL | fn invalid_major_only() {}
+   |    ^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `invalid_major_only_zero` in this scope
   --> $DIR/syntax.rs:146:5
    |
 LL |     invalid_major_only_zero();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:84:4
+   |
+LL | #[cfg(version("0"))]
+   |              ----- the item is gated here
+LL |
+LL | fn invalid_major_only_zero() {}
+   |    ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `invalid_major_only_negative` in this scope
   --> $DIR/syntax.rs:147:5
    |
 LL |     invalid_major_only_negative();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:97:4
+   |
+LL | #[cfg(version("-1"))]
+   |              ------ the item is gated here
+LL |
+LL | fn invalid_major_only_negative() {}
+   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `exceed_u16_major` in this scope
   --> $DIR/syntax.rs:148:5
    |
 LL |     exceed_u16_major();
    |     ^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:103:4
+   |
+LL | #[cfg(version("65536"))]
+   |              --------- the item is gated here
+LL |
+LL | fn exceed_u16_major() {}
+   |    ^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `exceed_u16_minor` in this scope
   --> $DIR/syntax.rs:149:5
    |
 LL |     exceed_u16_minor();
    |     ^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:107:4
+   |
+LL | #[cfg(version("1.65536.0"))]
+   |              ------------- the item is gated here
+LL |
+LL | fn exceed_u16_minor() {}
+   |    ^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `exceed_u16_patch` in this scope
   --> $DIR/syntax.rs:150:5
    |
 LL |     exceed_u16_patch();
    |     ^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:111:4
+   |
+LL | #[cfg(version("1.0.65536"))]
+   |              ------------- the item is gated here
+LL |
+LL | fn exceed_u16_patch() {}
+   |    ^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `exceed_u16_mixed` in this scope
   --> $DIR/syntax.rs:151:5
    |
 LL |     exceed_u16_mixed();
    |     ^^^^^^^^^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/syntax.rs:115:4
+   |
+LL | #[cfg(version("65536.0.65536"))]
+   |              ----------------- the item is gated here
+LL |
+LL | fn exceed_u16_mixed() {}
+   |    ^^^^^^^^^^^^^^^^
 
 error: aborting due to 14 previous errors; 14 warnings emitted
 
diff --git a/tests/ui/cfg/cmdline-false.stderr b/tests/ui/cfg/cmdline-false.stderr
index 5f57c754c40..3d486803821 100644
--- a/tests/ui/cfg/cmdline-false.stderr
+++ b/tests/ui/cfg/cmdline-false.stderr
@@ -3,6 +3,14 @@ error[E0425]: cannot find function `foo` in this scope
    |
 LL |     foo();
    |     ^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/cmdline-false.rs:5:4
+   |
+LL | #[cfg(false)]
+   |       ----- the item is gated here
+LL | fn foo() {}
+   |    ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/cfg/diagnostics-cross-crate.rs b/tests/ui/cfg/diagnostics-cross-crate.rs
index 00ac7e2fd08..f959332c817 100644
--- a/tests/ui/cfg/diagnostics-cross-crate.rs
+++ b/tests/ui/cfg/diagnostics-cross-crate.rs
@@ -11,24 +11,20 @@ fn main() {
     cfged_out::inner::uwu(); //~ ERROR cannot find function
     //~^ NOTE found an item that was configured out
     //~| NOTE not found in `cfged_out::inner`
-    //~| NOTE the item is gated here
 
     // The module isn't found - we would like to get a diagnostic, but currently don't due to
     // the awkward way the resolver diagnostics are currently implemented.
     cfged_out::inner::doesnt_exist::hello(); //~ ERROR failed to resolve
     //~^ NOTE could not find `doesnt_exist` in `inner`
     //~| NOTE found an item that was configured out
-    //~| NOTE the item is gated here
 
     // It should find the one in the right module, not the wrong one.
     cfged_out::inner::right::meow(); //~ ERROR cannot find function
     //~^ NOTE found an item that was configured out
     //~| NOTE not found in `cfged_out::inner::right
-    //~| NOTE the item is gated behind the `what-a-cool-feature` feature
 
     // Exists in the crate root - diagnostic.
     cfged_out::vanished(); //~ ERROR cannot find function
     //~^ NOTE found an item that was configured out
     //~| NOTE not found in `cfged_out`
-    //~| NOTE the item is gated here
 }
diff --git a/tests/ui/cfg/diagnostics-cross-crate.stderr b/tests/ui/cfg/diagnostics-cross-crate.stderr
index 155b3db2f42..658e5a442bd 100644
--- a/tests/ui/cfg/diagnostics-cross-crate.stderr
+++ b/tests/ui/cfg/diagnostics-cross-crate.stderr
@@ -1,5 +1,5 @@
 error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
-  --> $DIR/diagnostics-cross-crate.rs:18:23
+  --> $DIR/diagnostics-cross-crate.rs:17:23
    |
 LL |     cfged_out::inner::doesnt_exist::hello();
    |                       ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
@@ -7,13 +7,10 @@ LL |     cfged_out::inner::doesnt_exist::hello();
 note: found an item that was configured out
   --> $DIR/auxiliary/cfged_out.rs:6:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
 LL |     pub mod doesnt_exist {
    |             ^^^^^^^^^^^^
-note: the item is gated here
-  --> $DIR/auxiliary/cfged_out.rs:5:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0425]: cannot find function `uwu` in crate `cfged_out`
   --> $DIR/diagnostics-cross-crate.rs:7:16
@@ -30,16 +27,13 @@ LL |     cfged_out::inner::uwu();
 note: found an item that was configured out
   --> $DIR/auxiliary/cfged_out.rs:3:12
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
 LL |     pub fn uwu() {}
    |            ^^^
-note: the item is gated here
-  --> $DIR/auxiliary/cfged_out.rs:2:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0425]: cannot find function `meow` in module `cfged_out::inner::right`
-  --> $DIR/diagnostics-cross-crate.rs:24:30
+  --> $DIR/diagnostics-cross-crate.rs:22:30
    |
 LL |     cfged_out::inner::right::meow();
    |                              ^^^^ not found in `cfged_out::inner::right`
@@ -47,16 +41,13 @@ LL |     cfged_out::inner::right::meow();
 note: found an item that was configured out
   --> $DIR/auxiliary/cfged_out.rs:17:16
    |
+LL |         #[cfg(feature = "what-a-cool-feature")]
+   |               ------------------------------- the item is gated behind the `what-a-cool-feature` feature
 LL |         pub fn meow() {}
    |                ^^^^
-note: the item is gated behind the `what-a-cool-feature` feature
-  --> $DIR/auxiliary/cfged_out.rs:16:15
-   |
-LL |         #[cfg(feature = "what-a-cool-feature")]
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `vanished` in crate `cfged_out`
-  --> $DIR/diagnostics-cross-crate.rs:30:16
+  --> $DIR/diagnostics-cross-crate.rs:27:16
    |
 LL |     cfged_out::vanished();
    |                ^^^^^^^^ not found in `cfged_out`
@@ -64,13 +55,10 @@ LL |     cfged_out::vanished();
 note: found an item that was configured out
   --> $DIR/auxiliary/cfged_out.rs:22:8
    |
+LL | #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
+   |       -------------------------------------------- the item is gated here
 LL | pub fn vanished() {}
    |        ^^^^^^^^
-note: the item is gated here
-  --> $DIR/auxiliary/cfged_out.rs:21:7
-   |
-LL | #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/cfg/diagnostics-reexport-2.stderr b/tests/ui/cfg/diagnostics-reexport-2.stderr
index e1f91fcc5d1..713cffce65b 100644
--- a/tests/ui/cfg/diagnostics-reexport-2.stderr
+++ b/tests/ui/cfg/diagnostics-reexport-2.stderr
@@ -7,13 +7,11 @@ LL |     reexport::gated::foo();
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport-2.rs:10:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
+...
 LL |     pub mod gated {
    |             ^^^^^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport-2.rs:4:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0433]: failed to resolve: could not find `gated` in `reexport2`
   --> $DIR/diagnostics-reexport-2.rs:46:16
@@ -24,13 +22,11 @@ LL |     reexport2::gated::foo();
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport-2.rs:10:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
+...
 LL |     pub mod gated {
    |             ^^^^^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport-2.rs:4:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0433]: failed to resolve: could not find `gated` in `reexport30`
   --> $DIR/diagnostics-reexport-2.rs:50:17
@@ -41,13 +37,11 @@ LL |     reexport30::gated::foo();
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport-2.rs:10:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
+...
 LL |     pub mod gated {
    |             ^^^^^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport-2.rs:4:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0433]: failed to resolve: could not find `gated` in `reexport31`
   --> $DIR/diagnostics-reexport-2.rs:54:17
@@ -58,13 +52,11 @@ LL |     reexport31::gated::foo();
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport-2.rs:10:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
+...
 LL |     pub mod gated {
    |             ^^^^^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport-2.rs:4:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0433]: failed to resolve: could not find `gated` in `reexport32`
   --> $DIR/diagnostics-reexport-2.rs:58:17
@@ -75,13 +67,11 @@ LL |     reexport32::gated::foo();
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport-2.rs:10:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
+...
 LL |     pub mod gated {
    |             ^^^^^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport-2.rs:4:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/cfg/diagnostics-reexport.rs b/tests/ui/cfg/diagnostics-reexport.rs
index 56fac562238..c6a714fca71 100644
--- a/tests/ui/cfg/diagnostics-reexport.rs
+++ b/tests/ui/cfg/diagnostics-reexport.rs
@@ -34,7 +34,7 @@ mod b {
 }
 
 fn main() {
-    // There is no uwu at this path - no diagnostic.
+    // There is no uwu at this path, but there's one in a cgfd out sub-module, so we mention it.
     inner::uwu(); //~ ERROR cannot find function
     //~^ NOTE not found in `inner`
 }
diff --git a/tests/ui/cfg/diagnostics-reexport.stderr b/tests/ui/cfg/diagnostics-reexport.stderr
index bf1bbcba7e4..a3a6e13f475 100644
--- a/tests/ui/cfg/diagnostics-reexport.stderr
+++ b/tests/ui/cfg/diagnostics-reexport.stderr
@@ -7,13 +7,10 @@ LL | pub use a::x;
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport.rs:18:12
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
 LL |     pub fn x() {}
    |            ^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport.rs:17:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0432]: unresolved imports `b::x`, `b::y`
   --> $DIR/diagnostics-reexport.rs:22:13
@@ -26,23 +23,17 @@ LL | pub use b::{x, y};
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport.rs:29:12
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
 LL |     pub fn x() {}
    |            ^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport.rs:28:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport.rs:32:12
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
 LL |     pub fn y() {}
    |            ^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport.rs:31:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0425]: cannot find function `uwu` in module `inner`
   --> $DIR/diagnostics-reexport.rs:38:12
@@ -53,13 +44,10 @@ LL |     inner::uwu();
 note: found an item that was configured out
   --> $DIR/diagnostics-reexport.rs:8:20
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
 LL |     pub use super::uwu;
    |                    ^^^
-note: the item is gated here
-  --> $DIR/diagnostics-reexport.rs:7:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/cfg/diagnostics-same-crate.rs b/tests/ui/cfg/diagnostics-same-crate.rs
index 9153f20b296..29209d5f3ea 100644
--- a/tests/ui/cfg/diagnostics-same-crate.rs
+++ b/tests/ui/cfg/diagnostics-same-crate.rs
@@ -37,8 +37,8 @@ mod placeholder {
     //~| NOTE could not find `doesnt_exist` in `inner`
 }
 
-#[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
-pub fn vanished() {}
+#[cfg(i_dont_exist_and_you_can_do_nothing_about_it)] //~ NOTE the item is gated here
+pub fn vanished() {} //~ NOTE found an item that was configured out
 
 fn main() {
     // There is no uwu at this path - no diagnostic.
@@ -49,8 +49,7 @@ fn main() {
     inner::uwu(); //~ ERROR cannot find function
     //~| NOTE not found in `inner`
 
-    // The module isn't found - we would like to get a diagnostic, but currently don't due to
-    // the awkward way the resolver diagnostics are currently implemented.
+    // The module isn't found - we get a diagnostic.
     inner::doesnt_exist::hello(); //~ ERROR failed to resolve
     //~| NOTE could not find `doesnt_exist` in `inner`
 
@@ -58,9 +57,8 @@ fn main() {
     inner::right::meow(); //~ ERROR cannot find function
     //~| NOTE not found in `inner::right
 
-    // Exists in the crate root - we would generally want a diagnostic,
-    // but currently don't have one.
-    // Not that it matters much though, this is highly unlikely to confuse anyone.
+    // Exists in the crate root - we show a diagnostic because we treat "no module DefId" as "crate
+    // root DefId".
     vanished(); //~ ERROR cannot find function
     //~^ NOTE not found in this scope
 }
diff --git a/tests/ui/cfg/diagnostics-same-crate.stderr b/tests/ui/cfg/diagnostics-same-crate.stderr
index 121f25ca090..a8d789e61d1 100644
--- a/tests/ui/cfg/diagnostics-same-crate.stderr
+++ b/tests/ui/cfg/diagnostics-same-crate.stderr
@@ -7,13 +7,11 @@ LL |     use super::inner::doesnt_exist;
 note: found an item that was configured out
   --> $DIR/diagnostics-same-crate.rs:11:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
+...
 LL |     pub mod doesnt_exist {
    |             ^^^^^^^^^^^^
-note: the item is gated here
-  --> $DIR/diagnostics-same-crate.rs:8:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0432]: unresolved import `super::inner::doesnt_exist`
   --> $DIR/diagnostics-same-crate.rs:35:23
@@ -24,16 +22,14 @@ LL |     use super::inner::doesnt_exist::hi;
 note: found an item that was configured out
   --> $DIR/diagnostics-same-crate.rs:11:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
+...
 LL |     pub mod doesnt_exist {
    |             ^^^^^^^^^^^^
-note: the item is gated here
-  --> $DIR/diagnostics-same-crate.rs:8:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
-  --> $DIR/diagnostics-same-crate.rs:54:12
+  --> $DIR/diagnostics-same-crate.rs:53:12
    |
 LL |     inner::doesnt_exist::hello();
    |            ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
@@ -41,13 +37,11 @@ LL |     inner::doesnt_exist::hello();
 note: found an item that was configured out
   --> $DIR/diagnostics-same-crate.rs:11:13
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
+...
 LL |     pub mod doesnt_exist {
    |             ^^^^^^^^^^^^
-note: the item is gated here
-  --> $DIR/diagnostics-same-crate.rs:8:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0425]: cannot find function `uwu` in module `inner`
   --> $DIR/diagnostics-same-crate.rs:49:12
@@ -58,16 +52,13 @@ LL |     inner::uwu();
 note: found an item that was configured out
   --> $DIR/diagnostics-same-crate.rs:5:12
    |
+LL |     #[cfg(false)]
+   |           ----- the item is gated here
 LL |     pub fn uwu() {}
    |            ^^^
-note: the item is gated here
-  --> $DIR/diagnostics-same-crate.rs:4:11
-   |
-LL |     #[cfg(false)]
-   |           ^^^^^
 
 error[E0425]: cannot find function `meow` in module `inner::right`
-  --> $DIR/diagnostics-same-crate.rs:58:19
+  --> $DIR/diagnostics-same-crate.rs:57:19
    |
 LL |     inner::right::meow();
    |                   ^^^^ not found in `inner::right`
@@ -75,13 +66,10 @@ LL |     inner::right::meow();
 note: found an item that was configured out
   --> $DIR/diagnostics-same-crate.rs:26:16
    |
+LL |         #[cfg(feature = "what-a-cool-feature")]
+   |               ------------------------------- the item is gated behind the `what-a-cool-feature` feature
 LL |         pub fn meow() {}
    |                ^^^^
-note: the item is gated behind the `what-a-cool-feature` feature
-  --> $DIR/diagnostics-same-crate.rs:25:15
-   |
-LL |         #[cfg(feature = "what-a-cool-feature")]
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find function `uwu` in this scope
   --> $DIR/diagnostics-same-crate.rs:45:5
@@ -90,10 +78,18 @@ LL |     uwu();
    |     ^^^ not found in this scope
 
 error[E0425]: cannot find function `vanished` in this scope
-  --> $DIR/diagnostics-same-crate.rs:64:5
+  --> $DIR/diagnostics-same-crate.rs:62:5
    |
 LL |     vanished();
    |     ^^^^^^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/diagnostics-same-crate.rs:41:8
+   |
+LL | #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
+   |       -------------------------------------------- the item is gated here
+LL | pub fn vanished() {}
+   |        ^^^^^^^^
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs
index 7618e83a642..c5d86a27d52 100644
--- a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs
+++ b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs
@@ -10,9 +10,10 @@
 //!
 //! Added in <https://github.com/rust-lang/rust/pull/34216>.
 
-#[cfg_attr(all(), cfg_attr(all(), cfg(false)))]
-fn f() {}
+#[cfg_attr(all(), cfg_attr(all(), cfg(false)))] //~ NOTE the item is gated here
+fn f() {} //~ NOTE found an item that was configured out
 
 fn main() {
     f() //~ ERROR cannot find function `f` in this scope
+    //~^ NOTE not found in this scope
 }
diff --git a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr
index ddb8ea1e13a..3f833bd558b 100644
--- a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr
+++ b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr
@@ -3,6 +3,14 @@ error[E0425]: cannot find function `f` in this scope
    |
 LL |     f()
    |     ^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/nested-cfg-attr-conditional-compilation.rs:14:4
+   |
+LL | #[cfg_attr(all(), cfg_attr(all(), cfg(false)))]
+   |                                       ----- the item is gated here
+LL | fn f() {}
+   |    ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-12127.rs b/tests/ui/closures/fnonce-moved-twice-12127.rs
index 199d542e816..369ddcafaab 100644
--- a/tests/ui/issues/issue-12127.rs
+++ b/tests/ui/closures/fnonce-moved-twice-12127.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12127
+
 #![feature(unboxed_closures, tuple_trait)]
 
 fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
diff --git a/tests/ui/issues/issue-12127.stderr b/tests/ui/closures/fnonce-moved-twice-12127.stderr
index 2a6233547ee..c2e12827527 100644
--- a/tests/ui/issues/issue-12127.stderr
+++ b/tests/ui/closures/fnonce-moved-twice-12127.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `f`
-  --> $DIR/issue-12127.rs:11:9
+  --> $DIR/fnonce-moved-twice-12127.rs:13:9
    |
 LL |         f();
    |         --- `f` moved due to this call
@@ -7,11 +7,11 @@ LL |         f();
    |         ^ value used here after move
    |
 note: this value implements `FnOnce`, which causes it to be moved when called
-  --> $DIR/issue-12127.rs:10:9
+  --> $DIR/fnonce-moved-twice-12127.rs:12:9
    |
 LL |         f();
    |         ^
-   = note: move occurs because `f` has type `{closure@$DIR/issue-12127.rs:8:24: 8:30}`, which does not implement the `Copy` trait
+   = note: move occurs because `f` has type `{closure@$DIR/fnonce-moved-twice-12127.rs:10:24: 10:30}`, which does not implement the `Copy` trait
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-11958.rs b/tests/ui/closures/moved-upvar-mut-rebind-11958.rs
index 9185c5158af..701dc1a2cef 100644
--- a/tests/ui/issues/issue-11958.rs
+++ b/tests/ui/closures/moved-upvar-mut-rebind-11958.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/11958
+
 //@ run-pass
 
 // We shouldn't need to rebind a moved upvar as mut if it's already
diff --git a/tests/ui/issues/issue-11958.stderr b/tests/ui/closures/moved-upvar-mut-rebind-11958.stderr
index 5dca4c2f01d..b12bbcad925 100644
--- a/tests/ui/issues/issue-11958.stderr
+++ b/tests/ui/closures/moved-upvar-mut-rebind-11958.stderr
@@ -1,5 +1,5 @@
 warning: value assigned to `x` is never read
-  --> $DIR/issue-11958.rs:8:36
+  --> $DIR/moved-upvar-mut-rebind-11958.rs:10:36
    |
 LL |     let _thunk = Box::new(move|| { x = 2; });
    |                                    ^
@@ -8,7 +8,7 @@ LL |     let _thunk = Box::new(move|| { x = 2; });
    = note: `#[warn(unused_assignments)]` on by default
 
 warning: unused variable: `x`
-  --> $DIR/issue-11958.rs:8:36
+  --> $DIR/moved-upvar-mut-rebind-11958.rs:10:36
    |
 LL |     let _thunk = Box::new(move|| { x = 2; });
    |                                    ^
diff --git a/tests/ui/issues/issue-36023.rs b/tests/ui/codegen/llvm-miscompile-metadata-invalidation-36023.rs
index 32e8af65c7d..efa31a51881 100644
--- a/tests/ui/issues/issue-36023.rs
+++ b/tests/ui/codegen/llvm-miscompile-metadata-invalidation-36023.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/36023
 //@ run-pass
 #![allow(unused_variables)]
 use std::ops::Deref;
diff --git a/tests/ui/codegen/unsupported-static-initializer-in-const-array.rs b/tests/ui/codegen/unsupported-static-initializer-in-const-array.rs
new file mode 100644
index 00000000000..bc94130ee19
--- /dev/null
+++ b/tests/ui/codegen/unsupported-static-initializer-in-const-array.rs
@@ -0,0 +1,18 @@
+//! LLVM error with unsupported expression in static
+//! initializer for const pointer in array on macOS.
+//!
+//! Regression test for <https://github.com/rust-lang/rust/issues/89225>.
+
+//@ build-pass
+//@ compile-flags: -C opt-level=3
+
+const fn make() -> (i32, i32, *const i32) {
+    const V: i32 = 123;
+    &V as *const i32;
+    (0, 0, &V)
+}
+
+fn main() {
+    let arr = [make(); 32];
+    println!("{}", arr[0].0);
+}
diff --git a/tests/ui/issues/issue-12744.rs b/tests/ui/coercion/any-trait-object-debug-12744.rs
index eaf92d413d5..4d981c077ee 100644
--- a/tests/ui/issues/issue-12744.rs
+++ b/tests/ui/coercion/any-trait-object-debug-12744.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12744
+
 //@ run-pass
 fn main() {
     fn test() -> Box<dyn std::any::Any + 'static> { Box::new(1) }
diff --git a/tests/ui/issues/issue-18058.rs b/tests/ui/coherence/impl-coherence-error-for-undefined-type-18058.rs
index cced66717e1..52baf9871c3 100644
--- a/tests/ui/issues/issue-18058.rs
+++ b/tests/ui/coherence/impl-coherence-error-for-undefined-type-18058.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/18058
 impl Undefined {}
 //~^ ERROR cannot find type `Undefined` in this scope
 
diff --git a/tests/ui/issues/issue-18058.stderr b/tests/ui/coherence/impl-coherence-error-for-undefined-type-18058.stderr
index c880bb00291..07dce0b04fd 100644
--- a/tests/ui/issues/issue-18058.stderr
+++ b/tests/ui/coherence/impl-coherence-error-for-undefined-type-18058.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `Undefined` in this scope
-  --> $DIR/issue-18058.rs:1:6
+  --> $DIR/impl-coherence-error-for-undefined-type-18058.rs:2:6
    |
 LL | impl Undefined {}
    |      ^^^^^^^^^ not found in this scope
diff --git a/tests/ui/issues/issue-12860.rs b/tests/ui/collections/hashset-connected-border-12860.rs
index 255f6670793..40185bef7c8 100644
--- a/tests/ui/issues/issue-12860.rs
+++ b/tests/ui/collections/hashset-connected-border-12860.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12860
+
 //@ run-pass
 use std::collections::HashSet;
 
diff --git a/tests/ui/conditional-compilation/test-cfg.rs b/tests/ui/conditional-compilation/test-cfg.rs
index adbbc309be4..b3fff26a8fd 100644
--- a/tests/ui/conditional-compilation/test-cfg.rs
+++ b/tests/ui/conditional-compilation/test-cfg.rs
@@ -1,8 +1,10 @@
 //@ compile-flags: --cfg foo --check-cfg=cfg(foo,bar)
 
 #[cfg(all(foo, bar))] // foo AND bar
-fn foo() {}
+//~^ NOTE the item is gated here
+fn foo() {} //~ NOTE found an item that was configured out
 
 fn main() {
     foo(); //~ ERROR cannot find function `foo` in this scope
+    //~^ NOTE not found in this scope
 }
diff --git a/tests/ui/conditional-compilation/test-cfg.stderr b/tests/ui/conditional-compilation/test-cfg.stderr
index 9715f16acc2..379456f74b1 100644
--- a/tests/ui/conditional-compilation/test-cfg.stderr
+++ b/tests/ui/conditional-compilation/test-cfg.stderr
@@ -1,8 +1,17 @@
 error[E0425]: cannot find function `foo` in this scope
-  --> $DIR/test-cfg.rs:7:5
+  --> $DIR/test-cfg.rs:8:5
    |
 LL |     foo();
    |     ^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/test-cfg.rs:5:4
+   |
+LL | #[cfg(all(foo, bar))] // foo AND bar
+   |                --- the item is gated here
+LL |
+LL | fn foo() {}
+   |    ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-77919.rs b/tests/ui/const-generics/trait-resolution-error-with-const-generics-77919.rs
index bf603314977..5ab443422df 100644
--- a/tests/ui/issues/issue-77919.rs
+++ b/tests/ui/const-generics/trait-resolution-error-with-const-generics-77919.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/77919
 fn main() {
     [1; <Multiply<Five, Five>>::VAL];
 }
diff --git a/tests/ui/issues/issue-77919.stderr b/tests/ui/const-generics/trait-resolution-error-with-const-generics-77919.stderr
index dbbe70ff069..bac8abf46dc 100644
--- a/tests/ui/issues/issue-77919.stderr
+++ b/tests/ui/const-generics/trait-resolution-error-with-const-generics-77919.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `PhantomData` in this scope
-  --> $DIR/issue-77919.rs:9:9
+  --> $DIR/trait-resolution-error-with-const-generics-77919.rs:10:9
    |
 LL |     _n: PhantomData,
    |         ^^^^^^^^^^^ not found in this scope
@@ -10,7 +10,7 @@ LL + use std::marker::PhantomData;
    |
 
 error[E0412]: cannot find type `VAL` in this scope
-  --> $DIR/issue-77919.rs:11:63
+  --> $DIR/trait-resolution-error-with-const-generics-77919.rs:12:63
    |
 LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
    |                                                               ^^^ not found in this scope
@@ -21,7 +21,7 @@ LL | impl<N, M, VAL> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
    |          +++++
 
 error[E0046]: not all trait items implemented, missing: `VAL`
-  --> $DIR/issue-77919.rs:11:1
+  --> $DIR/trait-resolution-error-with-const-generics-77919.rs:12:1
    |
 LL |     const VAL: T;
    |     ------------ `VAL` from trait
diff --git a/tests/ui/issues/issue-13446.rs b/tests/ui/const-generics/vec-macro-in-static-array.rs
index 9f1fc42774f..7a81836e255 100644
--- a/tests/ui/issues/issue-13446.rs
+++ b/tests/ui/const-generics/vec-macro-in-static-array.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13446
+
 // Used to cause ICE
 
 static VEC: [u32; 256] = vec![];
diff --git a/tests/ui/issues/issue-13446.stderr b/tests/ui/const-generics/vec-macro-in-static-array.stderr
index 28c459e6e62..de21f2274f3 100644
--- a/tests/ui/issues/issue-13446.stderr
+++ b/tests/ui/const-generics/vec-macro-in-static-array.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-13446.rs:3:26
+  --> $DIR/vec-macro-in-static-array.rs:5:26
    |
 LL | static VEC: [u32; 256] = vec![];
    |                          ^^^^^^ expected `[u32; 256]`, found `Vec<_>`
diff --git a/tests/ui/coroutine/clone-impl-async.rs b/tests/ui/coroutine/clone-impl-async.rs
index 2794b167aa2..4e2b26d0295 100644
--- a/tests/ui/coroutine/clone-impl-async.rs
+++ b/tests/ui/coroutine/clone-impl-async.rs
@@ -9,7 +9,7 @@ use std::future::ready;
 
 struct NonClone;
 
-fn main() {
+fn local() {
     let inner_non_clone = async {
         let non_clone = NonClone;
         let () = ready(()).await;
@@ -34,7 +34,9 @@ fn main() {
     //~^ ERROR : Copy` is not satisfied
     check_clone(&maybe_copy_clone);
     //~^ ERROR : Clone` is not satisfied
+}
 
+fn non_local() {
     let inner_non_clone_fn = the_inner_non_clone_fn();
     check_copy(&inner_non_clone_fn);
     //~^ ERROR : Copy` is not satisfied
@@ -69,3 +71,5 @@ async fn the_maybe_copy_clone_fn() {}
 
 fn check_copy<T: Copy>(_x: &T) {}
 fn check_clone<T: Clone>(_x: &T) {}
+
+fn main() {}
diff --git a/tests/ui/coroutine/clone-impl-async.stderr b/tests/ui/coroutine/clone-impl-async.stderr
index 62bcce2fbcb..319a5ed3d8d 100644
--- a/tests/ui/coroutine/clone-impl-async.stderr
+++ b/tests/ui/coroutine/clone-impl-async.stderr
@@ -1,167 +1,155 @@
-error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}: Copy` is not satisfied
-  --> $DIR/clone-impl-async.rs:18:16
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+  --> $DIR/clone-impl-async.rs:41:16
    |
-LL |     check_copy(&inner_non_clone);
-   |     ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}`
+LL |     check_copy(&inner_non_clone_fn);
+   |     ---------- ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl-async.rs:70:18
+  --> $DIR/clone-impl-async.rs:72:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}: Clone` is not satisfied
-  --> $DIR/clone-impl-async.rs:20:17
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+  --> $DIR/clone-impl-async.rs:43:17
    |
-LL |     check_clone(&inner_non_clone);
-   |     ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}`
+LL |     check_clone(&inner_non_clone_fn);
+   |     ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl-async.rs:71:19
+  --> $DIR/clone-impl-async.rs:73:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
 
-error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}: Copy` is not satisfied
-  --> $DIR/clone-impl-async.rs:27:16
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+  --> $DIR/clone-impl-async.rs:47:16
    |
-LL |     check_copy(&outer_non_clone);
-   |     ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}`
+LL |     check_copy(&outer_non_clone_fn);
+   |     ---------- ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl-async.rs:70:18
+  --> $DIR/clone-impl-async.rs:72:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}: Clone` is not satisfied
-  --> $DIR/clone-impl-async.rs:29:17
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+  --> $DIR/clone-impl-async.rs:49:17
    |
-LL |     check_clone(&outer_non_clone);
-   |     ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}`
+LL |     check_clone(&outer_non_clone_fn);
+   |     ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl-async.rs:71:19
+  --> $DIR/clone-impl-async.rs:73:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
 
-error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}: Copy` is not satisfied
-  --> $DIR/clone-impl-async.rs:33:16
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+  --> $DIR/clone-impl-async.rs:53:16
    |
-LL |     check_copy(&maybe_copy_clone);
-   |     ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}`
+LL |     check_copy(&maybe_copy_clone_fn);
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl-async.rs:70:18
+  --> $DIR/clone-impl-async.rs:72:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}: Clone` is not satisfied
-  --> $DIR/clone-impl-async.rs:35:17
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+  --> $DIR/clone-impl-async.rs:55:17
    |
-LL |     check_clone(&maybe_copy_clone);
-   |     ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}`
+LL |     check_clone(&maybe_copy_clone_fn);
+   |     ----------- ^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl-async.rs:71:19
+  --> $DIR/clone-impl-async.rs:73:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
 
-error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
-  --> $DIR/clone-impl-async.rs:39:16
+error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}: Copy` is not satisfied
+  --> $DIR/clone-impl-async.rs:18:5
    |
-LL |     check_copy(&inner_non_clone_fn);
-   |     ---------- ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
-   |     |
-   |     required by a bound introduced by this call
+LL |     check_copy(&inner_non_clone);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}`
    |
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl-async.rs:70:18
+  --> $DIR/clone-impl-async.rs:72:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
-  --> $DIR/clone-impl-async.rs:41:17
+error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}: Clone` is not satisfied
+  --> $DIR/clone-impl-async.rs:20:5
    |
-LL |     check_clone(&inner_non_clone_fn);
-   |     ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
-   |     |
-   |     required by a bound introduced by this call
+LL |     check_clone(&inner_non_clone);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}`
    |
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl-async.rs:71:19
+  --> $DIR/clone-impl-async.rs:73:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
 
-error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
-  --> $DIR/clone-impl-async.rs:45:16
+error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}: Copy` is not satisfied
+  --> $DIR/clone-impl-async.rs:27:5
    |
-LL |     check_copy(&outer_non_clone_fn);
-   |     ---------- ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
-   |     |
-   |     required by a bound introduced by this call
+LL |     check_copy(&outer_non_clone);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}`
    |
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl-async.rs:70:18
+  --> $DIR/clone-impl-async.rs:72:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
-  --> $DIR/clone-impl-async.rs:47:17
+error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}: Clone` is not satisfied
+  --> $DIR/clone-impl-async.rs:29:5
    |
-LL |     check_clone(&outer_non_clone_fn);
-   |     ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
-   |     |
-   |     required by a bound introduced by this call
+LL |     check_clone(&outer_non_clone);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}`
    |
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl-async.rs:71:19
+  --> $DIR/clone-impl-async.rs:73:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
 
-error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
-  --> $DIR/clone-impl-async.rs:51:16
+error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}: Copy` is not satisfied
+  --> $DIR/clone-impl-async.rs:33:5
    |
-LL |     check_copy(&maybe_copy_clone_fn);
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
-   |     |
-   |     required by a bound introduced by this call
+LL |     check_copy(&maybe_copy_clone);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}`
    |
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl-async.rs:70:18
+  --> $DIR/clone-impl-async.rs:72:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
-  --> $DIR/clone-impl-async.rs:53:17
+error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}: Clone` is not satisfied
+  --> $DIR/clone-impl-async.rs:35:5
    |
-LL |     check_clone(&maybe_copy_clone_fn);
-   |     ----------- ^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
-   |     |
-   |     required by a bound introduced by this call
+LL |     check_clone(&maybe_copy_clone);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}`
    |
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl-async.rs:71:19
+  --> $DIR/clone-impl-async.rs:73:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
diff --git a/tests/ui/coroutine/clone-impl-static.stderr b/tests/ui/coroutine/clone-impl-static.stderr
index 9fb71fd5fd0..4df6b9759c3 100644
--- a/tests/ui/coroutine/clone-impl-static.stderr
+++ b/tests/ui/coroutine/clone-impl-static.stderr
@@ -1,10 +1,8 @@
 error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}: Copy` is not satisfied
-  --> $DIR/clone-impl-static.rs:14:16
+  --> $DIR/clone-impl-static.rs:14:5
    |
 LL |     check_copy(&generator);
-   |     ---------- ^^^^^^^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
-   |     |
-   |     required by a bound introduced by this call
+   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
    |
 note: required by a bound in `check_copy`
   --> $DIR/clone-impl-static.rs:20:18
@@ -13,12 +11,10 @@ LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
 error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}: Clone` is not satisfied
-  --> $DIR/clone-impl-static.rs:16:17
+  --> $DIR/clone-impl-static.rs:16:5
    |
 LL |     check_clone(&generator);
-   |     ----------- ^^^^^^^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
-   |     |
-   |     required by a bound introduced by this call
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
    |
 note: required by a bound in `check_clone`
   --> $DIR/clone-impl-static.rs:21:19
diff --git a/tests/ui/coroutine/clone-impl.rs b/tests/ui/coroutine/clone-impl.rs
index e528f031d52..9e04e256fc1 100644
--- a/tests/ui/coroutine/clone-impl.rs
+++ b/tests/ui/coroutine/clone-impl.rs
@@ -42,6 +42,7 @@ fn test3_upvars() {
     let clonable_0: Vec<u32> = Vec::new();
     let gen_clone_0 = #[coroutine]
     move || {
+        yield;
         drop(clonable_0);
     };
     check_copy(&gen_clone_0);
diff --git a/tests/ui/coroutine/clone-impl.stderr b/tests/ui/coroutine/clone-impl.stderr
index 714e5aa3d9e..f316902a42d 100644
--- a/tests/ui/coroutine/clone-impl.stderr
+++ b/tests/ui/coroutine/clone-impl.stderr
@@ -1,59 +1,81 @@
 error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`
-  --> $DIR/clone-impl.rs:47:16
+  --> $DIR/clone-impl.rs:48:5
    |
 LL |     move || {
    |     ------- within this `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`
 ...
 LL |     check_copy(&gen_clone_0);
-   |                ^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec<u32>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec<u32>`
    |
 note: captured value does not implement `Copy`
-  --> $DIR/clone-impl.rs:45:14
+  --> $DIR/clone-impl.rs:46:14
    |
 LL |         drop(clonable_0);
    |              ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:91:18
+  --> $DIR/clone-impl.rs:92:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`
-  --> $DIR/clone-impl.rs:73:16
+error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:55:5: 55:12}`
+  --> $DIR/clone-impl.rs:60:5
    |
 LL |     move || {
-   |     ------- within this `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:55:5: 55:12}`
 ...
 LL |     check_copy(&gen_clone_1);
-   |                ^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`, the trait `Copy` is not implemented for `Vec<u32>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:55:5: 55:12}`, the trait `Copy` is not implemented for `Vec<char>`
+   |
+note: coroutine does not implement `Copy` as this value is used across a yield
+  --> $DIR/clone-impl.rs:57:9
+   |
+LL |         let v = vec!['a'];
+   |             - has type `Vec<char>` which does not implement `Copy`
+LL |         yield;
+   |         ^^^^^ yield occurs here, with `v` maybe used later
+note: required by a bound in `check_copy`
+  --> $DIR/clone-impl.rs:92:18
+   |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+   |                  ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:68:5: 68:12}`
+  --> $DIR/clone-impl.rs:74:5
+   |
+LL |     move || {
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:68:5: 68:12}`
+...
+LL |     check_copy(&gen_clone_1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:68:5: 68:12}`, the trait `Copy` is not implemented for `Vec<u32>`
    |
 note: captured value does not implement `Copy`
-  --> $DIR/clone-impl.rs:71:14
+  --> $DIR/clone-impl.rs:72:14
    |
 LL |         drop(clonable_1);
    |              ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:91:18
+  --> $DIR/clone-impl.rs:92:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
-  --> $DIR/clone-impl.rs:85:16
+error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`
+  --> $DIR/clone-impl.rs:86:5
    |
 LL |     move || {
-   |     ------- within this `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`
 ...
 LL |     check_copy(&gen_non_clone);
-   |                ^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`, the trait `Copy` is not implemented for `NonClone`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`, the trait `Copy` is not implemented for `NonClone`
    |
 note: captured value does not implement `Copy`
-  --> $DIR/clone-impl.rs:83:14
+  --> $DIR/clone-impl.rs:84:14
    |
 LL |         drop(non_clonable);
    |              ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy`
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:91:18
+  --> $DIR/clone-impl.rs:92:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
@@ -63,22 +85,22 @@ LL + #[derive(Copy)]
 LL | struct NonClone;
    |
 
-error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
-  --> $DIR/clone-impl.rs:87:17
+error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`
+  --> $DIR/clone-impl.rs:88:5
    |
 LL |     move || {
-   |     ------- within this `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`
 ...
 LL |     check_clone(&gen_non_clone);
-   |                 ^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`, the trait `Clone` is not implemented for `NonClone`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`, the trait `Clone` is not implemented for `NonClone`
    |
 note: captured value does not implement `Clone`
-  --> $DIR/clone-impl.rs:83:14
+  --> $DIR/clone-impl.rs:84:14
    |
 LL |         drop(non_clonable);
    |              ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone`
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl.rs:92:19
+  --> $DIR/clone-impl.rs:93:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
@@ -88,28 +110,6 @@ LL + #[derive(Clone)]
 LL | struct NonClone;
    |
 
-error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}`
-  --> $DIR/clone-impl.rs:59:5
-   |
-LL |     move || {
-   |     ------- within this `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}`
-...
-LL |     check_copy(&gen_clone_1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}`, the trait `Copy` is not implemented for `Vec<char>`
-   |
-note: coroutine does not implement `Copy` as this value is used across a yield
-  --> $DIR/clone-impl.rs:56:9
-   |
-LL |         let v = vec!['a'];
-   |             - has type `Vec<char>` which does not implement `Copy`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `v` maybe used later
-note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:91:18
-   |
-LL | fn check_copy<T: Copy>(_x: &T) {}
-   |                  ^^^^ required by this bound in `check_copy`
-
 error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
index 8877d45ddda..11b78e3bcf8 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
@@ -9,7 +9,7 @@ LL | |         drop(a);
 LL | |     });
    | |______^ coroutine is not `Sync`
    |
-   = help: within `{main::{closure#0} upvar_tys=() resume_ty=() yield_ty=() return_ty=() witness={main::{closure#0}}}`, the trait `Sync` is not implemented for `NotSync`
+   = help: within `{main::{closure#0} upvar_tys=() resume_ty=() yield_ty=() return_ty=()}`, the trait `Sync` is not implemented for `NotSync`
 note: coroutine is not `Sync` as this value is used across a yield
   --> $DIR/coroutine-print-verbose-2.rs:20:9
    |
@@ -34,7 +34,7 @@ LL | |         drop(a);
 LL | |     });
    | |______^ coroutine is not `Send`
    |
-   = help: within `{main::{closure#1} upvar_tys=() resume_ty=() yield_ty=() return_ty=() witness={main::{closure#1}}}`, the trait `Send` is not implemented for `NotSend`
+   = help: within `{main::{closure#1} upvar_tys=() resume_ty=() yield_ty=() return_ty=()}`, the trait `Send` is not implemented for `NotSend`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/coroutine-print-verbose-2.rs:27:9
    |
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr
index 4a1e5b078a8..135e8175793 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr
@@ -11,7 +11,7 @@ LL | |     };
    | |_____^ expected `()`, found coroutine
    |
    = note: expected unit type `()`
-              found coroutine `{main::{closure#0} upvar_tys=?4t resume_ty=() yield_ty=i32 return_ty=&'?1 str witness={main::{closure#0}}}`
+              found coroutine `{main::{closure#0} upvar_tys=?4t resume_ty=() yield_ty=i32 return_ty=&'?1 str}`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coroutine/ref-upvar-not-send.stderr b/tests/ui/coroutine/ref-upvar-not-send.stderr
index 892b5d261c2..3a5e8ec4dab 100644
--- a/tests/ui/coroutine/ref-upvar-not-send.stderr
+++ b/tests/ui/coroutine/ref-upvar-not-send.stderr
@@ -1,14 +1,13 @@
 error: coroutine cannot be sent between threads safely
-  --> $DIR/ref-upvar-not-send.rs:15:30
+  --> $DIR/ref-upvar-not-send.rs:15:5
    |
-LL |       assert_send(#[coroutine] move || {
-   |  ______________________________^
+LL | /     assert_send(#[coroutine] move || {
 LL | |
 LL | |
 LL | |         yield;
 LL | |         let _x = x;
 LL | |     });
-   | |_____^ coroutine is not `Send`
+   | |______^ coroutine is not `Send`
    |
    = help: the trait `Sync` is not implemented for `*mut ()`
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
@@ -23,16 +22,15 @@ LL | fn assert_send<T: Send>(_: T) {}
    |                   ^^^^ required by this bound in `assert_send`
 
 error: coroutine cannot be sent between threads safely
-  --> $DIR/ref-upvar-not-send.rs:23:30
+  --> $DIR/ref-upvar-not-send.rs:23:5
    |
-LL |       assert_send(#[coroutine] move || {
-   |  ______________________________^
+LL | /     assert_send(#[coroutine] move || {
 LL | |
 LL | |
 LL | |         yield;
 LL | |         let _y = y;
 LL | |     });
-   | |_____^ coroutine is not `Send`
+   | |______^ coroutine is not `Send`
    |
    = help: within `{coroutine@$DIR/ref-upvar-not-send.rs:23:30: 23:37}`, the trait `Send` is not implemented for `*mut ()`
 note: captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send`
diff --git a/tests/ui/issues/issue-4734.rs b/tests/ui/drop/destructor-run-for-expression-4734.rs
index 58aa0179693..57971ee5ef7 100644
--- a/tests/ui/issues/issue-4734.rs
+++ b/tests/ui/drop/destructor-run-for-expression-4734.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/4734
 //@ run-pass
 #![allow(dead_code)]
 // Ensures that destructors are run for expressions of the form "e;" where
diff --git a/tests/ui/error-codes/E0423.stderr b/tests/ui/error-codes/E0423.stderr
index e50b8bd820c..b699e53fb48 100644
--- a/tests/ui/error-codes/E0423.stderr
+++ b/tests/ui/error-codes/E0423.stderr
@@ -54,7 +54,7 @@ help: use struct literal syntax instead
 LL -     let f = Foo();
 LL +     let f = Foo { a: val };
    |
-help: a function with a similar name exists (notice the capitalization difference)
+help: a function with a similar name exists (notice the capitalization)
    |
 LL -     let f = Foo();
 LL +     let f = foo();
diff --git a/tests/ui/explicit-tail-calls/callee_is_ref.fixed b/tests/ui/explicit-tail-calls/callee_is_ref.fixed
new file mode 100644
index 00000000000..7525e5c5df8
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/callee_is_ref.fixed
@@ -0,0 +1,26 @@
+//@ run-rustfix
+#![feature(explicit_tail_calls)]
+#![expect(incomplete_features)]
+
+fn f() {}
+
+fn g() {
+    become (*(&f))() //~ error: tail calls can only be performed with function definitions or pointers
+}
+
+fn h() {
+    let table = [f as fn()];
+    if let Some(fun) = table.get(0) {
+        become (*fun)(); //~ error: tail calls can only be performed with function definitions or pointers
+    }
+}
+
+fn i() {
+    become (***Box::new(&mut &f))(); //~ error: tail calls can only be performed with function definitions or pointers
+}
+
+fn main() {
+    g();
+    h();
+    i();
+}
diff --git a/tests/ui/explicit-tail-calls/callee_is_ref.rs b/tests/ui/explicit-tail-calls/callee_is_ref.rs
new file mode 100644
index 00000000000..36bf9efb952
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/callee_is_ref.rs
@@ -0,0 +1,26 @@
+//@ run-rustfix
+#![feature(explicit_tail_calls)]
+#![expect(incomplete_features)]
+
+fn f() {}
+
+fn g() {
+    become (&f)() //~ error: tail calls can only be performed with function definitions or pointers
+}
+
+fn h() {
+    let table = [f as fn()];
+    if let Some(fun) = table.get(0) {
+        become fun(); //~ error: tail calls can only be performed with function definitions or pointers
+    }
+}
+
+fn i() {
+    become Box::new(&mut &f)(); //~ error: tail calls can only be performed with function definitions or pointers
+}
+
+fn main() {
+    g();
+    h();
+    i();
+}
diff --git a/tests/ui/explicit-tail-calls/callee_is_ref.stderr b/tests/ui/explicit-tail-calls/callee_is_ref.stderr
new file mode 100644
index 00000000000..4a2ff465e68
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/callee_is_ref.stderr
@@ -0,0 +1,38 @@
+error: tail calls can only be performed with function definitions or pointers
+  --> $DIR/callee_is_ref.rs:8:12
+   |
+LL |     become (&f)()
+   |            ^^^^^^
+   |
+   = note: callee has type `&fn() {f}`
+help: consider dereferencing the expression to get a function definition
+   |
+LL |     become (*(&f))()
+   |            ++    +
+
+error: tail calls can only be performed with function definitions or pointers
+  --> $DIR/callee_is_ref.rs:14:16
+   |
+LL |         become fun();
+   |                ^^^^^
+   |
+   = note: callee has type `&fn()`
+help: consider dereferencing the expression to get a function pointer
+   |
+LL |         become (*fun)();
+   |                ++   +
+
+error: tail calls can only be performed with function definitions or pointers
+  --> $DIR/callee_is_ref.rs:19:12
+   |
+LL |     become Box::new(&mut &f)();
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: callee has type `Box<&mut &fn() {f}>`
+help: consider dereferencing the expression to get a function definition
+   |
+LL |     become (***Box::new(&mut &f))();
+   |            ++++                 +
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/explicit-tail-calls/callee_is_weird.rs b/tests/ui/explicit-tail-calls/callee_is_weird.rs
new file mode 100644
index 00000000000..b3ca878c232
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/callee_is_weird.rs
@@ -0,0 +1,29 @@
+#![feature(explicit_tail_calls, exclusive_wrapper, fn_traits, unboxed_closures)]
+#![expect(incomplete_features)]
+
+fn f() {}
+
+fn g() {
+    become std::sync::Exclusive::new(f)() //~ error: tail calls can only be performed with function definitions or pointers
+}
+
+fn h() {
+    become (&mut &std::sync::Exclusive::new(f))() //~ error: tail calls can only be performed with function definitions or pointers
+}
+
+fn i() {
+    struct J;
+
+    impl FnOnce<()> for J {
+        type Output = ();
+        extern "rust-call" fn call_once(self, (): ()) -> Self::Output {}
+    }
+
+    become J(); //~ error: tail calls can only be performed with function definitions or pointers
+}
+
+fn main() {
+    g();
+    h();
+    i();
+}
diff --git a/tests/ui/explicit-tail-calls/callee_is_weird.stderr b/tests/ui/explicit-tail-calls/callee_is_weird.stderr
new file mode 100644
index 00000000000..a4e5a38ce33
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/callee_is_weird.stderr
@@ -0,0 +1,26 @@
+error: tail calls can only be performed with function definitions or pointers
+  --> $DIR/callee_is_weird.rs:7:12
+   |
+LL |     become std::sync::Exclusive::new(f)()
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: callee has type `Exclusive<fn() {f}>`
+
+error: tail calls can only be performed with function definitions or pointers
+  --> $DIR/callee_is_weird.rs:11:12
+   |
+LL |     become (&mut &std::sync::Exclusive::new(f))()
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: callee has type `Exclusive<fn() {f}>`
+
+error: tail calls can only be performed with function definitions or pointers
+  --> $DIR/callee_is_weird.rs:22:12
+   |
+LL |     become J();
+   |            ^^^
+   |
+   = note: callee has type `J`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/explicit-tail-calls/infinite-recursion-in-ctfe.rs b/tests/ui/explicit-tail-calls/infinite-recursion-in-ctfe.rs
new file mode 100644
index 00000000000..0c55f13c16c
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/infinite-recursion-in-ctfe.rs
@@ -0,0 +1,10 @@
+#![feature(explicit_tail_calls)]
+#![expect(incomplete_features)]
+
+const _: () = f();
+
+const fn f() {
+    become f(); //~ error: constant evaluation is taking a long time
+}
+
+fn main() {}
diff --git a/tests/ui/explicit-tail-calls/infinite-recursion-in-ctfe.stderr b/tests/ui/explicit-tail-calls/infinite-recursion-in-ctfe.stderr
new file mode 100644
index 00000000000..b5a96114a58
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/infinite-recursion-in-ctfe.stderr
@@ -0,0 +1,17 @@
+error: constant evaluation is taking a long time
+  --> $DIR/infinite-recursion-in-ctfe.rs:7:5
+   |
+LL |     become f();
+   |     ^^^^^^^^^^
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/infinite-recursion-in-ctfe.rs:4:1
+   |
+LL | const _: () = f();
+   | ^^^^^^^^^^^
+   = note: `#[deny(long_running_const_eval)]` on by default
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/explicit-tail-calls/intrinsics.rs b/tests/ui/explicit-tail-calls/intrinsics.rs
new file mode 100644
index 00000000000..6fc521fa27d
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/intrinsics.rs
@@ -0,0 +1,13 @@
+#![feature(explicit_tail_calls, core_intrinsics)]
+#![expect(incomplete_features, internal_features)]
+
+fn trans((): ()) {
+    unsafe { become std::mem::transmute(()) } //~ error: tail calling intrinsics is not allowed
+
+}
+
+fn cats(x: u64) -> u32 {
+    become std::intrinsics::ctlz(x) //~ error: tail calling intrinsics is not allowed
+}
+
+fn main() {}
diff --git a/tests/ui/explicit-tail-calls/intrinsics.stderr b/tests/ui/explicit-tail-calls/intrinsics.stderr
new file mode 100644
index 00000000000..b012e3629dd
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/intrinsics.stderr
@@ -0,0 +1,14 @@
+error: tail calling intrinsics is not allowed
+  --> $DIR/intrinsics.rs:5:14
+   |
+LL |     unsafe { become std::mem::transmute(()) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: tail calling intrinsics is not allowed
+  --> $DIR/intrinsics.rs:10:5
+   |
+LL |     become std::intrinsics::ctlz(x)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/extern/windows-tcb-trash-13259.rs b/tests/ui/extern/windows-tcb-trash-13259.rs
new file mode 100644
index 00000000000..0852e31251a
--- /dev/null
+++ b/tests/ui/extern/windows-tcb-trash-13259.rs
@@ -0,0 +1,49 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13259
+
+//@ run-pass
+
+#[cfg(windows)]
+mod imp {
+    type LPVOID = *mut u8;
+    type DWORD = u32;
+    type LPWSTR = *mut u16;
+
+    extern "system" {
+        fn FormatMessageW(
+            flags: DWORD,
+            lpSrc: LPVOID,
+            msgId: DWORD,
+            langId: DWORD,
+            buf: LPWSTR,
+            nsize: DWORD,
+            args: *const u8,
+        ) -> DWORD;
+    }
+
+    pub fn test() {
+        let mut buf: [u16; 50] = [0; 50];
+        let ret = unsafe {
+            FormatMessageW(
+                0x1000,
+                core::ptr::null_mut(),
+                1,
+                0x400,
+                buf.as_mut_ptr(),
+                buf.len() as u32,
+                core::ptr::null(),
+            )
+        };
+        // On some 32-bit Windowses (Win7-8 at least) this will panic with segmented
+        // stacks taking control of pvArbitrary
+        assert!(ret != 0);
+    }
+}
+
+#[cfg(not(windows))]
+mod imp {
+    pub fn test() {}
+}
+
+fn main() {
+    imp::test()
+}
diff --git a/tests/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs b/tests/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs
deleted file mode 100644
index 66bf7973832..00000000000
--- a/tests/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#[omit_gdb_pretty_printer_section] //~ ERROR the `#[omit_gdb_pretty_printer_section]` attribute is
-fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.stderr b/tests/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.stderr
deleted file mode 100644
index 2e1d27fb776..00000000000
--- a/tests/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite
-  --> $DIR/feature-gate-omit-gdb-pretty-printer-section.rs:1:1
-   |
-LL | #[omit_gdb_pretty_printer_section]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(omit_gdb_pretty_printer_section)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/issues/issue-13105.rs b/tests/ui/fn/anonymous-parameters-trait-13105.rs
index d119aa9c788..171dab15fe7 100644
--- a/tests/ui/issues/issue-13105.rs
+++ b/tests/ui/fn/anonymous-parameters-trait-13105.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13105
+
 //@ edition: 2015
 //@ check-pass
 
diff --git a/tests/ui/issues/issue-36116.rs b/tests/ui/generics/unnecessary-path-disambiguator-36116.rs
index 2313e189aff..c2dab605f59 100644
--- a/tests/ui/issues/issue-36116.rs
+++ b/tests/ui/generics/unnecessary-path-disambiguator-36116.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/36116
 // Unnecessary path disambiguator is ok
 
 //@ check-pass
diff --git a/tests/ui/impl-trait/issues/issue-55872-2.rs b/tests/ui/impl-trait/issues/issue-55872-2.rs
index a3b2225126a..aea00dd9e3d 100644
--- a/tests/ui/impl-trait/issues/issue-55872-2.rs
+++ b/tests/ui/impl-trait/issues/issue-55872-2.rs
@@ -12,7 +12,6 @@ impl<S> Bar for S {
     type E = impl std::marker::Send;
     fn foo<T>() -> Self::E {
         //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-        //~| ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
         async {}
     }
 }
diff --git a/tests/ui/impl-trait/issues/issue-55872-2.stderr b/tests/ui/impl-trait/issues/issue-55872-2.stderr
index 51a7dd00ade..91c2ecdc8a4 100644
--- a/tests/ui/impl-trait/issues/issue-55872-2.stderr
+++ b/tests/ui/impl-trait/issues/issue-55872-2.stderr
@@ -4,13 +4,5 @@ error: type parameter `T` is part of concrete type but not used in parameter lis
 LL |     fn foo<T>() -> Self::E {
    |                    ^^^^^^^
 
-error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872-2.rs:13:20
-   |
-LL |     fn foo<T>() -> Self::E {
-   |                    ^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/issues/issue-55872-3.rs b/tests/ui/impl-trait/issues/issue-55872-3.rs
index 763b4b9fd32..698e7f36234 100644
--- a/tests/ui/impl-trait/issues/issue-55872-3.rs
+++ b/tests/ui/impl-trait/issues/issue-55872-3.rs
@@ -14,7 +14,6 @@ impl<S> Bar for S {
     fn foo<T>() -> Self::E {
         //~^ ERROR : Copy` is not satisfied [E0277]
         //~| ERROR type parameter `T` is part of concrete type
-        //~| ERROR type parameter `T` is part of concrete type
         async {}
     }
 }
diff --git a/tests/ui/impl-trait/issues/issue-55872-3.stderr b/tests/ui/impl-trait/issues/issue-55872-3.stderr
index ce2dd7f02b4..5124c46baeb 100644
--- a/tests/ui/impl-trait/issues/issue-55872-3.stderr
+++ b/tests/ui/impl-trait/issues/issue-55872-3.stderr
@@ -1,26 +1,15 @@
-error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}: Copy` is not satisfied
-  --> $DIR/issue-55872-3.rs:14:20
-   |
-LL |     fn foo<T>() -> Self::E {
-   |                    ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}`
-...
-LL |         async {}
-   |         -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}` here
-
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
   --> $DIR/issue-55872-3.rs:14:20
    |
 LL |     fn foo<T>() -> Self::E {
    |                    ^^^^^^^
 
-error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}: Copy` is not satisfied
   --> $DIR/issue-55872-3.rs:14:20
    |
 LL |     fn foo<T>() -> Self::E {
-   |                    ^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   |                    ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}`
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-12909.rs b/tests/ui/inference/collection-type-copy-behavior-12909.rs
index f2c33806aae..83536e8875c 100644
--- a/tests/ui/issues/issue-12909.rs
+++ b/tests/ui/inference/collection-type-copy-behavior-12909.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/12909
 //@ run-pass
 #![allow(unused_variables)]
 
diff --git a/tests/ui/instrument-coverage/coverage-options.bad.stderr b/tests/ui/instrument-coverage/coverage-options.bad.stderr
index 1a6b30dc832..4a272cf97fb 100644
--- a/tests/ui/instrument-coverage/coverage-options.bad.stderr
+++ b/tests/ui/instrument-coverage/coverage-options.bad.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `bad` for unstable option `coverage-options` - `block` | `branch` | `condition` | `mcdc` | `no-mir-spans` was expected
+error: incorrect value `bad` for unstable option `coverage-options` - `block` | `branch` | `condition` | `mcdc` was expected
 
diff --git a/tests/ui/issues/auxiliary/issue-25185-2.rs b/tests/ui/issues/auxiliary/issue-25185-2.rs
deleted file mode 100644
index 7ce3df255a3..00000000000
--- a/tests/ui/issues/auxiliary/issue-25185-2.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-extern crate issue_25185_1;
-
-pub use issue_25185_1::rust_dbg_extern_identity_u32;
diff --git a/tests/ui/issues/issue-13259-windows-tcb-trash.rs b/tests/ui/issues/issue-13259-windows-tcb-trash.rs
deleted file mode 100644
index 381e3f15259..00000000000
--- a/tests/ui/issues/issue-13259-windows-tcb-trash.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-//@ run-pass
-
-#[cfg(windows)]
-mod imp {
-    type LPVOID = *mut u8;
-    type DWORD = u32;
-    type LPWSTR = *mut u16;
-
-    extern "system" {
-        fn FormatMessageW(flags: DWORD,
-                          lpSrc: LPVOID,
-                          msgId: DWORD,
-                          langId: DWORD,
-                          buf: LPWSTR,
-                          nsize: DWORD,
-                          args: *const u8)
-                          -> DWORD;
-    }
-
-    pub fn test() {
-        let mut buf: [u16; 50] = [0; 50];
-        let ret = unsafe {
-            FormatMessageW(0x1000, core::ptr::null_mut(), 1, 0x400,
-                           buf.as_mut_ptr(), buf.len() as u32, core::ptr::null())
-        };
-        // On some 32-bit Windowses (Win7-8 at least) this will panic with segmented
-        // stacks taking control of pvArbitrary
-        assert!(ret != 0);
-    }
-}
-
-#[cfg(not(windows))]
-mod imp {
-    pub fn test() { }
-}
-
-fn main() {
-    imp::test()
-}
diff --git a/tests/ui/issues/issue-25185.rs b/tests/ui/issues/issue-25185.rs
deleted file mode 100644
index 7dc06ad96df..00000000000
--- a/tests/ui/issues/issue-25185.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ run-pass
-//@ aux-build:issue-25185-1.rs
-//@ aux-build:issue-25185-2.rs
-
-extern crate issue_25185_2;
-
-fn main() {
-    let x = unsafe {
-        issue_25185_2::rust_dbg_extern_identity_u32(1)
-    };
-    assert_eq!(x, 1);
-}
diff --git a/tests/ui/issues/issue-32655.rs b/tests/ui/issues/issue-32655.rs
deleted file mode 100644
index f52e0923129..00000000000
--- a/tests/ui/issues/issue-32655.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-macro_rules! foo (
-    () => (
-        #[derive_Clone] //~ ERROR cannot find attribute `derive_Clone` in this scope
-        struct T;
-    );
-);
-
-macro_rules! bar (
-    ($e:item) => ($e)
-);
-
-foo!();
-
-bar!(
-    #[derive_Clone] //~ ERROR cannot find attribute `derive_Clone` in this scope
-    struct S;
-);
-
-fn main() {}
diff --git a/tests/ui/issues/issue-32655.stderr b/tests/ui/issues/issue-32655.stderr
deleted file mode 100644
index b8362499b2d..00000000000
--- a/tests/ui/issues/issue-32655.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: cannot find attribute `derive_Clone` in this scope
-  --> $DIR/issue-32655.rs:3:11
-   |
-LL |         #[derive_Clone]
-   |           ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const`
-...
-LL | foo!();
-   | ------ in this macro invocation
-  --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
-   |
-   = note: similarly named attribute macro `derive_const` defined here
-   |
-   = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: cannot find attribute `derive_Clone` in this scope
-  --> $DIR/issue-32655.rs:15:7
-   |
-LL |     #[derive_Clone]
-   |       ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const`
-  --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
-   |
-   = note: similarly named attribute macro `derive_const` defined here
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/issues/issue-12677.rs b/tests/ui/iterators/bytes-iterator-clone-12677.rs
index dbc2dbc8527..cfbb85a3ecb 100644
--- a/tests/ui/issues/issue-12677.rs
+++ b/tests/ui/iterators/bytes-iterator-clone-12677.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12677
+
 //@ run-pass
 
 fn main() {
diff --git a/tests/ui/issues/issue-15673.rs b/tests/ui/iterators/iterator-type-inference-sum-15673.rs
index bb61c246276..aee027927f2 100644
--- a/tests/ui/issues/issue-15673.rs
+++ b/tests/ui/iterators/iterator-type-inference-sum-15673.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/15673
 //@ run-pass
 #![allow(stable_features)]
 
diff --git a/tests/ui/issues/issue-13058.rs b/tests/ui/lifetimes/iterator-trait-lifetime-error-13058.rs
index a5806feb720..6cfe440b43d 100644
--- a/tests/ui/issues/issue-13058.rs
+++ b/tests/ui/lifetimes/iterator-trait-lifetime-error-13058.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13058
+
 use std::ops::Range;
 
 trait Itble<'r, T, I: Iterator<Item=T>> { fn iter(&'r self) -> I; }
diff --git a/tests/ui/issues/issue-13058.stderr b/tests/ui/lifetimes/iterator-trait-lifetime-error-13058.stderr
index 4f4108fa182..e6564e36b21 100644
--- a/tests/ui/issues/issue-13058.stderr
+++ b/tests/ui/lifetimes/iterator-trait-lifetime-error-13058.stderr
@@ -1,5 +1,5 @@
 error[E0621]: explicit lifetime required in the type of `cont`
-  --> $DIR/issue-13058.rs:14:21
+  --> $DIR/iterator-trait-lifetime-error-13058.rs:16:21
    |
 LL |     let cont_iter = cont.iter();
    |                     ^^^^^^^^^^^ lifetime `'r` required
diff --git a/tests/ui/issues/issue-13167.rs b/tests/ui/lifetimes/lifetime-inference-destructuring-arg.rs
index 5f733e85948..7a019a71d75 100644
--- a/tests/ui/issues/issue-13167.rs
+++ b/tests/ui/lifetimes/lifetime-inference-destructuring-arg.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13167
+
 //@ check-pass
 //@ revisions: current next
 //@ ignore-compare-mode-next-solver (explicit revisions)
diff --git a/tests/ui/issues/issue-13323.rs b/tests/ui/lifetimes/matcher-trait-equality-13323.rs
index 8f334404f9a..efd56294b39 100644
--- a/tests/ui/issues/issue-13323.rs
+++ b/tests/ui/lifetimes/matcher-trait-equality-13323.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13323
+
 //@ run-pass
 
 struct StrWrap {
diff --git a/tests/ui/issues/issue-13405.rs b/tests/ui/lifetimes/struct-lifetime-field-assignment-13405.rs
index 80b298d2f37..9482d89681b 100644
--- a/tests/ui/issues/issue-13405.rs
+++ b/tests/ui/lifetimes/struct-lifetime-field-assignment-13405.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13405
+
 //@ check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
diff --git a/tests/ui/issues/issue-11740.rs b/tests/ui/lifetimes/unsafe-transmute-in-find-11740.rs
index c6099c2a0c0..eeecd2e9e40 100644
--- a/tests/ui/issues/issue-11740.rs
+++ b/tests/ui/lifetimes/unsafe-transmute-in-find-11740.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/11740
+
 //@ check-pass
 
 struct Attr {
diff --git a/tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs b/tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs
index 8c194ec50df..ad7b0674478 100644
--- a/tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs
+++ b/tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs
@@ -4,6 +4,7 @@
 
 //@ ignore-emscripten no weak symbol support
 //@ ignore-apple no extern_weak linkage
+//@ ignore-aix no extern_weak linkage
 
 //@ aux-build:lib.rs
 
diff --git a/tests/ui/issues/auxiliary/issue-25185-1.rs b/tests/ui/linking/auxiliary/aux-25185-1.rs
index 032d7d5de34..032d7d5de34 100644
--- a/tests/ui/issues/auxiliary/issue-25185-1.rs
+++ b/tests/ui/linking/auxiliary/aux-25185-1.rs
diff --git a/tests/ui/linking/auxiliary/aux-25185-2.rs b/tests/ui/linking/auxiliary/aux-25185-2.rs
new file mode 100644
index 00000000000..96c73f623e4
--- /dev/null
+++ b/tests/ui/linking/auxiliary/aux-25185-2.rs
@@ -0,0 +1,3 @@
+extern crate aux_25185_1;
+
+pub use aux_25185_1::rust_dbg_extern_identity_u32;
diff --git a/tests/ui/linking/rlib-to-dylib-native-deps-inclusion-25185.rs b/tests/ui/linking/rlib-to-dylib-native-deps-inclusion-25185.rs
new file mode 100644
index 00000000000..bbcfcb75106
--- /dev/null
+++ b/tests/ui/linking/rlib-to-dylib-native-deps-inclusion-25185.rs
@@ -0,0 +1,13 @@
+// https://github.com/rust-lang/rust/issues/25185
+//@ run-pass
+//@ aux-build:aux-25185-1.rs
+//@ aux-build:aux-25185-2.rs
+
+extern crate aux_25185_2;
+
+fn main() {
+    let x = unsafe {
+        aux_25185_2::rust_dbg_extern_identity_u32(1)
+    };
+    assert_eq!(x, 1);
+}
diff --git a/tests/ui/lint/dangling-pointers-from-locals.rs b/tests/ui/lint/dangling-pointers-from-locals.rs
new file mode 100644
index 00000000000..e321df2f427
--- /dev/null
+++ b/tests/ui/lint/dangling-pointers-from-locals.rs
@@ -0,0 +1,188 @@
+//@ check-pass
+
+struct Zst((), ());
+struct Adt(u8);
+
+const X: u8 = 5;
+
+fn simple() -> *const u8 {
+    let x = 0;
+    &x
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn bindings() -> *const u8 {
+    let x = 0;
+    let x = &x;
+    x
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn bindings_with_return() -> *const u8 {
+    let x = 42;
+    let y = &x;
+    return y;
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn with_simple_cast() -> *const u8 {
+    let x = 0u8;
+    &x as *const u8
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn bindings_and_casts() -> *const u8 {
+    let x = 0u8;
+    let x = &x as *const u8;
+    x as *const u8
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn return_with_complex_cast() -> *mut u8 {
+    let mut x = 0u8;
+    return &mut x as *mut u8 as *const u8 as *mut u8;
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn with_block() -> *const u8 {
+    let x = 0;
+    &{ x }
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn with_many_blocks() -> *const u8 {
+    let x = 0;
+    {
+        {
+            &{
+                //~^ WARN a dangling pointer will be produced
+                { x }
+            }
+        }
+    }
+}
+
+fn simple_return() -> *const u8 {
+    let x = 0;
+    return &x;
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn return_mut() -> *mut u8 {
+    let mut x = 0;
+    return &mut x;
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn const_and_flow() -> *const u8 {
+    if false {
+        let x = 8;
+        return &x;
+        //~^ WARN a dangling pointer will be produced
+    }
+    &X // not dangling
+}
+
+fn vector<T: Default>() -> *const Vec<T> {
+    let x = vec![T::default()];
+    &x
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn local_adt() -> *const Adt {
+    let x = Adt(5);
+    return &x;
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn closure() -> *const u8 {
+    let _x = || -> *const u8 {
+        let x = 8;
+        return &x;
+        //~^ WARN a dangling pointer will be produced
+    };
+    &X // not dangling
+}
+
+fn fn_ptr() -> *const fn() -> u8 {
+    fn ret_u8() -> u8 {
+        0
+    }
+
+    let x = ret_u8 as fn() -> u8;
+    &x
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn as_arg(a: Adt) -> *const Adt {
+    &a
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn fn_ptr_as_arg(a: fn() -> u8) -> *const fn() -> u8 {
+    &a
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn ptr_as_arg(a: *const Adt) -> *const *const Adt {
+    &a
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn adt_as_arg(a: &Adt) -> *const &Adt {
+    &a
+    //~^ WARN a dangling pointer will be produced
+}
+
+fn unit() -> *const () {
+    let x = ();
+    &x // not dangling
+}
+
+fn zst() -> *const Zst {
+    let x = Zst((), ());
+    &x // not dangling
+}
+
+fn ref_implicit(a: &Adt) -> *const Adt {
+    a // not dangling
+}
+
+fn ref_explicit(a: &Adt) -> *const Adt {
+    &*a // not dangling
+}
+
+fn identity(a: *const Adt) -> *const Adt {
+    a // not dangling
+}
+
+fn from_ref(a: &Adt) -> *const Adt {
+    std::ptr::from_ref(a) // not dangling
+}
+
+fn inner_static() -> *const u8 {
+    static U: u8 = 5;
+    if false {
+        return &U as *const u8; // not dangling
+    }
+    &U // not dangling
+}
+
+fn return_in_closure() {
+    let x = 0;
+    let c = || -> *const u8 {
+        &x // not dangling by it-self
+    };
+}
+
+fn option<T: Default>() -> *const Option<T> {
+    let x = Some(T::default());
+    &x // can't compute layout of `Option<T>`, so cnat' be sure it won't be a ZST
+}
+
+fn generic<T: Default>() -> *const T {
+    let x = T::default();
+    &x // can't compute layout of `T`, so can't be sure it won't be a ZST
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dangling-pointers-from-locals.stderr b/tests/ui/lint/dangling-pointers-from-locals.stderr
new file mode 100644
index 00000000000..e1d28bf22a0
--- /dev/null
+++ b/tests/ui/lint/dangling-pointers-from-locals.stderr
@@ -0,0 +1,247 @@
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:10:5
+   |
+LL | fn simple() -> *const u8 {
+   |                --------- return type of the function is `*const u8`
+LL |     let x = 0;
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     &x
+   |     ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+   = note: `#[warn(dangling_pointers_from_locals)]` on by default
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:17:5
+   |
+LL | fn bindings() -> *const u8 {
+   |                  --------- return type of the function is `*const u8`
+LL |     let x = 0;
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     let x = &x;
+   |             -- dangling pointer created here
+LL |     x
+   |     ^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:24:12
+   |
+LL | fn bindings_with_return() -> *const u8 {
+   |                              --------- return type of the function is `*const u8`
+LL |     let x = 42;
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     let y = &x;
+   |             -- dangling pointer created here
+LL |     return y;
+   |            ^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:30:5
+   |
+LL | fn with_simple_cast() -> *const u8 {
+   |                          --------- return type of the function is `*const u8`
+LL |     let x = 0u8;
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     &x as *const u8
+   |     --^^^^^^^^^^^^^
+   |     |
+   |     dangling pointer created here
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:37:5
+   |
+LL | fn bindings_and_casts() -> *const u8 {
+   |                            --------- return type of the function is `*const u8`
+LL |     let x = 0u8;
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     let x = &x as *const u8;
+   |             -- dangling pointer created here
+LL |     x as *const u8
+   |     ^^^^^^^^^^^^^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:43:12
+   |
+LL | fn return_with_complex_cast() -> *mut u8 {
+   |                                  ------- return type of the function is `*mut u8`
+LL |     let mut x = 0u8;
+   |         ----- `x` is part the function and will be dropped at the end of the function
+LL |     return &mut x as *mut u8 as *const u8 as *mut u8;
+   |            ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            |
+   |            dangling pointer created here
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:49:5
+   |
+LL | fn with_block() -> *const u8 {
+   |                    --------- return type of the function is `*const u8`
+LL |     let x = 0;
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     &{ x }
+   |     ^^^^^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:57:13
+   |
+LL |   fn with_many_blocks() -> *const u8 {
+   |                            --------- return type of the function is `*const u8`
+LL |       let x = 0;
+   |           - `x` is part the function and will be dropped at the end of the function
+...
+LL | /             &{
+LL | |
+LL | |                 { x }
+LL | |             }
+   | |_____________^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:67:12
+   |
+LL | fn simple_return() -> *const u8 {
+   |                       --------- return type of the function is `*const u8`
+LL |     let x = 0;
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     return &x;
+   |            ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:73:12
+   |
+LL | fn return_mut() -> *mut u8 {
+   |                    ------- return type of the function is `*mut u8`
+LL |     let mut x = 0;
+   |         ----- `x` is part the function and will be dropped at the end of the function
+LL |     return &mut x;
+   |            ^^^^^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:80:16
+   |
+LL | fn const_and_flow() -> *const u8 {
+   |                        --------- return type of the function is `*const u8`
+LL |     if false {
+LL |         let x = 8;
+   |             - `x` is part the function and will be dropped at the end of the function
+LL |         return &x;
+   |                ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:88:5
+   |
+LL | fn vector<T: Default>() -> *const Vec<T> {
+   |                            ------------- return type of the function is `*const Vec<T>`
+LL |     let x = vec![T::default()];
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     &x
+   |     ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `Vec<T>` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:94:12
+   |
+LL | fn local_adt() -> *const Adt {
+   |                   ---------- return type of the function is `*const Adt`
+LL |     let x = Adt(5);
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     return &x;
+   |            ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `Adt` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:101:16
+   |
+LL |     let _x = || -> *const u8 {
+   |                    --------- return type of the closure is `*const u8`
+LL |         let x = 8;
+   |             - `x` is part the closure and will be dropped at the end of the closure
+LL |         return &x;
+   |                ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the closure because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `x` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:113:5
+   |
+LL | fn fn_ptr() -> *const fn() -> u8 {
+   |                ----------------- return type of the function is `*const fn() -> u8`
+...
+LL |     let x = ret_u8 as fn() -> u8;
+   |         - `x` is part the function and will be dropped at the end of the function
+LL |     &x
+   |     ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `fn() -> u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `a` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:118:5
+   |
+LL | fn as_arg(a: Adt) -> *const Adt {
+   |           -          ---------- return type of the function is `*const Adt`
+   |           |
+   |           `a` is part the function and will be dropped at the end of the function
+LL |     &a
+   |     ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `Adt` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `a` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:123:5
+   |
+LL | fn fn_ptr_as_arg(a: fn() -> u8) -> *const fn() -> u8 {
+   |                  -                 ----------------- return type of the function is `*const fn() -> u8`
+   |                  |
+   |                  `a` is part the function and will be dropped at the end of the function
+LL |     &a
+   |     ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `fn() -> u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `a` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:128:5
+   |
+LL | fn ptr_as_arg(a: *const Adt) -> *const *const Adt {
+   |               -                 ----------------- return type of the function is `*const *const Adt`
+   |               |
+   |               `a` is part the function and will be dropped at the end of the function
+LL |     &a
+   |     ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `*const Adt` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: a dangling pointer will be produced because the local variable `a` will be dropped
+  --> $DIR/dangling-pointers-from-locals.rs:133:5
+   |
+LL | fn adt_as_arg(a: &Adt) -> *const &Adt {
+   |               -           ----------- return type of the function is `*const &Adt`
+   |               |
+   |               `a` is part the function and will be dropped at the end of the function
+LL |     &a
+   |     ^^
+   |
+   = note: pointers do not have a lifetime; after returning, the `&Adt` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
+
+warning: 19 warnings emitted
+
diff --git a/tests/ui/lint/lint-non-uppercase-usages.stderr b/tests/ui/lint/lint-non-uppercase-usages.stderr
index 7c7e573a88e..b34be31216d 100644
--- a/tests/ui/lint/lint-non-uppercase-usages.stderr
+++ b/tests/ui/lint/lint-non-uppercase-usages.stderr
@@ -29,7 +29,7 @@ warning: const parameter `foo` should have an upper case name
 LL | fn foo<const foo: u32>() {
    |              ^^^
    |
-help: convert the identifier to upper case (notice the capitalization difference)
+help: convert the identifier to upper case (notice the capitalization)
    |
 LL - fn foo<const foo: u32>() {
 LL + fn foo<const FOO: u32>() {
diff --git a/tests/ui/loop-match/const-continue-to-block.rs b/tests/ui/loop-match/const-continue-to-block.rs
index fd7ebeefeb6..a0f60aaec33 100644
--- a/tests/ui/loop-match/const-continue-to-block.rs
+++ b/tests/ui/loop-match/const-continue-to-block.rs
@@ -24,3 +24,24 @@ fn const_continue_to_block() -> u8 {
         }
     }
 }
+
+fn const_continue_to_shadowed_block() -> u8 {
+    let state = 0;
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            match state {
+                0 => {
+                    #[const_continue]
+                    break 'blk 1;
+                }
+                _ => 'blk: {
+                    //~^ WARN label name `'blk` shadows a label name that is already in scope
+                    #[const_continue]
+                    break 'blk 2;
+                    //~^ ERROR `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
+                }
+            }
+        }
+    }
+}
diff --git a/tests/ui/loop-match/const-continue-to-block.stderr b/tests/ui/loop-match/const-continue-to-block.stderr
index 3a5339a0394..f4e223bcff1 100644
--- a/tests/ui/loop-match/const-continue-to-block.stderr
+++ b/tests/ui/loop-match/const-continue-to-block.stderr
@@ -1,8 +1,23 @@
+warning: label name `'blk` shadows a label name that is already in scope
+  --> $DIR/const-continue-to-block.rs:38:22
+   |
+LL |         state = 'blk: {
+   |                 ---- first declared here
+...
+LL |                 _ => 'blk: {
+   |                      ^^^^ label `'blk` already in scope
+
 error: `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
   --> $DIR/const-continue-to-block.rs:20:27
    |
 LL |                     break 'b 2;
    |                           ^^
 
-error: aborting due to 1 previous error
+error: `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
+  --> $DIR/const-continue-to-block.rs:41:27
+   |
+LL |                     break 'blk 2;
+   |                           ^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/loop-match/invalid.rs b/tests/ui/loop-match/invalid.rs
index 0c47b1e0057..08eaf832f56 100644
--- a/tests/ui/loop-match/invalid.rs
+++ b/tests/ui/loop-match/invalid.rs
@@ -142,6 +142,25 @@ fn break_without_value_unit() {
     }
 }
 
+fn break_without_label() {
+    let mut state = State::A;
+    let _ = {
+        #[loop_match]
+        loop {
+            state = 'blk: {
+                match state {
+                    _ => {
+                        #[const_continue]
+                        break State::A;
+                        //~^ ERROR unlabeled `break` inside of a labeled block
+                        //~| ERROR a `#[const_continue]` must break to a label with a value
+                    }
+                }
+            }
+        }
+    };
+}
+
 fn arm_has_guard(cond: bool) {
     let mut state = State::A;
     #[loop_match]
diff --git a/tests/ui/loop-match/invalid.stderr b/tests/ui/loop-match/invalid.stderr
index 70f246caa9c..9e9796a2ea7 100644
--- a/tests/ui/loop-match/invalid.stderr
+++ b/tests/ui/loop-match/invalid.stderr
@@ -9,6 +9,12 @@ help: give the `break` a value of the expected type
 LL |                     break 'blk /* value */;
    |                                +++++++++++
 
+error[E0695]: unlabeled `break` inside of a labeled block
+  --> $DIR/invalid.rs:154:25
+   |
+LL |                         break State::A;
+   |                         ^^^^^^^^^^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label
+
 error: invalid update of the `#[loop_match]` state
   --> $DIR/invalid.rs:18:9
    |
@@ -80,14 +86,20 @@ error: a `#[const_continue]` must break to a label with a value
 LL |                     break 'blk;
    |                     ^^^^^^^^^^
 
+error: a `#[const_continue]` must break to a label with a value
+  --> $DIR/invalid.rs:154:25
+   |
+LL |                         break State::A;
+   |                         ^^^^^^^^^^^^^^
+
 error: match arms that are part of a `#[loop_match]` cannot have guards
-  --> $DIR/invalid.rs:155:29
+  --> $DIR/invalid.rs:174:29
    |
 LL |                 State::B if cond => break 'a,
    |                             ^^^^
 
 error[E0004]: non-exhaustive patterns: `State::B` and `State::C` not covered
-  --> $DIR/invalid.rs:168:19
+  --> $DIR/invalid.rs:187:19
    |
 LL |             match state {
    |                   ^^^^^ patterns `State::B` and `State::C` not covered
@@ -110,12 +122,12 @@ LL ~                 State::B | State::C => todo!(),
    |
 
 error[E0579]: lower range bound must be less than upper
-  --> $DIR/invalid.rs:185:17
+  --> $DIR/invalid.rs:204:17
    |
 LL |                 4.0..3.0 => {
    |                 ^^^^^^^^
 
-error: aborting due to 14 previous errors
+error: aborting due to 16 previous errors
 
-Some errors have detailed explanations: E0004, E0308, E0579.
+Some errors have detailed explanations: E0004, E0308, E0579, E0695.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/macros/builtin-std-paths-fail.stderr b/tests/ui/macros/builtin-std-paths-fail.stderr
index 49034c3987b..85d2bd2132f 100644
--- a/tests/ui/macros/builtin-std-paths-fail.stderr
+++ b/tests/ui/macros/builtin-std-paths-fail.stderr
@@ -104,8 +104,8 @@ LL | #[std::test]
    |
 note: found an item that was configured out
   --> $SRC_DIR/std/src/lib.rs:LL:COL
-note: the item is gated here
-  --> $SRC_DIR/std/src/lib.rs:LL:COL
+   |
+   = note: the item is gated here
 
 error: aborting due to 16 previous errors
 
diff --git a/tests/ui/issues/issue-26093.rs b/tests/ui/macros/invalid-assignment-in-macro-26093.rs
index c838515caf9..686a13a3eec 100644
--- a/tests/ui/issues/issue-26093.rs
+++ b/tests/ui/macros/invalid-assignment-in-macro-26093.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/26093
 macro_rules! not_a_place {
     ($thing:expr) => {
         $thing = 42;
diff --git a/tests/ui/issues/issue-26093.stderr b/tests/ui/macros/invalid-assignment-in-macro-26093.stderr
index 1a08d0fef41..99f188c7183 100644
--- a/tests/ui/issues/issue-26093.stderr
+++ b/tests/ui/macros/invalid-assignment-in-macro-26093.stderr
@@ -1,5 +1,5 @@
 error[E0070]: invalid left-hand side of assignment
-  --> $DIR/issue-26093.rs:3:16
+  --> $DIR/invalid-assignment-in-macro-26093.rs:4:16
    |
 LL |         $thing = 42;
    |                ^
@@ -13,7 +13,7 @@ LL |     not_a_place!(99);
    = note: this error originates in the macro `not_a_place` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0067]: invalid left-hand side of assignment
-  --> $DIR/issue-26093.rs:5:16
+  --> $DIR/invalid-assignment-in-macro-26093.rs:6:16
    |
 LL |         $thing += 42;
    |                ^^
diff --git a/tests/ui/macros/macro-inner-attributes.stderr b/tests/ui/macros/macro-inner-attributes.stderr
index d74b64db5ac..3c043c38abb 100644
--- a/tests/ui/macros/macro-inner-attributes.stderr
+++ b/tests/ui/macros/macro-inner-attributes.stderr
@@ -4,6 +4,13 @@ error[E0433]: failed to resolve: use of unresolved module or unlinked crate `a`
 LL |     a::bar();
    |     ^ use of unresolved module or unlinked crate `a`
    |
+note: found an item that was configured out
+  --> $DIR/macro-inner-attributes.rs:7:7
+   |
+LL | test!(a,
+   |       ^
+LL |       #[cfg(false)],
+   |             ----- the item is gated here
 help: there is a crate or module with a similar name
    |
 LL -     a::bar();
diff --git a/tests/ui/macros/macro-outer-attributes.stderr b/tests/ui/macros/macro-outer-attributes.stderr
index 9215754d4bb..4696bb774e3 100644
--- a/tests/ui/macros/macro-outer-attributes.stderr
+++ b/tests/ui/macros/macro-outer-attributes.stderr
@@ -7,13 +7,10 @@ LL |     a::bar();
 note: found an item that was configured out
   --> $DIR/macro-outer-attributes.rs:9:14
    |
+LL |       #[cfg(false)],
+   |             ----- the item is gated here
 LL |       pub fn bar() { });
    |              ^^^
-note: the item is gated here
-  --> $DIR/macro-outer-attributes.rs:8:13
-   |
-LL |       #[cfg(false)],
-   |             ^^^^^
 help: consider importing this function
    |
 LL + use b::bar;
diff --git a/tests/ui/issues/issue-11844.rs b/tests/ui/match/option-result-mismatch-11844.rs
index f974a470296..24a2004134d 100644
--- a/tests/ui/issues/issue-11844.rs
+++ b/tests/ui/match/option-result-mismatch-11844.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/11844
+
 fn main() {
     let a = Some(Box::new(1));
     match a {
diff --git a/tests/ui/issues/issue-11844.stderr b/tests/ui/match/option-result-mismatch-11844.stderr
index 9ff66eaef49..8a84b7b8a48 100644
--- a/tests/ui/issues/issue-11844.stderr
+++ b/tests/ui/match/option-result-mismatch-11844.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-11844.rs:4:9
+  --> $DIR/option-result-mismatch-11844.rs:6:9
    |
 LL |     match a {
    |           - this expression has type `Option<Box<{integer}>>`
diff --git a/tests/ui/issues/issue-13466.rs b/tests/ui/match/option-result-type-param-mismatch-13466.rs
index 78ce4c1d2f6..05dbdfdee0e 100644
--- a/tests/ui/issues/issue-13466.rs
+++ b/tests/ui/match/option-result-type-param-mismatch-13466.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13466
+
 // Regression test for #13466
 
 //@ dont-require-annotations: NOTE
diff --git a/tests/ui/issues/issue-13466.stderr b/tests/ui/match/option-result-type-param-mismatch-13466.stderr
index 68a555a1626..b0cf1591f5e 100644
--- a/tests/ui/issues/issue-13466.stderr
+++ b/tests/ui/match/option-result-type-param-mismatch-13466.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-13466.rs:10:9
+  --> $DIR/option-result-type-param-mismatch-13466.rs:12:9
    |
 LL |     let _x: usize = match Some(1) {
    |                           ------- this expression has type `Option<{integer}>`
@@ -10,7 +10,7 @@ LL |         Ok(u) => u,
               found enum `Result<_, _>`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-13466.rs:16:9
+  --> $DIR/option-result-type-param-mismatch-13466.rs:18:9
    |
 LL |     let _x: usize = match Some(1) {
    |                           ------- this expression has type `Option<{integer}>`
diff --git a/tests/ui/issues/issue-13027.rs b/tests/ui/match/overeager-sub-match-pruning-13027.rs
index fbd1d75067b..c4feb697f7d 100644
--- a/tests/ui/issues/issue-13027.rs
+++ b/tests/ui/match/overeager-sub-match-pruning-13027.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13027
+
 //@ run-pass
 
 // Tests that match expression handles overlapped literal and range
diff --git a/tests/ui/issues/issue-12567.rs b/tests/ui/match/slice-move-out-error-12567.rs
index 1b2a37de475..3f9bf9c76cf 100644
--- a/tests/ui/issues/issue-12567.rs
+++ b/tests/ui/match/slice-move-out-error-12567.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12567
+
 fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) {
     match (l1, l2) {
     //~^ ERROR: cannot move out of type `[T]`, a non-copy slice
diff --git a/tests/ui/issues/issue-12567.stderr b/tests/ui/match/slice-move-out-error-12567.stderr
index 0b19299ece3..ab5377d4701 100644
--- a/tests/ui/issues/issue-12567.stderr
+++ b/tests/ui/match/slice-move-out-error-12567.stderr
@@ -1,5 +1,5 @@
 error[E0508]: cannot move out of type `[T]`, a non-copy slice
-  --> $DIR/issue-12567.rs:2:11
+  --> $DIR/slice-move-out-error-12567.rs:4:11
    |
 LL |     match (l1, l2) {
    |           ^^^^^^^^ cannot move out of here
@@ -23,7 +23,7 @@ LL +         (&[hd1, ..], [hd2, ..])
    |
 
 error[E0508]: cannot move out of type `[T]`, a non-copy slice
-  --> $DIR/issue-12567.rs:2:11
+  --> $DIR/slice-move-out-error-12567.rs:4:11
    |
 LL |     match (l1, l2) {
    |           ^^^^^^^^ cannot move out of here
diff --git a/tests/ui/issues/issue-12285.rs b/tests/ui/match/struct-reference-patterns-12285.rs
index fe199147128..246e230b0de 100644
--- a/tests/ui/issues/issue-12285.rs
+++ b/tests/ui/match/struct-reference-patterns-12285.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12285
+
 //@ run-pass
 
 struct S;
diff --git a/tests/ui/issues/issue-12920.rs b/tests/ui/parser/encode-symbol-ice-12920.rs
index f3b1b643c45..87389c0ffb4 100644
--- a/tests/ui/issues/issue-12920.rs
+++ b/tests/ui/parser/encode-symbol-ice-12920.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12920
+
 //@ run-fail
 //@ error-pattern:explicit panic
 //@ needs-subprocess
diff --git a/tests/ui/parser/item-kw-case-mismatch.stderr b/tests/ui/parser/item-kw-case-mismatch.stderr
index df39eb10fdb..d2a1eb7f2f5 100644
--- a/tests/ui/parser/item-kw-case-mismatch.stderr
+++ b/tests/ui/parser/item-kw-case-mismatch.stderr
@@ -4,7 +4,7 @@ error: keyword `use` is written in the wrong case
 LL | Use std::ptr::read;
    | ^^^
    |
-help: write it in the correct case (notice the capitalization difference)
+help: write it in the correct case (notice the capitalization)
    |
 LL - Use std::ptr::read;
 LL + use std::ptr::read;
@@ -28,7 +28,7 @@ error: keyword `fn` is written in the wrong case
 LL | async Fn _a() {}
    |       ^^
    |
-help: write it in the correct case (notice the capitalization difference)
+help: write it in the correct case (notice the capitalization)
    |
 LL - async Fn _a() {}
 LL + async fn _a() {}
@@ -40,7 +40,7 @@ error: keyword `fn` is written in the wrong case
 LL | Fn _b() {}
    | ^^
    |
-help: write it in the correct case (notice the capitalization difference)
+help: write it in the correct case (notice the capitalization)
    |
 LL - Fn _b() {}
 LL + fn _b() {}
diff --git a/tests/ui/parser/kw-in-trait-bounds.stderr b/tests/ui/parser/kw-in-trait-bounds.stderr
index 1892d0b6226..5a4adf3e37b 100644
--- a/tests/ui/parser/kw-in-trait-bounds.stderr
+++ b/tests/ui/parser/kw-in-trait-bounds.stderr
@@ -4,7 +4,7 @@ error: expected identifier, found keyword `fn`
 LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
    |          ^^
    |
-help: use `Fn` to refer to the trait (notice the capitalization difference)
+help: use `Fn` to refer to the trait (notice the capitalization)
    |
 LL - fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
 LL + fn _f<F: Fn(), G>(_: impl fn(), _: &dyn fn())
@@ -16,7 +16,7 @@ error: expected identifier, found keyword `fn`
 LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
    |                           ^^
    |
-help: use `Fn` to refer to the trait (notice the capitalization difference)
+help: use `Fn` to refer to the trait (notice the capitalization)
    |
 LL - fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
 LL + fn _f<F: fn(), G>(_: impl Fn(), _: &dyn fn())
@@ -28,7 +28,7 @@ error: expected identifier, found keyword `fn`
 LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
    |                                         ^^
    |
-help: use `Fn` to refer to the trait (notice the capitalization difference)
+help: use `Fn` to refer to the trait (notice the capitalization)
    |
 LL - fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
 LL + fn _f<F: fn(), G>(_: impl fn(), _: &dyn Fn())
@@ -40,7 +40,7 @@ error: expected identifier, found keyword `fn`
 LL | G: fn(),
    |    ^^
    |
-help: use `Fn` to refer to the trait (notice the capitalization difference)
+help: use `Fn` to refer to the trait (notice the capitalization)
    |
 LL - G: fn(),
 LL + G: Fn(),
diff --git a/tests/ui/parser/misspelled-keywords/hrdt.stderr b/tests/ui/parser/misspelled-keywords/hrdt.stderr
index e5fc1a50382..497bd613bf4 100644
--- a/tests/ui/parser/misspelled-keywords/hrdt.stderr
+++ b/tests/ui/parser/misspelled-keywords/hrdt.stderr
@@ -4,7 +4,7 @@ error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found keyword
 LL |     Where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
    |           ^^^ expected one of 7 possible tokens
    |
-help: write keyword `where` in lowercase (notice the capitalization difference)
+help: write keyword `where` in lowercase (notice the capitalization)
    |
 LL -     Where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
 LL +     where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
diff --git a/tests/ui/parser/misspelled-keywords/impl-return.stderr b/tests/ui/parser/misspelled-keywords/impl-return.stderr
index ff5391461a9..d49d962d7e9 100644
--- a/tests/ui/parser/misspelled-keywords/impl-return.stderr
+++ b/tests/ui/parser/misspelled-keywords/impl-return.stderr
@@ -4,7 +4,7 @@ error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `Display
 LL | fn code() -> Impl Display {}
    |                   ^^^^^^^ expected one of 7 possible tokens
    |
-help: write keyword `impl` in lowercase (notice the capitalization difference)
+help: write keyword `impl` in lowercase (notice the capitalization)
    |
 LL - fn code() -> Impl Display {}
 LL + fn code() -> impl Display {}
diff --git a/tests/ui/parser/misspelled-keywords/static.stderr b/tests/ui/parser/misspelled-keywords/static.stderr
index e559f2be109..0df40bcdc33 100644
--- a/tests/ui/parser/misspelled-keywords/static.stderr
+++ b/tests/ui/parser/misspelled-keywords/static.stderr
@@ -4,7 +4,7 @@ error: expected one of `!` or `::`, found `a`
 LL | Static a = 0;
    |        ^ expected one of `!` or `::`
    |
-help: write keyword `static` in lowercase (notice the capitalization difference)
+help: write keyword `static` in lowercase (notice the capitalization)
    |
 LL - Static a = 0;
 LL + static a = 0;
diff --git a/tests/ui/parser/misspelled-keywords/struct.stderr b/tests/ui/parser/misspelled-keywords/struct.stderr
index edbec3b9456..af8614ef14b 100644
--- a/tests/ui/parser/misspelled-keywords/struct.stderr
+++ b/tests/ui/parser/misspelled-keywords/struct.stderr
@@ -4,7 +4,7 @@ error: expected one of `!` or `::`, found `Foor`
 LL | Struct Foor {
    |        ^^^^ expected one of `!` or `::`
    |
-help: write keyword `struct` in lowercase (notice the capitalization difference)
+help: write keyword `struct` in lowercase (notice the capitalization)
    |
 LL - Struct Foor {
 LL + struct Foor {
diff --git a/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
index 4e1fcaf4936..bd809e77a8f 100644
--- a/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
+++ b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
@@ -4,7 +4,7 @@ error: expected identifier, found keyword `fn`
 LL | fn foo(_: impl fn() -> i32) {}
    |                ^^
    |
-help: use `Fn` to refer to the trait (notice the capitalization difference)
+help: use `Fn` to refer to the trait (notice the capitalization)
    |
 LL - fn foo(_: impl fn() -> i32) {}
 LL + fn foo(_: impl Fn() -> i32) {}
@@ -16,7 +16,7 @@ error: expected identifier, found keyword `fn`
 LL | fn foo2<T: fn(i32)>(_: T) {}
    |            ^^
    |
-help: use `Fn` to refer to the trait (notice the capitalization difference)
+help: use `Fn` to refer to the trait (notice the capitalization)
    |
 LL - fn foo2<T: fn(i32)>(_: T) {}
 LL + fn foo2<T: Fn(i32)>(_: T) {}
diff --git a/tests/ui/parser/typod-const-in-const-param-def.stderr b/tests/ui/parser/typod-const-in-const-param-def.stderr
index bf7168a0157..cc1600fe5cb 100644
--- a/tests/ui/parser/typod-const-in-const-param-def.stderr
+++ b/tests/ui/parser/typod-const-in-const-param-def.stderr
@@ -4,7 +4,7 @@ error: `const` keyword was mistyped as `Const`
 LL | pub fn foo<Const N: u8>() {}
    |            ^^^^^
    |
-help: use the `const` keyword (notice the capitalization difference)
+help: use the `const` keyword (notice the capitalization)
    |
 LL - pub fn foo<Const N: u8>() {}
 LL + pub fn foo<const N: u8>() {}
@@ -16,7 +16,7 @@ error: `const` keyword was mistyped as `Const`
 LL | pub fn baz<Const N: u8, T>() {}
    |            ^^^^^
    |
-help: use the `const` keyword (notice the capitalization difference)
+help: use the `const` keyword (notice the capitalization)
    |
 LL - pub fn baz<Const N: u8, T>() {}
 LL + pub fn baz<const N: u8, T>() {}
@@ -28,7 +28,7 @@ error: `const` keyword was mistyped as `Const`
 LL | pub fn qux<T, Const N: u8>() {}
    |               ^^^^^
    |
-help: use the `const` keyword (notice the capitalization difference)
+help: use the `const` keyword (notice the capitalization)
    |
 LL - pub fn qux<T, Const N: u8>() {}
 LL + pub fn qux<T, const N: u8>() {}
@@ -40,7 +40,7 @@ error: `const` keyword was mistyped as `Const`
 LL | pub fn quux<T, Const N: u8, U>() {}
    |                ^^^^^
    |
-help: use the `const` keyword (notice the capitalization difference)
+help: use the `const` keyword (notice the capitalization)
    |
 LL - pub fn quux<T, Const N: u8, U>() {}
 LL + pub fn quux<T, const N: u8, U>() {}
diff --git a/tests/ui/issues/issue-7519-match-unit-in-arg.rs b/tests/ui/pattern/unit-pattern-matching-in-function-argument-7519.rs
index a7cea577b22..7bfa9ee6625 100644
--- a/tests/ui/issues/issue-7519-match-unit-in-arg.rs
+++ b/tests/ui/pattern/unit-pattern-matching-in-function-argument-7519.rs
@@ -2,6 +2,7 @@
 
 /*
 #7519 ICE pattern matching unit in function argument
+https://github.com/rust-lang/rust/issues/7519
 */
 
 fn foo(():()) { }
diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr
index 86f6be85a07..edcffaf6b70 100644
--- a/tests/ui/privacy/private-in-public-warn.stderr
+++ b/tests/ui/privacy/private-in-public-warn.stderr
@@ -93,6 +93,42 @@ LL |     struct Priv;
 LL |         type Alias = Priv;
    |         ^^^^^^^^^^ can't leak private type
 
+error: type `types::Priv` is more private than the item `types::ES`
+  --> $DIR/private-in-public-warn.rs:27:9
+   |
+LL |         pub static ES: Priv;
+   |         ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
+
+error: type `types::Priv` is more private than the item `types::ef1`
+  --> $DIR/private-in-public-warn.rs:28:9
+   |
+LL |         pub fn ef1(arg: Priv);
+   |         ^^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
+
+error: type `types::Priv` is more private than the item `types::ef2`
+  --> $DIR/private-in-public-warn.rs:29:9
+   |
+LL |         pub fn ef2() -> Priv;
+   |         ^^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
+
 error: trait `traits::PrivTr` is more private than the item `traits::Alias`
   --> $DIR/private-in-public-warn.rs:42:5
    |
@@ -359,42 +395,6 @@ note: but type `Priv2` is only usable at visibility `pub(self)`
 LL |     struct Priv2;
    |     ^^^^^^^^^^^^
 
-error: type `types::Priv` is more private than the item `types::ES`
-  --> $DIR/private-in-public-warn.rs:27:9
-   |
-LL |         pub static ES: Priv;
-   |         ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
-   |
-note: but type `types::Priv` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:9:5
-   |
-LL |     struct Priv;
-   |     ^^^^^^^^^^^
-
-error: type `types::Priv` is more private than the item `types::ef1`
-  --> $DIR/private-in-public-warn.rs:28:9
-   |
-LL |         pub fn ef1(arg: Priv);
-   |         ^^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
-   |
-note: but type `types::Priv` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:9:5
-   |
-LL |     struct Priv;
-   |     ^^^^^^^^^^^
-
-error: type `types::Priv` is more private than the item `types::ef2`
-  --> $DIR/private-in-public-warn.rs:29:9
-   |
-LL |         pub fn ef2() -> Priv;
-   |         ^^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
-   |
-note: but type `types::Priv` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:9:5
-   |
-LL |     struct Priv;
-   |     ^^^^^^^^^^^
-
 warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/private-in-public-warn.rs:42:23
    |
diff --git a/tests/ui/issues/issue-13407.rs b/tests/ui/privacy/private-unit-struct-assignment.rs
index 7794be37b85..b8e1c4ecb18 100644
--- a/tests/ui/issues/issue-13407.rs
+++ b/tests/ui/privacy/private-unit-struct-assignment.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13407
+
 mod A {
     struct C;
 }
diff --git a/tests/ui/issues/issue-13407.stderr b/tests/ui/privacy/private-unit-struct-assignment.stderr
index ac2eb6581fe..8c36a08846d 100644
--- a/tests/ui/issues/issue-13407.stderr
+++ b/tests/ui/privacy/private-unit-struct-assignment.stderr
@@ -1,17 +1,17 @@
 error[E0603]: unit struct `C` is private
-  --> $DIR/issue-13407.rs:6:8
+  --> $DIR/private-unit-struct-assignment.rs:8:8
    |
 LL |     A::C = 1;
    |        ^ private unit struct
    |
 note: the unit struct `C` is defined here
-  --> $DIR/issue-13407.rs:2:5
+  --> $DIR/private-unit-struct-assignment.rs:4:5
    |
 LL |     struct C;
    |     ^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/issue-13407.rs:6:5
+  --> $DIR/private-unit-struct-assignment.rs:8:5
    |
 LL |     struct C;
    |     -------- unit struct defined here
diff --git a/tests/ui/privacy/projections.stderr b/tests/ui/privacy/projections.stderr
index 010d77998e3..addb6a075a2 100644
--- a/tests/ui/privacy/projections.stderr
+++ b/tests/ui/privacy/projections.stderr
@@ -1,16 +1,3 @@
-warning: type `Priv` is more private than the item `Leak`
-  --> $DIR/projections.rs:3:5
-   |
-LL |     pub type Leak = Priv;
-   |     ^^^^^^^^^^^^^ type alias `Leak` is reachable at visibility `pub(crate)`
-   |
-note: but type `Priv` is only usable at visibility `pub(self)`
-  --> $DIR/projections.rs:2:5
-   |
-LL |     struct Priv;
-   |     ^^^^^^^^^^^
-   = note: `#[warn(private_interfaces)]` on by default
-
 error[E0446]: private type `Priv` in public interface
   --> $DIR/projections.rs:24:5
    |
@@ -29,6 +16,19 @@ LL |     struct Priv;
 LL |     type A<T: Trait> = T::A<m::Leak>;
    |     ^^^^^^^^^^^^^^^^ can't leak private type
 
+warning: type `Priv` is more private than the item `Leak`
+  --> $DIR/projections.rs:3:5
+   |
+LL |     pub type Leak = Priv;
+   |     ^^^^^^^^^^^^^ type alias `Leak` is reachable at visibility `pub(crate)`
+   |
+note: but type `Priv` is only usable at visibility `pub(self)`
+  --> $DIR/projections.rs:2:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
+
 error: type `Priv` is private
   --> $DIR/projections.rs:14:15
    |
diff --git a/tests/ui/issues/issue-12729.rs b/tests/ui/privacy/use-in-impl-scope-12729.rs
index 4d45846bc60..58fe042beec 100644
--- a/tests/ui/issues/issue-12729.rs
+++ b/tests/ui/privacy/use-in-impl-scope-12729.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12729
+
 //@ edition: 2015
 //@ check-pass
 #![allow(dead_code)]
diff --git a/tests/ui/issues/issue-11820.rs b/tests/ui/resolve/reference-clone-nonclone-11820.rs
index ada844f8ee1..74dad96da94 100644
--- a/tests/ui/issues/issue-11820.rs
+++ b/tests/ui/resolve/reference-clone-nonclone-11820.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/11820
+
 //@ run-pass
 
 #![allow(noop_method_call)]
diff --git a/tests/ui/rustdoc/cfg-rustdoc.rs b/tests/ui/rustdoc/cfg-rustdoc.rs
index dd8e1ed97c4..11c48d07552 100644
--- a/tests/ui/rustdoc/cfg-rustdoc.rs
+++ b/tests/ui/rustdoc/cfg-rustdoc.rs
@@ -1,6 +1,7 @@
-#[cfg(doc)]
-pub struct Foo;
+#[cfg(doc)] //~ NOTE the item is gated here
+pub struct Foo; //~ NOTE found an item that was configured out
 
 fn main() {
-    let f = Foo; //~ ERROR
+    let f = Foo; //~ ERROR cannot find value `Foo` in this scope
+    //~^ NOTE not found in this scope
 }
diff --git a/tests/ui/rustdoc/cfg-rustdoc.stderr b/tests/ui/rustdoc/cfg-rustdoc.stderr
index 340a8e22482..0e8a5dfea61 100644
--- a/tests/ui/rustdoc/cfg-rustdoc.stderr
+++ b/tests/ui/rustdoc/cfg-rustdoc.stderr
@@ -3,6 +3,14 @@ error[E0425]: cannot find value `Foo` in this scope
    |
 LL |     let f = Foo;
    |             ^^^ not found in this scope
+   |
+note: found an item that was configured out
+  --> $DIR/cfg-rustdoc.rs:2:12
+   |
+LL | #[cfg(doc)]
+   |       --- the item is gated here
+LL | pub struct Foo;
+   |            ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-13214.rs b/tests/ui/statics/enum-with-static-str-variant-13214.rs
index 8140ec943a0..1db37da632d 100644
--- a/tests/ui/issues/issue-13214.rs
+++ b/tests/ui/statics/enum-with-static-str-variant-13214.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13214
+
 //@ build-pass
 #![allow(dead_code)]
 // defining static with struct that contains enum
diff --git a/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr b/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
index 6d6fd983038..47efe69cfc2 100644
--- a/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
+++ b/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
@@ -8,7 +8,7 @@ LL |     let x: i32 = MyS::foo;
    |
    = note: expected type `i32`
            found fn item `fn() -> MyS {MyS::foo}`
-help: try referring to the associated const `FOO` instead (notice the capitalization difference)
+help: try referring to the associated const `FOO` instead (notice the capitalization)
    |
 LL -     let x: i32 = MyS::foo;
 LL +     let x: i32 = MyS::FOO;
diff --git a/tests/ui/suggestions/bool_typo_err_suggest.stderr b/tests/ui/suggestions/bool_typo_err_suggest.stderr
index faf799d0fda..d46ce1ad8a9 100644
--- a/tests/ui/suggestions/bool_typo_err_suggest.stderr
+++ b/tests/ui/suggestions/bool_typo_err_suggest.stderr
@@ -16,7 +16,7 @@ error[E0425]: cannot find value `False` in this scope
 LL |     let y = False;
    |             ^^^^^ not found in this scope
    |
-help: you may want to use a bool value instead (notice the capitalization difference)
+help: you may want to use a bool value instead (notice the capitalization)
    |
 LL -     let y = False;
 LL +     let y = false;
diff --git a/tests/ui/suggestions/case-difference-suggestions.rs b/tests/ui/suggestions/case-difference-suggestions.rs
new file mode 100644
index 00000000000..d554b6e9367
--- /dev/null
+++ b/tests/ui/suggestions/case-difference-suggestions.rs
@@ -0,0 +1,57 @@
+fn main() {
+
+    // Simple case difference, no hit
+    let hello = "hello";
+    println!("{}", Hello); //~ ERROR cannot find value `Hello` in this scope
+
+    // Multiple case differences, hit
+    let myVariable = 10;
+    println!("{}", myvariable); //~ ERROR cannot find value `myvariable` in this scope
+
+    // Case difference with special characters, hit
+    let user_name = "john";
+    println!("{}", User_Name); //~ ERROR cannot find value `User_Name` in this scope
+
+    // All uppercase vs all lowercase, hit
+    let FOO = 42;
+    println!("{}", foo); //~ ERROR cannot find value `foo` in this scope
+
+
+    // 0 vs O
+    let FFO0 = 100;
+    println!("{}", FFOO); //~ ERROR cannot find value `FFOO` in this scope
+
+    let l1st = vec![1, 2, 3];
+    println!("{}", list); //~ ERROR cannot find value `list` in this scope
+
+    let S5 = "test";
+    println!("{}", SS); //~ ERROR cannot find value `SS` in this scope
+
+    let aS5 = "test";
+    println!("{}", a55); //~ ERROR cannot find value `a55` in this scope
+
+    let B8 = 8;
+    println!("{}", BB); //~ ERROR cannot find value `BB` in this scope
+
+    let g9 = 9;
+    println!("{}", gg); //~ ERROR cannot find value `gg` in this scope
+
+    let o1d = "old";
+    println!("{}", old); //~ ERROR cannot find value `old` in this scope
+
+    let new1 = "new";
+    println!("{}", newl); //~ ERROR cannot find value `newl` in this scope
+
+    let apple = "apple";
+    println!("{}", app1e); //~ ERROR cannot find value `app1e` in this scope
+
+    let a = 1;
+    println!("{}", A); //~ ERROR cannot find value `A` in this scope
+
+    let worldlu = "world";
+    println!("{}", world1U); //~ ERROR cannot find value `world1U` in this scope
+
+    let myV4rlable = 42;
+    println!("{}", myv4r1able); //~ ERROR cannot find value `myv4r1able` in this scope
+
+}
diff --git a/tests/ui/suggestions/case-difference-suggestions.stderr b/tests/ui/suggestions/case-difference-suggestions.stderr
new file mode 100644
index 00000000000..c3d2410a6eb
--- /dev/null
+++ b/tests/ui/suggestions/case-difference-suggestions.stderr
@@ -0,0 +1,99 @@
+error[E0425]: cannot find value `Hello` in this scope
+  --> $DIR/case-difference-suggestions.rs:5:20
+   |
+LL |     println!("{}", Hello);
+   |                    ^^^^^ help: a local variable with a similar name exists: `hello`
+
+error[E0425]: cannot find value `myvariable` in this scope
+  --> $DIR/case-difference-suggestions.rs:9:20
+   |
+LL |     println!("{}", myvariable);
+   |                    ^^^^^^^^^^ help: a local variable with a similar name exists (notice the capitalization): `myVariable`
+
+error[E0425]: cannot find value `User_Name` in this scope
+  --> $DIR/case-difference-suggestions.rs:13:20
+   |
+LL |     println!("{}", User_Name);
+   |                    ^^^^^^^^^ help: a local variable with a similar name exists: `user_name`
+
+error[E0425]: cannot find value `foo` in this scope
+  --> $DIR/case-difference-suggestions.rs:17:20
+   |
+LL |     println!("{}", foo);
+   |                    ^^^ help: a local variable with a similar name exists (notice the capitalization): `FOO`
+
+error[E0425]: cannot find value `FFOO` in this scope
+  --> $DIR/case-difference-suggestions.rs:22:20
+   |
+LL |     println!("{}", FFOO);
+   |                    ^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `FFO0`
+
+error[E0425]: cannot find value `list` in this scope
+  --> $DIR/case-difference-suggestions.rs:25:20
+   |
+LL |     println!("{}", list);
+   |                    ^^^^ help: a local variable with a similar name exists: `l1st`
+
+error[E0425]: cannot find value `SS` in this scope
+  --> $DIR/case-difference-suggestions.rs:28:20
+   |
+LL |     println!("{}", SS);
+   |                    ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `S5`
+
+error[E0425]: cannot find value `a55` in this scope
+  --> $DIR/case-difference-suggestions.rs:31:20
+   |
+LL |     println!("{}", a55);
+   |                    ^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `aS5`
+
+error[E0425]: cannot find value `BB` in this scope
+  --> $DIR/case-difference-suggestions.rs:34:20
+   |
+LL |     println!("{}", BB);
+   |                    ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `B8`
+
+error[E0425]: cannot find value `gg` in this scope
+  --> $DIR/case-difference-suggestions.rs:37:20
+   |
+LL |     println!("{}", gg);
+   |                    ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `g9`
+
+error[E0425]: cannot find value `old` in this scope
+  --> $DIR/case-difference-suggestions.rs:40:20
+   |
+LL |     println!("{}", old);
+   |                    ^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `o1d`
+
+error[E0425]: cannot find value `newl` in this scope
+  --> $DIR/case-difference-suggestions.rs:43:20
+   |
+LL |     println!("{}", newl);
+   |                    ^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `new1`
+
+error[E0425]: cannot find value `app1e` in this scope
+  --> $DIR/case-difference-suggestions.rs:46:20
+   |
+LL |     println!("{}", app1e);
+   |                    ^^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `apple`
+
+error[E0425]: cannot find value `A` in this scope
+  --> $DIR/case-difference-suggestions.rs:49:20
+   |
+LL |     println!("{}", A);
+   |                    ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `world1U` in this scope
+  --> $DIR/case-difference-suggestions.rs:52:20
+   |
+LL |     println!("{}", world1U);
+   |                    ^^^^^^^ help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion): `worldlu`
+
+error[E0425]: cannot find value `myv4r1able` in this scope
+  --> $DIR/case-difference-suggestions.rs:55:20
+   |
+LL |     println!("{}", myv4r1able);
+   |                    ^^^^^^^^^^ help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion): `myV4rlable`
+
+error: aborting due to 16 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/suggestions/incorrect-variant-literal.svg b/tests/ui/suggestions/incorrect-variant-literal.svg
index 279fd30f216..2cab1f4b60f 100644
--- a/tests/ui/suggestions/incorrect-variant-literal.svg
+++ b/tests/ui/suggestions/incorrect-variant-literal.svg
@@ -455,7 +455,7 @@
 </tspan>
     <tspan x="10px" y="3916px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="3934px"><tspan class="fg-ansi256-014 bold">help</tspan><tspan>: there is a variant with a similar name (notice the capitalization difference)</tspan>
+    <tspan x="10px" y="3934px"><tspan class="fg-ansi256-014 bold">help</tspan><tspan>: there is a variant with a similar name (notice the capitalization)</tspan>
 </tspan>
     <tspan x="10px" y="3952px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/threads-sendsync/tcp-stress.rs b/tests/ui/threads-sendsync/tcp-stress.rs
deleted file mode 100644
index b2f76a55fb9..00000000000
--- a/tests/ui/threads-sendsync/tcp-stress.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-//@ run-pass
-//@ ignore-android needs extra network permissions
-//@ needs-threads
-//@ ignore-netbsd system ulimit (Too many open files)
-//@ ignore-openbsd system ulimit (Too many open files)
-
-use std::io::prelude::*;
-use std::net::{TcpListener, TcpStream};
-use std::process;
-use std::sync::mpsc::channel;
-use std::thread::{self, Builder};
-use std::time::Duration;
-
-const TARGET_CNT: usize = 200;
-
-fn main() {
-    // This test has a chance to time out, try to not let it time out
-    thread::spawn(move || -> () {
-        thread::sleep(Duration::from_secs(30));
-        process::exit(1);
-    });
-
-    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
-    let addr = listener.local_addr().unwrap();
-    thread::spawn(move || -> () {
-        loop {
-            let mut stream = match listener.accept() {
-                Ok(stream) => stream.0,
-                Err(_) => continue,
-            };
-            let _ = stream.read(&mut [0]);
-            let _ = stream.write(&[2]);
-        }
-    });
-
-    let (tx, rx) = channel();
-
-    let mut spawned_cnt = 0;
-    for _ in 0..TARGET_CNT {
-        let tx = tx.clone();
-        let res = Builder::new().stack_size(64 * 1024).spawn(move || {
-            match TcpStream::connect(addr) {
-                Ok(mut stream) => {
-                    let _ = stream.write(&[1]);
-                    let _ = stream.read(&mut [0]);
-                }
-                Err(..) => {}
-            }
-            tx.send(()).unwrap();
-        });
-        if let Ok(_) = res {
-            spawned_cnt += 1;
-        };
-    }
-
-    // Wait for all clients to exit, but don't wait for the server to exit. The
-    // server just runs infinitely.
-    drop(tx);
-    for _ in 0..spawned_cnt {
-        rx.recv().unwrap();
-    }
-    assert_eq!(spawned_cnt, TARGET_CNT);
-    process::exit(0);
-}
diff --git a/tests/ui/traits/const-traits/conditionally-const-in-anon-const.rs b/tests/ui/traits/const-traits/conditionally-const-in-anon-const.rs
new file mode 100644
index 00000000000..5aebcceb7c7
--- /dev/null
+++ b/tests/ui/traits/const-traits/conditionally-const-in-anon-const.rs
@@ -0,0 +1,28 @@
+#![feature(const_trait_impl, impl_trait_in_bindings)]
+
+struct S;
+#[const_trait]
+trait Trait<const N: u32> {}
+
+impl const Trait<0> for () {}
+
+const fn f<
+    T: Trait<
+        {
+            const fn g<U: [const] Trait<0>>() {}
+
+            struct I<U: [const] Trait<0>>(U);
+            //~^ ERROR `[const]` is not allowed here
+
+            let x: &impl [const] Trait<0> = &();
+            //~^ ERROR `[const]` is not allowed here
+
+            0
+        },
+    >,
+>(x: &T) {
+    // Should be allowed here
+    let y: &impl [const] Trait<0> = x;
+}
+
+pub fn main() {}
diff --git a/tests/ui/traits/const-traits/conditionally-const-in-anon-const.stderr b/tests/ui/traits/const-traits/conditionally-const-in-anon-const.stderr
new file mode 100644
index 00000000000..c6be249b95a
--- /dev/null
+++ b/tests/ui/traits/const-traits/conditionally-const-in-anon-const.stderr
@@ -0,0 +1,32 @@
+error: `[const]` is not allowed here
+  --> $DIR/conditionally-const-in-anon-const.rs:14:25
+   |
+LL |             struct I<U: [const] Trait<0>>(U);
+   |                         ^^^^^^^
+   |
+note: structs cannot have `[const]` trait bounds
+  --> $DIR/conditionally-const-in-anon-const.rs:14:13
+   |
+LL |             struct I<U: [const] Trait<0>>(U);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `[const]` is not allowed here
+  --> $DIR/conditionally-const-in-anon-const.rs:17:26
+   |
+LL |             let x: &impl [const] Trait<0> = &();
+   |                          ^^^^^^^
+   |
+note: anonymous constants cannot have `[const]` trait bounds
+  --> $DIR/conditionally-const-in-anon-const.rs:11:9
+   |
+LL | /         {
+LL | |             const fn g<U: [const] Trait<0>>() {}
+LL | |
+LL | |             struct I<U: [const] Trait<0>>(U);
+...  |
+LL | |             0
+LL | |         },
+   | |_________^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/const-traits/conditionally-const-in-struct-args.rs b/tests/ui/traits/const-traits/conditionally-const-in-struct-args.rs
deleted file mode 100644
index 0c644694585..00000000000
--- a/tests/ui/traits/const-traits/conditionally-const-in-struct-args.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//@ compile-flags: -Znext-solver
-//@ known-bug: #132067
-//@ check-pass
-
-#![feature(const_trait_impl)]
-
-struct S;
-#[const_trait]
-trait Trait<const N: u32> {}
-
-const fn f<
-    T: Trait<
-        {
-            struct I<U: [const] Trait<0>>(U);
-            0
-        },
-    >,
->() {
-}
-
-pub fn main() {}
diff --git a/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr b/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr
index 010b1584643..5c3bb236967 100644
--- a/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr
+++ b/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr
@@ -16,7 +16,11 @@ error: `[const]` is not allowed here
 LL | struct Struct<T: [const] Trait> { field: T }
    |                  ^^^^^^^
    |
-   = note: this item cannot have `[const]` trait bounds
+note: structs cannot have `[const]` trait bounds
+  --> $DIR/conditionally-const-invalid-places.rs:9:1
+   |
+LL | struct Struct<T: [const] Trait> { field: T }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `[const]` is not allowed here
   --> $DIR/conditionally-const-invalid-places.rs:10:23
@@ -24,7 +28,11 @@ error: `[const]` is not allowed here
 LL | struct TupleStruct<T: [const] Trait>(T);
    |                       ^^^^^^^
    |
-   = note: this item cannot have `[const]` trait bounds
+note: structs cannot have `[const]` trait bounds
+  --> $DIR/conditionally-const-invalid-places.rs:10:1
+   |
+LL | struct TupleStruct<T: [const] Trait>(T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `[const]` is not allowed here
   --> $DIR/conditionally-const-invalid-places.rs:11:22
@@ -32,7 +40,11 @@ error: `[const]` is not allowed here
 LL | struct UnitStruct<T: [const] Trait>;
    |                      ^^^^^^^
    |
-   = note: this item cannot have `[const]` trait bounds
+note: structs cannot have `[const]` trait bounds
+  --> $DIR/conditionally-const-invalid-places.rs:11:1
+   |
+LL | struct UnitStruct<T: [const] Trait>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `[const]` is not allowed here
   --> $DIR/conditionally-const-invalid-places.rs:14:14
@@ -40,7 +52,11 @@ error: `[const]` is not allowed here
 LL | enum Enum<T: [const] Trait> { Variant(T) }
    |              ^^^^^^^
    |
-   = note: this item cannot have `[const]` trait bounds
+note: enums cannot have `[const]` trait bounds
+  --> $DIR/conditionally-const-invalid-places.rs:14:1
+   |
+LL | enum Enum<T: [const] Trait> { Variant(T) }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `[const]` is not allowed here
   --> $DIR/conditionally-const-invalid-places.rs:16:16
@@ -48,7 +64,11 @@ error: `[const]` is not allowed here
 LL | union Union<T: [const] Trait> { field: T }
    |                ^^^^^^^
    |
-   = note: this item cannot have `[const]` trait bounds
+note: unions cannot have `[const]` trait bounds
+  --> $DIR/conditionally-const-invalid-places.rs:16:1
+   |
+LL | union Union<T: [const] Trait> { field: T }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `[const]` is not allowed here
   --> $DIR/conditionally-const-invalid-places.rs:19:14
diff --git a/tests/ui/issues/issue-13204.rs b/tests/ui/traits/default-method-lifetime-params-13204.rs
index 01362f6fe61..cdf34ab773c 100644
--- a/tests/ui/issues/issue-13204.rs
+++ b/tests/ui/traits/default-method-lifetime-params-13204.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13204
+
 //@ run-pass
 #![allow(unused_mut)]
 // Test that when instantiating trait default methods, typeck handles
diff --git a/tests/ui/issues/issue-13434.rs b/tests/ui/traits/fnonce-repro-trait-impl-13434.rs
index caf7b632393..61d5a1d74ae 100644
--- a/tests/ui/issues/issue-13434.rs
+++ b/tests/ui/traits/fnonce-repro-trait-impl-13434.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13434
+
 //@ run-pass
 #[derive(Debug)]
 struct MyStruct;
diff --git a/tests/ui/traits/next-solver/cycles/rayon-hang-1.rs b/tests/ui/traits/next-solver/cycles/rayon-hang-1.rs
new file mode 100644
index 00000000000..61e1f1b200f
--- /dev/null
+++ b/tests/ui/traits/next-solver/cycles/rayon-hang-1.rs
@@ -0,0 +1,32 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// A regression test for trait-system-refactor-initiative#109.
+
+trait ParallelIterator: Sized {
+    type Item;
+}
+trait IntoParallelIterator {
+    type Iter: ParallelIterator<Item = Self::Item>;
+    type Item;
+}
+impl<T: ParallelIterator> IntoParallelIterator for T {
+    type Iter = T;
+    type Item = T::Item;
+}
+
+macro_rules! multizip_impls {
+    ($($T:ident),+) => {
+       fn foo<$( $T, )+>() where
+        $(
+            $T: IntoParallelIterator,
+            $T::Iter: ParallelIterator,
+        )+
+            ($( $T, )+): IntoParallelIterator<Item = ($( $T::Item, )+)>,
+        {}
+    }
+}
+
+multizip_impls! { A, B, C, D, E, F, G, H, I, J, K, L }
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/cycles/rayon-hang-2.rs b/tests/ui/traits/next-solver/cycles/rayon-hang-2.rs
new file mode 100644
index 00000000000..bb5d8335dd6
--- /dev/null
+++ b/tests/ui/traits/next-solver/cycles/rayon-hang-2.rs
@@ -0,0 +1,49 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// A regression test for trait-system-refactor-initiative#109.
+// Unlike `rayon-hang-1.rs` the cycles in this test are not
+// unproductive, which causes the `AliasRelate` goal when trying
+// to apply where-clauses to only error in the second iteration.
+//
+// This makes the exponential blowup to be significantly harder
+// to avoid.
+
+trait ParallelIterator: Sized {
+    type Item;
+}
+
+trait IntoParallelIteratorIndir {
+    type Iter: ParallelIterator<Item = Self::Item>;
+    type Item;
+}
+impl<I> IntoParallelIteratorIndir for I
+where
+    Box<I>: IntoParallelIterator,
+{
+    type Iter = <Box<I> as IntoParallelIterator>::Iter;
+    type Item = <Box<I> as IntoParallelIterator>::Item;
+}
+trait IntoParallelIterator {
+    type Iter: ParallelIterator<Item = Self::Item>;
+    type Item;
+}
+impl<T: ParallelIterator> IntoParallelIterator for T {
+    type Iter = T;
+    type Item = T::Item;
+}
+
+macro_rules! multizip_impls {
+    ($($T:ident),+) => {
+       fn foo<'a, $( $T, )+>() where
+        $(
+            $T: IntoParallelIteratorIndir,
+            $T::Iter: ParallelIterator,
+        )+
+        {}
+    }
+}
+
+multizip_impls! { A, B, C, D, E, F, G, H, I, J, K, L }
+
+fn main() {}
diff --git a/tests/ui/issues/issue-22434.rs b/tests/ui/type-alias/missing-associated-type-in-trait-object-22434.rs
index d9f7b987c64..35b30374c15 100644
--- a/tests/ui/issues/issue-22434.rs
+++ b/tests/ui/type-alias/missing-associated-type-in-trait-object-22434.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/22434
 pub trait Foo {
     type A;
 }
diff --git a/tests/ui/issues/issue-22434.stderr b/tests/ui/type-alias/missing-associated-type-in-trait-object-22434.stderr
index 172ae386c3e..73afefa5a1f 100644
--- a/tests/ui/issues/issue-22434.stderr
+++ b/tests/ui/type-alias/missing-associated-type-in-trait-object-22434.stderr
@@ -1,5 +1,5 @@
 error[E0191]: the value of the associated type `A` in `Foo` must be specified
-  --> $DIR/issue-22434.rs:5:23
+  --> $DIR/missing-associated-type-in-trait-object-22434.rs:6:23
    |
 LL |     type A;
    |     ------ `A` defined here
diff --git a/tests/ui/type-inference/partial-type-hint-12909.rs b/tests/ui/type-inference/partial-type-hint-12909.rs
new file mode 100644
index 00000000000..d7017f451e3
--- /dev/null
+++ b/tests/ui/type-inference/partial-type-hint-12909.rs
@@ -0,0 +1,21 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12909
+
+//@ run-pass
+#![allow(unused_variables)]
+
+use std::collections::HashMap;
+
+fn copy<T: Copy>(&x: &T) -> T {
+    x
+}
+
+fn main() {
+    let arr = [(1, 1), (2, 2), (3, 3)];
+
+    let v1: Vec<&_> = arr.iter().collect();
+    let v2: Vec<_> = arr.iter().map(copy).collect();
+
+    let m1: HashMap<_, _> = arr.iter().map(copy).collect();
+    let m2: HashMap<isize, _> = arr.iter().map(copy).collect();
+    let m3: HashMap<_, usize> = arr.iter().map(copy).collect();
+}
diff --git a/tests/ui/issues/issue-12863.rs b/tests/ui/typeck/function-in-pattern-error-12863.rs
index 1ac1c3d818e..d2fa2555658 100644
--- a/tests/ui/issues/issue-12863.rs
+++ b/tests/ui/typeck/function-in-pattern-error-12863.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/12863
+
 mod foo { pub fn bar() {} }
 
 fn main() {
diff --git a/tests/ui/issues/issue-12863.stderr b/tests/ui/typeck/function-in-pattern-error-12863.stderr
index 95d4a704e72..f28874b5d48 100644
--- a/tests/ui/issues/issue-12863.stderr
+++ b/tests/ui/typeck/function-in-pattern-error-12863.stderr
@@ -1,5 +1,5 @@
 error[E0532]: expected unit struct, unit variant or constant, found function `foo::bar`
-  --> $DIR/issue-12863.rs:5:9
+  --> $DIR/function-in-pattern-error-12863.rs:7:9
    |
 LL |         foo::bar => {}
    |         ^^^^^^^^ not a unit struct, unit variant or constant
diff --git a/tests/ui/issues/issue-48276.rs b/tests/ui/typeck/incorrect-self-type-in-trait-impl-48276.rs
index f55c056fa67..1cff2078755 100644
--- a/tests/ui/issues/issue-48276.rs
+++ b/tests/ui/typeck/incorrect-self-type-in-trait-impl-48276.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/48276
 // Regression test for issue #48276 - ICE when self type does not match what is
 // required by a trait and regions are involved.
 
diff --git a/tests/ui/issues/issue-48276.stderr b/tests/ui/typeck/incorrect-self-type-in-trait-impl-48276.stderr
index 370905ee0df..124dc459237 100644
--- a/tests/ui/issues/issue-48276.stderr
+++ b/tests/ui/typeck/incorrect-self-type-in-trait-impl-48276.stderr
@@ -1,5 +1,5 @@
 error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
-  --> $DIR/issue-48276.rs:11:5
+  --> $DIR/incorrect-self-type-in-trait-impl-48276.rs:12:5
    |
 LL |     fn from(a: A) -> Self;
    |     ---------------------- trait method declared without `&self`
@@ -8,7 +8,7 @@ LL |     fn from(self: &'a Self) -> &'b str {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl
 
 error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
-  --> $DIR/issue-48276.rs:20:5
+  --> $DIR/incorrect-self-type-in-trait-impl-48276.rs:21:5
    |
 LL |     fn from(&self) -> B {
    |     ^^^^^^^^^^^^^^^^^^^ `&self` used in impl
@@ -16,7 +16,7 @@ LL |     fn from(&self) -> B {
    = note: `from` from trait: `fn(T) -> Self`
 
 error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
-  --> $DIR/issue-48276.rs:27:5
+  --> $DIR/incorrect-self-type-in-trait-impl-48276.rs:28:5
    |
 LL |     fn from(&self) -> &'static str {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl
diff --git a/tests/ui/issues/issue-13359.rs b/tests/ui/typeck/isize-usize-mismatch-error.rs
index 5d31d7f861c..2fb5cf489c0 100644
--- a/tests/ui/issues/issue-13359.rs
+++ b/tests/ui/typeck/isize-usize-mismatch-error.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13359
+
 //@ dont-require-annotations: NOTE
 
 fn foo(_s: i16) { }
diff --git a/tests/ui/issues/issue-13359.stderr b/tests/ui/typeck/isize-usize-mismatch-error.stderr
index 91f5de8e8f3..d5724665a03 100644
--- a/tests/ui/issues/issue-13359.stderr
+++ b/tests/ui/typeck/isize-usize-mismatch-error.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-13359.rs:8:9
+  --> $DIR/isize-usize-mismatch-error.rs:10:9
    |
 LL |     foo(1*(1 as isize));
    |     --- ^^^^^^^^^^^^^^ expected `i16`, found `isize`
@@ -7,7 +7,7 @@ LL |     foo(1*(1 as isize));
    |     arguments to this function are incorrect
    |
 note: function defined here
-  --> $DIR/issue-13359.rs:3:4
+  --> $DIR/isize-usize-mismatch-error.rs:5:4
    |
 LL | fn foo(_s: i16) { }
    |    ^^^ -------
@@ -17,7 +17,7 @@ LL |     foo((1*(1 as isize)).try_into().unwrap());
    |         +              +++++++++++++++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/issue-13359.rs:12:9
+  --> $DIR/isize-usize-mismatch-error.rs:14:9
    |
 LL |     bar(1*(1 as usize));
    |     --- ^^^^^^^^^^^^^^ expected `u32`, found `usize`
@@ -25,7 +25,7 @@ LL |     bar(1*(1 as usize));
    |     arguments to this function are incorrect
    |
 note: function defined here
-  --> $DIR/issue-13359.rs:5:4
+  --> $DIR/isize-usize-mismatch-error.rs:7:4
    |
 LL | fn bar(_s: u32) { }
    |    ^^^ -------
diff --git a/tests/ui/issues/issue-32995-2.rs b/tests/ui/typeck/parenthesized-type-parameters-error-32995.rs
index e713a64d3f5..e0c2ab5f303 100644
--- a/tests/ui/issues/issue-32995-2.rs
+++ b/tests/ui/typeck/parenthesized-type-parameters-error-32995.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/32995
 fn main() {
     { fn f<X: ::std::marker()::Send>() {} }
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
diff --git a/tests/ui/issues/issue-32995-2.stderr b/tests/ui/typeck/parenthesized-type-parameters-error-32995.stderr
index 6c2d772a233..590cdcdb43b 100644
--- a/tests/ui/issues/issue-32995-2.stderr
+++ b/tests/ui/typeck/parenthesized-type-parameters-error-32995.stderr
@@ -1,17 +1,17 @@
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:2:22
+  --> $DIR/parenthesized-type-parameters-error-32995.rs:3:22
    |
 LL |     { fn f<X: ::std::marker()::Send>() {} }
    |                      ^^^^^^^^ only `Fn` traits may use parentheses
 
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:5:29
+  --> $DIR/parenthesized-type-parameters-error-32995.rs:6:29
    |
 LL |     { fn f() -> impl ::std::marker()::Send { } }
    |                             ^^^^^^^^ only `Fn` traits may use parentheses
 
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:12:13
+  --> $DIR/parenthesized-type-parameters-error-32995.rs:13:13
    |
 LL | impl ::std::marker()::Copy for X {}
    |             ^^^^^^^^ only `Fn` traits may use parentheses
diff --git a/tests/ui/issues/issue-11771.rs b/tests/ui/typeck/unit-type-add-error-11771.rs
index c69cd1e79e3..d009f50f4b9 100644
--- a/tests/ui/issues/issue-11771.rs
+++ b/tests/ui/typeck/unit-type-add-error-11771.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/11771
+
 fn main() {
     let x = ();
     1 +
diff --git a/tests/ui/issues/issue-11771.stderr b/tests/ui/typeck/unit-type-add-error-11771.stderr
index 5603dc18b63..155cc093524 100644
--- a/tests/ui/issues/issue-11771.stderr
+++ b/tests/ui/typeck/unit-type-add-error-11771.stderr
@@ -1,5 +1,5 @@
 error[E0277]: cannot add `()` to `{integer}`
-  --> $DIR/issue-11771.rs:3:7
+  --> $DIR/unit-type-add-error-11771.rs:5:7
    |
 LL |     1 +
    |       ^ no implementation for `{integer} + ()`
@@ -17,7 +17,7 @@ LL |     1 +
            and 56 others
 
 error[E0277]: cannot add `()` to `{integer}`
-  --> $DIR/issue-11771.rs:8:7
+  --> $DIR/unit-type-add-error-11771.rs:10:7
    |
 LL |     1 +
    |       ^ no implementation for `{integer} + ()`
diff --git a/tests/ui/issues/issue-13202.rs b/tests/ui/typeck/unwrap-or-panic-input-13202.rs
index 99ffba3fba5..29833a727c5 100644
--- a/tests/ui/issues/issue-13202.rs
+++ b/tests/ui/typeck/unwrap-or-panic-input-13202.rs
@@ -1,3 +1,5 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/13202
+
 //@ run-fail
 //@ error-pattern:bad input
 //@ needs-subprocess
diff --git a/tests/ui/issues/issue-18685.rs b/tests/ui/unboxed-closures/self-param-space-conflict-in-unboxed-closure-18685.rs
index 3dab341f615..38cf26c2777 100644
--- a/tests/ui/issues/issue-18685.rs
+++ b/tests/ui/unboxed-closures/self-param-space-conflict-in-unboxed-closure-18685.rs
@@ -1,8 +1,8 @@
+// https://github.com/rust-lang/rust/issues/18685
 //@ run-pass
 // Test that the self param space is not used in a conflicting
 // manner by unboxed closures within a default method on a trait
 
-
 trait Tr {
     fn foo(&self);
 
diff --git a/triagebot.toml b/triagebot.toml
index 168815465b6..fefff78d64e 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -355,6 +355,7 @@ trigger_labels = [
 [autolabel."T-libs"]
 trigger_files = [
     "library/alloc",
+    "library/compiler-builtins",
     "library/core",
     "library/panic_abort",
     "library/panic_unwind",
@@ -1006,10 +1007,6 @@ cc = [
 message = "Some changes occurred in GUI tests."
 cc = ["@GuillaumeGomez"]
 
-[mentions."tests/run-make/"]
-message = "This PR modifies `run-make` tests."
-cc = ["@jieyouxu"]
-
 [mentions."tests/auxiliary/minicore.rs"]
 message = "This PR modifies `tests/auxiliary/minicore.rs`."
 cc = ["@jieyouxu"]
@@ -1064,6 +1061,14 @@ cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@davidtwco", "@vakaras"]
 message = "`rustc_error_messages` was changed"
 cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"]
 
+[mentions."compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs"]
+message = "`rustc_errors::annotate_snippet_emitter_writer` was changed"
+cc = ["@Muscraft"]
+
+[mentions."compiler/rustc_errors/src/emitter.rs"]
+message = "`rustc_errors::emitter` was changed"
+cc = ["@Muscraft"]
+
 [mentions."compiler/rustc_errors/src/translation.rs"]
 message = "`rustc_errors::translation` was changed"
 cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"]
@@ -1104,10 +1109,6 @@ Otherwise, you can ignore this comment.
 [mentions."src/tools/x"]
 message = "`src/tools/x` was changed. Bump version of Cargo.toml in `src/tools/x` so tidy will suggest installing the new version."
 
-[mentions."src/tools/tidy"]
-message = "There are changes to the `tidy` tool."
-cc = ["@jieyouxu"]
-
 [mentions."src/tools/tidy/src/deps.rs"]
 message = "The list of allowed third-party dependencies may have been modified! You must ensure that any new dependencies have compatible licenses before merging."
 cc = ["@davidtwco", "@wesleywiser"]