about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock24
-rw-r--r--compiler/rustc_abi/src/callconv.rs20
-rw-r--r--compiler/rustc_abi/src/layout.rs11
-rw-r--r--compiler/rustc_abi/src/lib.rs16
-rw-r--r--compiler/rustc_arena/src/lib.rs1
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs84
-rw-r--r--compiler/rustc_borrowck/src/lib.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs3
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs13
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs8
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs10
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs18
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs6
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs12
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs53
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs4
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/Cargo.toml2
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/mod.rs23
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0636.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0705.md2
-rw-r--r--compiler/rustc_expand/src/base.rs8
-rw-r--r--compiler/rustc_expand/src/config.rs21
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs2
-rw-r--r--compiler/rustc_feature/src/accepted.rs3
-rw-r--r--compiler/rustc_feature/src/unstable.rs96
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs51
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs50
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs35
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs30
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lint/src/builtin.rs6
-rw-r--r--compiler/rustc_lint/src/levels.rs7
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/types.rs5
-rw-r--r--compiler/rustc_lint/src/unused.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs56
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs3
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs8
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs11
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs7
-rw-r--r--compiler/rustc_middle/src/traits/select.rs7
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs135
-rw-r--r--compiler/rustc_middle/src/ty/context.rs22
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs18
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs12
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs7
-rw-r--r--compiler/rustc_middle/src/ty/util.rs18
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs7
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs12
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs16
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/mod.rs5
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs3
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs3
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs224
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs25
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs3
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs2
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs4
-rw-r--r--compiler/rustc_mir_transform/src/remove_uninit_drops.rs3
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs24
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs31
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs7
-rw-r--r--compiler/rustc_passes/messages.ftl21
-rw-r--r--compiler/rustc_passes/src/check_attr.rs56
-rw-r--r--compiler/rustc_passes/src/check_const.rs4
-rw-r--r--compiler/rustc_passes/src/errors.rs33
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs4
-rw-r--r--compiler/rustc_passes/src/reachable.rs2
-rw-r--r--compiler/rustc_passes/src/stability.rs12
-rw-r--r--compiler/rustc_pattern_analysis/Cargo.toml2
-rw-r--r--compiler/rustc_privacy/src/lib.rs8
-rw-r--r--compiler/rustc_query_system/src/ich/impls_syntax.rs6
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs6
-rw-r--r--compiler/rustc_resolve/src/lib.rs3
-rw-r--r--compiler/rustc_resolve/src/macros.rs38
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs8
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs21
-rw-r--r--compiler/rustc_session/messages.ftl3
-rw-r--r--compiler/rustc_session/src/errors.rs10
-rw-r--r--compiler/rustc_session/src/options.rs5
-rw-r--r--compiler/rustc_session/src/session.rs9
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs20
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs5
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs22
-rw-r--r--compiler/rustc_target/src/callconv/x86.rs104
-rw-r--r--compiler/rustc_target/src/spec/abi/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs23
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/tests/tests_impl.rs11
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs256
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs102
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs36
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs112
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs204
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs11
-rw-r--r--compiler/rustc_transmute/src/lib.rs10
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs16
-rw-r--r--compiler/rustc_ty_utils/src/layout/invariant.rs (renamed from compiler/rustc_ty_utils/src/layout_sanity_check.rs)2
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs1
-rw-r--r--compiler/rustc_type_ir/src/interner.rs8
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs51
-rw-r--r--compiler/rustc_type_ir/src/relate.rs4
-rw-r--r--library/alloc/benches/lib.rs3
-rw-r--r--library/alloc/src/lib.rs3
-rw-r--r--library/alloc/tests/lib.rs3
-rw-r--r--library/core/src/fmt/rt.rs26
-rw-r--r--library/core/src/intrinsics.rs1
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/primitive_docs.rs8
-rw-r--r--library/core/src/ptr/const_ptr.rs92
-rw-r--r--library/core/src/ptr/mod.rs491
-rw-r--r--library/core/src/ptr/mut_ptr.rs95
-rw-r--r--library/core/src/ptr/non_null.rs22
-rw-r--r--library/core/src/sync/atomic.rs12
-rw-r--r--library/core/tests/lib.rs3
-rw-r--r--library/panic_unwind/src/lib.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/lib.rs1
-rw-r--r--library/portable-simd/crates/core_simd/tests/pointers.rs2
-rw-r--r--library/proc_macro/src/lib.rs1
-rw-r--r--library/std/src/fs.rs2
-rw-r--r--library/std/src/lib.rs4
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt4
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs8
-rw-r--r--library/std/src/sys/pal/windows/fs.rs41
-rw-r--r--library/unwind/src/lib.rs1
-rwxr-xr-xsrc/bootstrap/configure.py3
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs43
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs22
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs20
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs33
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs1220
-rw-r--r--src/bootstrap/src/core/builder/mod.rs (renamed from src/bootstrap/src/core/builder.rs)1219
-rw-r--r--src/bootstrap/src/core/builder/tests.rs2
-rw-r--r--src/bootstrap/src/lib.rs19
-rw-r--r--src/bootstrap/src/utils/channel.rs14
-rw-r--r--src/bootstrap/src/utils/helpers.rs27
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile6
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile8
-rwxr-xr-xsrc/ci/docker/scripts/freebsd-toolchain.sh8
-rw-r--r--src/ci/github-actions/jobs.yml10
-rw-r--r--src/doc/rustc/src/platform-support.md18
-rw-r--r--src/doc/rustc/src/platform-support/arm-none-eabi.md15
-rw-r--r--src/doc/rustc/src/platform-support/nuttx.md2
-rw-r--r--src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md15
-rw-r--r--src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md37
-rw-r--r--src/doc/unstable-book/src/compiler-flags/regparm.md20
-rw-r--r--src/doc/unstable-book/src/language-features/result-ffi-guarantees.md14
-rw-r--r--src/doc/unstable-book/src/language-features/strict-provenance-lints.md (renamed from src/doc/unstable-book/src/language-features/strict-provenance.md)7
-rw-r--r--src/etc/installer/msi/rust.wxs41
-rw-r--r--src/librustdoc/clean/mod.rs6
-rw-r--r--src/librustdoc/core.rs39
-rw-r--r--src/rustdoc-json-types/Cargo.toml2
-rw-r--r--src/rustdoc-json-types/lib.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/indexing_slicing.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_div_ceil.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/utils.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/trailing_empty_array.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs19
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed8
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs8
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr12
-rw-r--r--src/tools/compiletest/src/common.rs4
-rw-r--r--src/tools/compiletest/src/header.rs79
-rw-r--r--src/tools/compiletest/src/lib.rs6
-rw-r--r--src/tools/compiletest/src/main.rs2
-rw-r--r--src/tools/compiletest/src/runtest.rs4
-rw-r--r--src/tools/compiletest/src/runtest/debugger.rs15
-rw-r--r--src/tools/compiletest/src/runtest/debuginfo.rs27
-rw-r--r--src/tools/jsondoclint/Cargo.toml2
-rw-r--r--src/tools/linkchecker/main.rs11
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs9
-rw-r--r--src/tools/miri/src/lib.rs2
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs1
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.rs1
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.rs1
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs1
-rw-r--r--src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.rs1
-rw-r--r--src/tools/miri/tests/fail/provenance/provenance_transmute.rs1
-rw-r--r--src/tools/miri/tests/fail/provenance/ptr_int_unexposed.rs1
-rw-r--r--src/tools/miri/tests/fail/provenance/ptr_invalid.rs1
-rw-r--r--src/tools/miri/tests/fail/provenance/ptr_invalid_offset.rs1
-rw-r--r--src/tools/miri/tests/fail/provenance/strict_provenance_cast.rs1
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs1
-rw-r--r--src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs1
-rw-r--r--src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs1
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-affinity.rs1
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs1
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-mem.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-misc.rs1
-rw-r--r--src/tools/miri/tests/pass-dep/libc/mmap.rs1
-rw-r--r--src/tools/miri/tests/pass/align_offset_symbolic.rs1
-rw-r--r--src/tools/miri/tests/pass/atomic.rs2
-rw-r--r--src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs1
-rw-r--r--src/tools/miri/tests/pass/concurrency/address_reuse_happens_before.rs1
-rw-r--r--src/tools/miri/tests/pass/const-addrs.rs1
-rw-r--r--src/tools/miri/tests/pass/drop_type_without_drop_glue.rs2
-rw-r--r--src/tools/miri/tests/pass/extern_types.rs2
-rw-r--r--src/tools/miri/tests/pass/provenance.rs1
-rw-r--r--src/tools/miri/tests/pass/ptr_int_from_exposed.rs1
-rw-r--r--src/tools/miri/tests/pass/ptr_raw.rs1
-rw-r--r--src/tools/miri/tests/pass/shims/ptr_mask.rs1
-rw-r--r--src/tools/miri/tests/pass/slices.rs1
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs1
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs1
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs1
-rw-r--r--src/tools/miri/tests/pass/transmute_ptr.rs1
-rw-r--r--src/tools/miri/tests/pass/underscore_pattern.rs1
-rw-r--r--src/tools/miri/tests/pass/zero-sized-accesses-and-offsets.rs1
-rw-r--r--src/tools/miropt-test-tools/src/lib.rs3
-rw-r--r--src/tools/rust-analyzer/.editorconfig2
-rw-r--r--src/tools/rust-analyzer/.github/workflows/ci.yaml6
-rw-r--r--src/tools/rust-analyzer/Cargo.lock86
-rw-r--r--src/tools/rust-analyzer/Cargo.toml14
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/visibility.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs25
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/db.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs20
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs52
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_result_return_type.rs1115
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs2229
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs2457
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs1268
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs126
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs55
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs35
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/annotations.rs238
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs38
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/references.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/runnables.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html12
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/benchmark.rs13
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/items.rs6
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs6
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rast208
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rs17
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/tests.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs9
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs12
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram3
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs6
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ptr.rs2
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc44
-rw-r--r--src/tools/rust-analyzer/editors/code/package-lock.json1525
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json53
-rw-r--r--src/tools/rust-analyzer/editors/code/src/config.ts4
-rw-r--r--src/tools/rust-analyzer/editors/code/src/debug.ts43
-rw-r--r--src/tools/rust-analyzer/editors/code/src/main.ts9
-rw-r--r--src/tools/rust-analyzer/lib/line-index/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/lib/line-index/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/lib/line-index/src/tests.rs23
-rw-r--r--src/tools/rust-analyzer/rust-version2
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs2
-rw-r--r--src/tools/tidy/Cargo.toml2
-rw-r--r--src/tools/tidy/src/issues.txt21
-rw-r--r--src/tools/unicode-table-generator/Cargo.toml2
-rw-r--r--src/tools/unicode-table-generator/src/range_search.rs6
-rw-r--r--tests/assembly/riscv-soft-abi-with-float-features.rs46
-rw-r--r--tests/codegen/atomicptr.rs1
-rw-r--r--tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs1
-rw-r--r--tests/codegen/regparm-inreg.rs125
-rw-r--r--tests/codegen/riscv-target-abi.rs2
-rw-r--r--tests/crashes/131637.rs7
-rw-r--r--tests/crashes/131648.rs7
-rw-r--r--tests/crashes/131668.rs12
-rw-r--r--tests/crashes/131758.rs11
-rw-r--r--tests/crashes/131762.rs9
-rw-r--r--tests/crashes/131787.rs5
-rw-r--r--tests/crashes/131886.rs12
-rw-r--r--tests/crashes/131915.rs13
-rw-r--r--tests/debuginfo/constant-ordering-prologue.rs6
-rw-r--r--tests/mir-opt/dest-prop/union.rs3
-rw-r--r--tests/mir-opt/gvn_ptr_eq_with_constant.rs2
-rw-r--r--tests/mir-opt/issues/issue_59352.rs1
-rw-r--r--tests/run-make/import-macro-verbatim/include/include.txt1
-rw-r--r--tests/run-make/import-macro-verbatim/rmake.rs8
-rw-r--r--tests/run-make/import-macro-verbatim/verbatim.rs12
-rw-r--r--tests/run-make/rustc-crates-on-stable/rmake.rs4
-rw-r--r--tests/rustdoc-ui/deprecated-attrs.rs19
-rw-r--r--tests/rustdoc-ui/deprecated-attrs.stderr35
-rw-r--r--tests/rustdoc-ui/rustc-check-passes.stderr2
-rw-r--r--tests/rustdoc/impossible-default.rs8
-rw-r--r--tests/ui/abi/unsupported.aarch64.stderr25
-rw-r--r--tests/ui/abi/unsupported.arm.stderr25
-rw-r--r--tests/ui/abi/unsupported.i686.stderr8
-rw-r--r--tests/ui/abi/unsupported.riscv32.stderr25
-rw-r--r--tests/ui/abi/unsupported.riscv64.stderr25
-rw-r--r--tests/ui/abi/unsupported.rs30
-rw-r--r--tests/ui/abi/unsupported.x64.stderr25
-rw-r--r--tests/ui/argument-suggestions/issue-109425.fixed4
-rw-r--r--tests/ui/argument-suggestions/issue-109425.rs4
-rw-r--r--tests/ui/argument-suggestions/issue-109425.stderr42
-rw-r--r--tests/ui/argument-suggestions/issue-112507.stderr5
-rw-r--r--tests/ui/async-await/field-in-sync.rs13
-rw-r--r--tests/ui/async-await/field-in-sync.stderr17
-rw-r--r--tests/ui/async-await/issue-61076.stderr4
-rw-r--r--tests/ui/async-await/try-in-sync.rs9
-rw-r--r--tests/ui/async-await/try-in-sync.stderr18
-rw-r--r--tests/ui/attributes/optimize.rs22
-rw-r--r--tests/ui/attributes/optimize.stderr38
-rw-r--r--tests/ui/closures/issue-111932.stderr2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs2
-rw-r--r--tests/ui/const-generics/infer/issue-77092.stderr2
-rw-r--r--tests/ui/coroutine/other-attribute-on-gen.rs40
-rw-r--r--tests/ui/feature-gates/duplicate-features.rs4
-rw-r--r--tests/ui/feature-gates/duplicate-features.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-optimize_attribute.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-optimize_attribute.stderr30
-rw-r--r--tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs99
-rw-r--r--tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr349
-rw-r--r--tests/ui/feature-gates/feature-gate-strict_provenance_lints.rs (renamed from tests/ui/feature-gates/feature-gate-strict_provenance.rs)0
-rw-r--r--tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr (renamed from tests/ui/feature-gates/feature-gate-strict_provenance.stderr)12
-rw-r--r--tests/ui/fmt/ifmt-unimpl.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr4
-rw-r--r--tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs24
-rw-r--r--tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr4
-rw-r--r--tests/ui/invalid-compile-flags/regparm/requires-x86.rs21
-rw-r--r--tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr4
-rw-r--r--tests/ui/layout/thaw-transmute-invalid-enum.rs (renamed from tests/crashes/126966.rs)9
-rw-r--r--tests/ui/layout/thaw-transmute-invalid-enum.stderr68
-rw-r--r--tests/ui/layout/thaw-validate-invalid-enum.rs (renamed from tests/crashes/128870.rs)5
-rw-r--r--tests/ui/layout/thaw-validate-invalid-enum.stderr29
-rw-r--r--tests/ui/lint/auxiliary/allow-macro.rs7
-rw-r--r--tests/ui/lint/auxiliary/deny-macro.rs7
-rw-r--r--tests/ui/lint/auxiliary/forbid-macro.rs7
-rw-r--r--tests/ui/lint/auxiliary/warn-macro.rs7
-rw-r--r--tests/ui/lint/deny-inside-forbid-ignored.cli_forbid.stderr35
-rw-r--r--tests/ui/lint/deny-inside-forbid-ignored.cli_forbid_warnings.stderr35
-rw-r--r--tests/ui/lint/deny-inside-forbid-ignored.rs20
-rw-r--r--tests/ui/lint/deny-inside-forbid-ignored.source_only.stderr35
-rw-r--r--tests/ui/lint/forbid-macro-with-deny.allow.stderr26
-rw-r--r--tests/ui/lint/forbid-macro-with-deny.rs45
-rw-r--r--tests/ui/lint/forbid-macro-with-deny.warn.stderr26
-rw-r--r--tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs4
-rw-r--r--tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr5
-rw-r--r--tests/ui/lint/issue-80988.rs10
-rw-r--r--tests/ui/lint/issue-80988.stderr15
-rw-r--r--tests/ui/lint/lint-ctypes-enum.rs1
-rw-r--r--tests/ui/lint/lint-ctypes-enum.stderr58
-rw-r--r--tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs2
-rw-r--r--tests/ui/lint/lint-strict-provenance-lossy-casts.rs2
-rw-r--r--tests/ui/lint/unit_bindings.deny_level.stderr40
-rw-r--r--tests/ui/lint/unit_bindings.rs60
-rw-r--r--tests/ui/lint/unused/unused-macro-rules-compile-error.stderr12
-rw-r--r--tests/ui/lint/unused/unused-macro-rules-decl.stderr16
-rw-r--r--tests/ui/lint/unused/unused-macro-rules.stderr16
-rw-r--r--tests/ui/mir/alignment/i686-pc-windows-msvc.rs2
-rw-r--r--tests/ui/mir/alignment/packed.rs2
-rw-r--r--tests/ui/rfcs/rfc-3391-result-ffi-guarantees.rs133
-rw-r--r--tests/ui/stats/hir-stats.stderr46
-rw-r--r--tests/ui/structs-enums/type-sizes.rs1
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs)0
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr)0
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs)0
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr)0
-rw-r--r--tests/ui/traits/const-traits/assoc-type.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs)0
-rw-r--r--tests/ui/traits/const-traits/assoc-type.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr)0
-rw-r--r--tests/ui/traits/const-traits/attr-misuse.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/attr-misuse.rs)0
-rw-r--r--tests/ui/traits/const-traits/attr-misuse.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/attr-misuse.stderr)0
-rw-r--r--tests/ui/traits/const-traits/auxiliary/cross-crate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs)0
-rw-r--r--tests/ui/traits/const-traits/auxiliary/staged-api.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-fail.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-fail.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr)0
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-pass.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-pass.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-in-impl.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-in-impl.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-chain.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-chain.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-dup-bound.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-fail.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst-bound.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst-bound.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-pass.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.rs)0
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-pass.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr)0
-rw-r--r--tests/ui/traits/const-traits/call.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-and-non-const-impl.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-and-non-const-impl.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-bounds-non-const-trait.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-closure-parse-not-item.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-closure-parse-not-item.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method-fail.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-closures.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-closures.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-default-method-bodies.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-default-method-bodies.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-bound.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-bound.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.precise.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.stock.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-drop.precise.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-drop.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-drop.stock.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-fns-are-early-bound.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-fns-are-early-bound.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-impl-norecover.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-norecover.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-impl-norecover.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-norecover.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-impl-recovery.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-recovery.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-impl-recovery.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-recovery.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-impl-requires-const-trait.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs)0
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-gate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs)0
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs)0
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs)0
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr)0
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs)0
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr)0
-rw-r--r--tests/ui/traits/const-traits/cross-crate-default-method-body-is-const.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs)0
-rw-r--r--tests/ui/traits/const-traits/cross-crate.gatednc.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr)0
-rw-r--r--tests/ui/traits/const-traits/cross-crate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs)0
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stock.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr)0
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stocknc.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr)0
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs)0
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs)0
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr)0
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-with-staged-api.rs)0
-rw-r--r--tests/ui/traits/const-traits/do-not-const-check-override.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs)0
-rw-r--r--tests/ui/traits/const-traits/do-not-const-check.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/auxiliary/cross-crate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/const_closure-const_trait_impl-ice-113381.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/effect-param-infer.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/fallback.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/group-traits.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/helloworld.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/ice-113375-index-out-of-bounds-generics.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/infer-fallback.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/minicore.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/minicore.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/mismatched_generic_args.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/mismatched_generic_args.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/mismatched_generic_args.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/mismatched_generic_args.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/project.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/span-bug-issue-121418.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/span-bug-issue-121418.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/trait-fn-const.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/trait-fn-const.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/with-without-next-solver.coherence.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr)0
-rw-r--r--tests/ui/traits/const-traits/effects/with-without-next-solver.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs)0
-rw-r--r--tests/ui/traits/const-traits/effects/with-without-next-solver.stock.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr)0
-rw-r--r--tests/ui/traits/const-traits/feature-gate.gated.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.gated.stderr)0
-rw-r--r--tests/ui/traits/const-traits/feature-gate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.rs)0
-rw-r--r--tests/ui/traits/const-traits/feature-gate.stock.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.stock.stderr)0
-rw-r--r--tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/function-pointer-does-not-require-const.rs)0
-rw-r--r--tests/ui/traits/const-traits/gate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/gate.rs)0
-rw-r--r--tests/ui/traits/const-traits/gate.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/gate.stderr)0
-rw-r--r--tests/ui/traits/const-traits/generic-bound.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.rs)0
-rw-r--r--tests/ui/traits/const-traits/generic-bound.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr)0
-rw-r--r--tests/ui/traits/const-traits/hir-const-check.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs)0
-rw-r--r--tests/ui/traits/const-traits/hir-const-check.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr)0
-rw-r--r--tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs)0
-rw-r--r--tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr)0
-rw-r--r--tests/ui/traits/const-traits/ice-120503-async-const-method.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.rs)0
-rw-r--r--tests/ui/traits/const-traits/ice-120503-async-const-method.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr)0
-rw-r--r--tests/ui/traits/const-traits/ice-121536-const-method.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.rs)0
-rw-r--r--tests/ui/traits/const-traits/ice-121536-const-method.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr)0
-rw-r--r--tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs)0
-rw-r--r--tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr)0
-rw-r--r--tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs)0
-rw-r--r--tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr)0
-rw-r--r--tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs)0
-rw-r--r--tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr)0
-rw-r--r--tests/ui/traits/const-traits/impl-tilde-const-trait.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/impl-tilde-const-trait.rs)0
-rw-r--r--tests/ui/traits/const-traits/impl-tilde-const-trait.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/impl-tilde-const-trait.stderr)0
-rw-r--r--tests/ui/traits/const-traits/impl-with-default-fn-fail.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs)0
-rw-r--r--tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr)0
-rw-r--r--tests/ui/traits/const-traits/impl-with-default-fn-pass.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs)0
-rw-r--r--tests/ui/traits/const-traits/inherent-impl-const-bounds.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs)0
-rw-r--r--tests/ui/traits/const-traits/inherent-impl.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl.rs)0
-rw-r--r--tests/ui/traits/const-traits/inherent-impl.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl.stderr)0
-rw-r--r--tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.rs)0
-rw-r--r--tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.stderr)0
-rw-r--r--tests/ui/traits/const-traits/issue-100222.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs)0
-rw-r--r--tests/ui/traits/const-traits/issue-102156.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.rs)0
-rw-r--r--tests/ui/traits/const-traits/issue-102156.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr)0
-rw-r--r--tests/ui/traits/const-traits/issue-102985.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.rs)0
-rw-r--r--tests/ui/traits/const-traits/issue-102985.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr)0
-rw-r--r--tests/ui/traits/const-traits/issue-103677.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-103677.rs)0
-rw-r--r--tests/ui/traits/const-traits/issue-79450.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs)0
-rw-r--r--tests/ui/traits/const-traits/issue-79450.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr)0
-rw-r--r--tests/ui/traits/const-traits/issue-88155.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.rs)0
-rw-r--r--tests/ui/traits/const-traits/issue-88155.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.stderr)0
-rw-r--r--tests/ui/traits/const-traits/issue-92111.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.rs)0
-rw-r--r--tests/ui/traits/const-traits/issue-92111.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr)0
-rw-r--r--tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs)0
-rw-r--r--tests/ui/traits/const-traits/match-non-const-eq.gated.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr)0
-rw-r--r--tests/ui/traits/const-traits/match-non-const-eq.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs)0
-rw-r--r--tests/ui/traits/const-traits/match-non-const-eq.stock.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr)0
-rw-r--r--tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-bare-trait-objects-const-trait-bounds.rs)0
-rw-r--r--tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs)0
-rw-r--r--tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr)0
-rw-r--r--tests/ui/traits/const-traits/mbe-dyn-const-2015.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs)0
-rw-r--r--tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.rs)0
-rw-r--r--tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.stderr)0
-rw-r--r--tests/ui/traits/const-traits/nested-closure.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs)0
-rw-r--r--tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.rs)0
-rw-r--r--tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.stderr)0
-rw-r--r--tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs)0
-rw-r--r--tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs)0
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs)0
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs)0
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specialization/default-keyword.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs)0
-rw-r--r--tests/ui/traits/const-traits/specialization/default-keyword.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs)0
-rw-r--r--tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs)0
-rw-r--r--tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs)0
-rw-r--r--tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specializing-constness-2.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs)0
-rw-r--r--tests/ui/traits/const-traits/specializing-constness-2.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr)0
-rw-r--r--tests/ui/traits/const-traits/specializing-constness.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs)0
-rw-r--r--tests/ui/traits/const-traits/specializing-constness.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr)0
-rw-r--r--tests/ui/traits/const-traits/staged-api-user-crate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api-user-crate.rs)0
-rw-r--r--tests/ui/traits/const-traits/staged-api-user-crate.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api-user-crate.stderr)0
-rw-r--r--tests/ui/traits/const-traits/staged-api.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs)0
-rw-r--r--tests/ui/traits/const-traits/staged-api.stable.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr)0
-rw-r--r--tests/ui/traits/const-traits/staged-api.unstable.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr)0
-rw-r--r--tests/ui/traits/const-traits/static-const-trait-bound.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/static-const-trait-bound.rs)0
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.gated.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr)0
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.rs)0
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.stock.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.stock.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs)0
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr)0
-rw-r--r--tests/ui/traits/const-traits/super-traits.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs)0
-rw-r--r--tests/ui/traits/const-traits/syntax.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/syntax.rs)0
-rw-r--r--tests/ui/traits/const-traits/tilde-const-and-const-params.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs)0
-rw-r--r--tests/ui/traits/const-traits/tilde-const-and-const-params.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr)0
-rw-r--r--tests/ui/traits/const-traits/tilde-const-assoc-fn-in-trait-impl.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs)0
-rw-r--r--tests/ui/traits/const-traits/tilde-const-inherent-assoc-const-fn.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs)0
-rw-r--r--tests/ui/traits/const-traits/tilde-const-invalid-places.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs)0
-rw-r--r--tests/ui/traits/const-traits/tilde-const-invalid-places.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr)0
-rw-r--r--tests/ui/traits/const-traits/tilde-const-syntax.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-syntax.rs)0
-rw-r--r--tests/ui/traits/const-traits/tilde-const-trait-assoc-tys.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs)0
-rw-r--r--tests/ui/traits/const-traits/tilde-twice.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-twice.rs)0
-rw-r--r--tests/ui/traits/const-traits/tilde-twice.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-twice.stderr)0
-rw-r--r--tests/ui/traits/const-traits/trait-default-body-stability.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs)0
-rw-r--r--tests/ui/traits/const-traits/trait-default-body-stability.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr)0
-rw-r--r--tests/ui/traits/const-traits/trait-method-ptr-in-consts-ice.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs)0
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-const.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs)0
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-const.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr)0
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-run.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs)0
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-self-referential.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs)0
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs)0
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr)0
-rw-r--r--tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs)0
-rw-r--r--tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr (renamed from tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr)0
-rw-r--r--tests/ui/traits/fully-qualified-syntax-cast.rs15
-rw-r--r--tests/ui/traits/fully-qualified-syntax-cast.stderr9
-rw-r--r--tests/ui/traits/next-solver/canonical/do-not-bail-due-to-placeholders.rs16
-rw-r--r--tests/ui/traits/next-solver/normalize/normalize-allow-too-many-vars.rs52
-rw-r--r--tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs11
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs6
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr11
-rw-r--r--tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs19
-rw-r--r--tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr34
-rw-r--r--triagebot.toml11
685 files changed, 11979 insertions, 7208 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2ae6d6dc73f..4d54b5aeb4e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1907,7 +1907,7 @@ dependencies = [
  "anyhow",
  "clap",
  "fs-err",
- "rustc-hash 1.1.0",
+ "rustc-hash 2.0.0",
  "rustdoc-json-types",
  "serde",
  "serde_json",
@@ -3514,7 +3514,7 @@ dependencies = [
  "memmap2",
  "parking_lot",
  "portable-atomic",
- "rustc-hash 1.1.0",
+ "rustc-hash 2.0.0",
  "rustc-rayon",
  "rustc-stable-hash",
  "rustc_arena",
@@ -4211,7 +4211,7 @@ dependencies = [
 name = "rustc_pattern_analysis"
 version = "0.0.0"
 dependencies = [
- "rustc-hash 1.1.0",
+ "rustc-hash 2.0.0",
  "rustc_apfloat",
  "rustc_arena",
  "rustc_data_structures",
@@ -4609,7 +4609,7 @@ name = "rustdoc-json-types"
 version = "0.1.0"
 dependencies = [
  "bincode",
- "rustc-hash 1.1.0",
+ "rustc-hash 2.0.0",
  "serde",
  "serde_json",
 ]
@@ -5239,7 +5239,7 @@ dependencies = [
  "ignore",
  "miropt-test-tools",
  "regex",
- "rustc-hash 1.1.0",
+ "rustc-hash 2.0.0",
  "semver",
  "similar",
  "termcolor",
@@ -5571,13 +5571,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "unicode-bdd"
-version = "0.1.0"
-dependencies = [
- "ucd-parse",
-]
-
-[[package]]
 name = "unicode-bidi"
 version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5627,6 +5620,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
 
 [[package]]
+name = "unicode-table-generator"
+version = "0.1.0"
+dependencies = [
+ "ucd-parse",
+]
+
+[[package]]
 name = "unicode-width"
 version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs
index 2ecac8a9df1..872cae59a4e 100644
--- a/compiler/rustc_abi/src/callconv.rs
+++ b/compiler/rustc_abi/src/callconv.rs
@@ -3,18 +3,23 @@ mod abi {
     pub(crate) use crate::Variants;
 }
 
+#[cfg(feature = "nightly")]
 use rustc_macros::HashStable_Generic;
 
-use crate::{Abi, Align, FieldsShape, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
+#[cfg(feature = "nightly")]
+use crate::{Abi, FieldsShape, TyAbiInterface, TyAndLayout};
+use crate::{Align, HasDataLayout, Size};
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub enum RegKind {
     Integer,
     Float,
     Vector,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct Reg {
     pub kind: RegKind,
     pub size: Size,
@@ -108,15 +113,8 @@ impl HomogeneousAggregate {
     }
 }
 
+#[cfg(feature = "nightly")]
 impl<'a, Ty> TyAndLayout<'a, Ty> {
-    /// Returns `true` if this is an aggregate type (including a ScalarPair!)
-    pub fn is_aggregate(&self) -> bool {
-        match self.abi {
-            Abi::Uninhabited | Abi::Scalar(_) | Abi::Vector { .. } => false,
-            Abi::ScalarPair(..) | Abi::Aggregate { .. } => true,
-        }
-    }
-
     /// Returns `Homogeneous` if this layout is an aggregate containing fields of
     /// only a single type (e.g., `(u32, u32)`). Such aggregates are often
     /// special-cased in ABIs.
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 5ce5f14ce57..0340d1bd6bc 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -11,8 +11,10 @@ use crate::{
     Variants, WrappingRange,
 };
 
+#[cfg(feature = "nightly")]
 mod ty;
 
+#[cfg(feature = "nightly")]
 pub use ty::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx};
 
 // A variant is absent if it's uninhabited and only has ZST fields.
@@ -54,6 +56,9 @@ pub enum LayoutCalculatorError<F> {
 
     /// A union had no fields.
     EmptyUnion,
+
+    /// The fields or variants have irreconcilable reprs
+    ReprConflict,
 }
 
 impl<F> LayoutCalculatorError<F> {
@@ -64,6 +69,7 @@ impl<F> LayoutCalculatorError<F> {
             }
             LayoutCalculatorError::SizeOverflow => LayoutCalculatorError::SizeOverflow,
             LayoutCalculatorError::EmptyUnion => LayoutCalculatorError::EmptyUnion,
+            LayoutCalculatorError::ReprConflict => LayoutCalculatorError::ReprConflict,
         }
     }
 
@@ -77,6 +83,7 @@ impl<F> LayoutCalculatorError<F> {
             }
             LayoutCalculatorError::SizeOverflow => "size overflow",
             LayoutCalculatorError::EmptyUnion => "type is a union with no fields",
+            LayoutCalculatorError::ReprConflict => "type has an invalid repr",
         })
     }
 }
@@ -514,6 +521,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         }
 
         let dl = self.cx.data_layout();
+        // bail if the enum has an incoherent repr that cannot be computed
+        if repr.packed() {
+            return Err(LayoutCalculatorError::ReprConflict);
+        }
 
         let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx, VariantIdx>> {
             if dont_niche_optimize_enum {
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 84d756b6d51..8e90130da4c 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -29,14 +29,14 @@ mod layout;
 mod tests;
 
 pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind};
-pub use layout::{
-    FIRST_VARIANT, FieldIdx, Layout, LayoutCalculator, LayoutCalculatorError, TyAbiInterface,
-    TyAndLayout, VariantIdx,
-};
+#[cfg(feature = "nightly")]
+pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx};
+pub use layout::{LayoutCalculator, LayoutCalculatorError};
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
 /// instead of implementing everything in `rustc_middle`.
+#[cfg(feature = "nightly")]
 pub trait HashStableContext {}
 
 #[derive(Clone, Copy, PartialEq, Eq, Default)]
@@ -1644,6 +1644,14 @@ pub struct LayoutS<FieldIdx: Idx, VariantIdx: Idx> {
 }
 
 impl<FieldIdx: Idx, VariantIdx: Idx> LayoutS<FieldIdx, VariantIdx> {
+    /// Returns `true` if this is an aggregate type (including a ScalarPair!)
+    pub fn is_aggregate(&self) -> bool {
+        match self.abi {
+            Abi::Uninhabited | Abi::Scalar(_) | Abi::Vector { .. } => false,
+            Abi::ScalarPair(..) | Abi::Aggregate { .. } => true,
+        }
+    }
+
     pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
         let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
         let size = scalar.size(cx);
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index cecf223b961..4d8525989cc 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -23,7 +23,6 @@
 #![feature(maybe_uninit_slice)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![feature(strict_provenance)]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index f2773dcdc60..94fcfabc32c 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -600,59 +600,61 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
 }
 
 fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate) {
-    // checks if `#![feature]` has been used to enable any lang feature
-    // does not check the same for lib features unless there's at least one
-    // declared lang feature
-    if !sess.opts.unstable_features.is_nightly_build() {
-        if features.declared_features.is_empty() {
-            return;
-        }
-        for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
-            let mut err = errors::FeatureOnNonNightly {
-                span: attr.span,
-                channel: option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"),
-                stable_features: vec![],
-                sugg: None,
-            };
-
-            let mut all_stable = true;
-            for ident in
-                attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident())
-            {
-                let name = ident.name;
-                let stable_since = features
-                    .declared_lang_features
-                    .iter()
-                    .flat_map(|&(feature, _, since)| if feature == name { since } else { None })
-                    .next();
-                if let Some(since) = stable_since {
-                    err.stable_features.push(errors::StableFeature { name, since });
-                } else {
-                    all_stable = false;
-                }
-            }
-            if all_stable {
-                err.sugg = Some(attr.span);
+    // checks if `#![feature]` has been used to enable any feature.
+    if sess.opts.unstable_features.is_nightly_build() {
+        return;
+    }
+    if features.enabled_features().is_empty() {
+        return;
+    }
+    let mut errored = false;
+    for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
+        // `feature(...)` used on non-nightly. This is definitely an error.
+        let mut err = errors::FeatureOnNonNightly {
+            span: attr.span,
+            channel: option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"),
+            stable_features: vec![],
+            sugg: None,
+        };
+
+        let mut all_stable = true;
+        for ident in attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident()) {
+            let name = ident.name;
+            let stable_since = features
+                .enabled_lang_features()
+                .iter()
+                .flat_map(|&(feature, _, since)| if feature == name { since } else { None })
+                .next();
+            if let Some(since) = stable_since {
+                err.stable_features.push(errors::StableFeature { name, since });
+            } else {
+                all_stable = false;
             }
-            sess.dcx().emit_err(err);
         }
+        if all_stable {
+            err.sugg = Some(attr.span);
+        }
+        sess.dcx().emit_err(err);
+        errored = true;
     }
+    // Just make sure we actually error if anything is listed in `enabled_features`.
+    assert!(errored);
 }
 
 fn check_incompatible_features(sess: &Session, features: &Features) {
-    let declared_features = features
-        .declared_lang_features
+    let enabled_features = features
+        .enabled_lang_features()
         .iter()
         .copied()
         .map(|(name, span, _)| (name, span))
-        .chain(features.declared_lib_features.iter().copied());
+        .chain(features.enabled_lib_features().iter().copied());
 
     for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES
         .iter()
-        .filter(|&&(f1, f2)| features.active(f1) && features.active(f2))
+        .filter(|&&(f1, f2)| features.enabled(f1) && features.enabled(f2))
     {
-        if let Some((f1_name, f1_span)) = declared_features.clone().find(|(name, _)| name == f1) {
-            if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2)
+        if let Some((f1_name, f1_span)) = enabled_features.clone().find(|(name, _)| name == f1) {
+            if let Some((f2_name, f2_span)) = enabled_features.clone().find(|(name, _)| name == f2)
             {
                 let spans = vec![f1_span, f2_span];
                 sess.dcx().emit_err(errors::IncompatibleFeatures {
@@ -672,7 +674,7 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) {
 
     // Ban GCE with the new solver, because it does not implement GCE correctly.
     if let Some(&(_, gce_span, _)) = features
-        .declared_lang_features
+        .enabled_lang_features()
         .iter()
         .find(|&&(feat, _, _)| feat == sym::generic_const_exprs)
     {
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index cbf8aa313c5..698fdafc936 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -187,10 +187,10 @@ fn do_mir_borrowck<'tcx>(
 
     let location_table = LocationTable::new(body);
 
-    let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
+    let move_data = MoveData::gather_moves(body, tcx, |_| true);
     let promoted_move_data = promoted
         .iter_enumerated()
-        .map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, param_env, |_| true)));
+        .map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, |_| true)));
 
     let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
         .into_engine(tcx, body)
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 238d7d0749a..7b60a632c30 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1128,7 +1128,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             }
             let projected_ty = curr_projected_ty.projection_ty_core(
                 tcx,
-                self.param_env,
                 proj,
                 |this, field, ()| {
                     let ty = this.field_ty(tcx, field);
@@ -1919,7 +1918,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 // than 1.
                 // If the length is larger than 1, the repeat expression will need to copy the
                 // element, so we require the `Copy` trait.
-                if len.try_eval_target_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
+                if len.try_to_target_usize(tcx).is_none_or(|len| len > 1) {
                     match operand {
                         Operand::Copy(..) | Operand::Constant(..) => {
                             // These are always okay: direct use of a const, or a value that can evidently be copied.
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index cbe411d78d5..e7f9f894381 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -133,6 +133,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                 .expect_const()
                 .try_to_valtree()
                 .expect("expected monomorphic const in codegen")
+                .0
                 .unwrap_branch();
 
             assert_eq!(x.layout(), y.layout());
@@ -806,8 +807,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                 ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => m.load_scalar(fx),
                 ty::Array(elem, len)
                     if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
-                        && len.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
-                            == Some(expected_bytes) =>
+                        && len
+                            .try_to_target_usize(fx.tcx)
+                            .expect("expected monomorphic const in codegen")
+                            == expected_bytes =>
                 {
                     m.force_stack(fx).0.load(
                         fx,
@@ -907,8 +910,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                 ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => {}
                 ty::Array(elem, len)
                     if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
-                        && len.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
-                            == Some(expected_bytes) => {}
+                        && len
+                            .try_to_target_usize(fx.tcx)
+                            .expect("expected monomorphic const in codegen")
+                            == expected_bytes => {}
                 _ => {
                     fx.tcx.dcx().span_fatal(
                         span,
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index b611f9ba8bc..45738068509 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -30,7 +30,7 @@ use rustc_middle::ty::{Instance, ParamEnv, Ty, TyCtxt};
 use rustc_span::Span;
 use rustc_span::def_id::DefId;
 use rustc_target::abi::call::FnAbi;
-use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, WasmCAbi};
+use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, WasmCAbi, X86Abi};
 
 use crate::common::{SignType, TypeReflection, type_is_pointer};
 use crate::context::CodegenCx;
@@ -2347,6 +2347,12 @@ impl<'tcx> HasWasmCAbiOpt for Builder<'_, '_, 'tcx> {
     }
 }
 
+impl<'tcx> HasX86AbiOpt for Builder<'_, '_, 'tcx> {
+    fn x86_abi_opt(&self) -> X86Abi {
+        self.cx.x86_abi_opt()
+    }
+}
+
 pub trait ToGccComp {
     fn to_gcc_comparison(&self) -> ComparisonOp;
 }
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 7cb49bf7991..707b35967a6 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -19,7 +19,9 @@ use rustc_session::Session;
 use rustc_span::source_map::respan;
 use rustc_span::{DUMMY_SP, Span};
 use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
-use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, TlsModel, WasmCAbi};
+use rustc_target::spec::{
+    HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi,
+};
 
 use crate::callee::get_fn;
 use crate::common::SignType;
@@ -538,6 +540,12 @@ impl<'gcc, 'tcx> HasWasmCAbiOpt for CodegenCx<'gcc, 'tcx> {
     }
 }
 
+impl<'gcc, 'tcx> HasX86AbiOpt for CodegenCx<'gcc, 'tcx> {
+    fn x86_abi_opt(&self) -> X86Abi {
+        X86Abi { regparm: self.tcx.sess.opts.unstable_opts.regparm }
+    }
+}
+
 impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 4e1b99fdebf..43dbfafa871 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -76,8 +76,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
             ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
             ty::Array(elem, len)
                 if matches!(*elem.kind(), ty::Uint(ty::UintTy::U8))
-                    && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all())
-                        == Some(expected_bytes) =>
+                    && len
+                        .try_to_target_usize(bx.tcx)
+                        .expect("expected monomorphic const in codegen")
+                        == expected_bytes =>
             {
                 let place = PlaceRef::alloca(bx, args[0].layout);
                 args[0].val.store(bx, place);
@@ -696,8 +698,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
             }
             ty::Array(elem, len)
                 if matches!(*elem.kind(), ty::Uint(ty::UintTy::U8))
-                    && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all())
-                        == Some(expected_bytes) =>
+                    && len
+                        .try_to_target_usize(bx.tcx)
+                        .expect("expected monomorphic const in codegen")
+                        == expected_bytes =>
             {
                 // Zero-extend iN to the array length:
                 let ze = bx.zext(result, bx.type_ix(expected_bytes * 8));
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 4075849323a..cee704a9c22 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -1,3 +1,5 @@
+use std::ffi::CStr;
+
 use itertools::Itertools as _;
 use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
@@ -305,7 +307,7 @@ fn generate_coverage_map<'ll>(
 /// specific, well-known section and name.
 fn save_function_record(
     cx: &CodegenCx<'_, '_>,
-    covfun_section_name: &str,
+    covfun_section_name: &CStr,
     mangled_function_name: &str,
     source_hash: u64,
     filenames_ref: u64,
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 4f93e6ab1e5..484a4d00c13 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -1,5 +1,5 @@
 use std::cell::RefCell;
-use std::ffi::CString;
+use std::ffi::{CStr, CString};
 
 use libc::c_uint;
 use rustc_codegen_ssa::traits::{
@@ -292,10 +292,10 @@ pub(crate) fn save_cov_data_to_mod<'ll, 'tcx>(
     .unwrap();
     debug!("covmap var name: {:?}", covmap_var_name);
 
-    let covmap_section_name = llvm::build_string(|s| unsafe {
+    let covmap_section_name = CString::new(llvm::build_byte_buffer(|s| unsafe {
         llvm::LLVMRustCoverageWriteMapSectionNameToString(cx.llmod, s);
-    })
-    .expect("Rust Coverage section name failed UTF-8 conversion");
+    }))
+    .expect("covmap section name should not contain NUL");
     debug!("covmap section name: {:?}", covmap_section_name);
 
     let llglobal = llvm::add_global(cx.llmod, cx.val_ty(cov_data_val), &covmap_var_name);
@@ -310,7 +310,7 @@ pub(crate) fn save_cov_data_to_mod<'ll, 'tcx>(
 
 pub(crate) fn save_func_record_to_mod<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
-    covfun_section_name: &str,
+    covfun_section_name: &CStr,
     func_name_hash: u64,
     func_record_val: &'ll llvm::Value,
     is_used: bool,
@@ -354,9 +354,9 @@ pub(crate) fn save_func_record_to_mod<'ll, 'tcx>(
 /// - `__llvm_covfun` on Linux
 /// - `__LLVM_COV,__llvm_covfun` on macOS (includes `__LLVM_COV,` segment prefix)
 /// - `.lcovfun$M` on Windows (includes `$M` sorting suffix)
-pub(crate) fn covfun_section_name(cx: &CodegenCx<'_, '_>) -> String {
-    llvm::build_string(|s| unsafe {
+pub(crate) fn covfun_section_name(cx: &CodegenCx<'_, '_>) -> CString {
+    CString::new(llvm::build_byte_buffer(|s| unsafe {
         llvm::LLVMRustCoverageWriteFuncSectionNameToString(cx.llmod, s);
-    })
-    .expect("Rust Coverage function record section name failed UTF-8 conversion")
+    }))
+    .expect("covfun section name should not contain NUL")
 }
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 64f1d21b438..c9a17c9852d 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1179,8 +1179,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
             ty::Array(elem, len)
                 if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
-                    && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all())
-                        == Some(expected_bytes) =>
+                    && len
+                        .try_to_target_usize(bx.tcx)
+                        .expect("expected monomorphic const in codegen")
+                        == expected_bytes =>
             {
                 let place = PlaceRef::alloca(bx, args[0].layout);
                 args[0].val.store(bx, place);
@@ -1245,12 +1247,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     }
 
     if name == sym::simd_shuffle_generic {
-        let idx = fn_args[2]
-            .expect_const()
-            .eval(tcx, ty::ParamEnv::reveal_all(), span)
-            .unwrap()
-            .1
-            .unwrap_branch();
+        let idx = fn_args[2].expect_const().try_to_valtree().unwrap().0.unwrap_branch();
         let n = idx.len() as u64;
 
         let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
@@ -1469,8 +1466,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             }
             ty::Array(elem, len)
                 if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
-                    && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all())
-                        == Some(expected_bytes) =>
+                    && len
+                        .try_to_target_usize(bx.tcx)
+                        .expect("expected monomorphic const in codegen")
+                        == expected_bytes =>
             {
                 // Zero-extend iN to the array length:
                 let ze = bx.zext(i_, bx.type_ix(expected_bytes * 8));
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index b306396e15a..e837022044e 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -210,10 +210,9 @@ impl MemoryEffects {
     }
 }
 
-pub fn set_section(llglobal: &Value, section_name: &str) {
-    let section_name_cstr = CString::new(section_name).expect("unexpected CString error");
+pub fn set_section(llglobal: &Value, section_name: &CStr) {
     unsafe {
-        LLVMSetSection(llglobal, section_name_cstr.as_ptr());
+        LLVMSetSection(llglobal, section_name.as_ptr());
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 369ab387bea..526d2b86d48 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -23,7 +23,6 @@ use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
 use rustc_middle::ty::{
     self, ExistentialProjection, GenericArgKind, GenericArgsRef, ParamEnv, Ty, TyCtxt,
 };
-use rustc_span::DUMMY_SP;
 use rustc_target::abi::Integer;
 use smallvec::SmallVec;
 
@@ -685,21 +684,25 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
         ty::ConstKind::Param(param) => {
             write!(output, "{}", param.name)
         }
-        ty::ConstKind::Value(ty, _) => {
+        ty::ConstKind::Value(ty, valtree) => {
             match ty.kind() {
                 ty::Int(ity) => {
                     // FIXME: directly extract the bits from a valtree instead of evaluating an
                     // already evaluated `Const` in order to get the bits.
-                    let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
+                    let bits = ct
+                        .try_to_bits(tcx, ty::ParamEnv::reveal_all())
+                        .expect("expected monomorphic const in codegen");
                     let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
                     write!(output, "{val}")
                 }
                 ty::Uint(_) => {
-                    let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
+                    let val = ct
+                        .try_to_bits(tcx, ty::ParamEnv::reveal_all())
+                        .expect("expected monomorphic const in codegen");
                     write!(output, "{val}")
                 }
                 ty::Bool => {
-                    let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
+                    let val = ct.try_to_bool().expect("expected monomorphic const in codegen");
                     write!(output, "{val}")
                 }
                 _ => {
@@ -711,8 +714,9 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
                     // avoiding collisions and will make the emitted type names shorter.
                     let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
                         let mut hasher = StableHasher::new();
-                        let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
-                        hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
+                        hcx.while_hashing_spans(false, |hcx| {
+                            (ty, valtree).hash_stable(hcx, &mut hasher)
+                        });
                         hasher.finish::<Hash64>()
                     });
 
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index cbd95146294..73bfa9dbd10 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -11,7 +11,6 @@
 #![feature(let_chains)]
 #![feature(negative_impls)]
 #![feature(rustdoc_internals)]
-#![feature(strict_provenance)]
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![warn(unreachable_pub)]
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index a132ca69540..82fea4c58e1 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -361,12 +361,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             (Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty),
             (Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
             (Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm),
-            (Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty),
+            (Pointer(..), Int(..)) => {
+                // FIXME: this exposes the provenance, which shouldn't be necessary.
+                bx.ptrtoint(imm, to_backend_ty)
+            }
             (Float(_), Pointer(..)) => {
                 let int_imm = bx.bitcast(imm, bx.cx().type_isize());
                 bx.ptradd(bx.const_null(bx.type_ptr()), int_imm)
             }
             (Pointer(..), Float(_)) => {
+                // FIXME: this exposes the provenance, which shouldn't be necessary.
                 let int_imm = bx.ptrtoint(imm, bx.cx().type_isize());
                 bx.bitcast(int_imm, to_backend_ty)
             }
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 463a66d4e2e..73344508a9d 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -276,7 +276,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         let gate = match op.status_in_item(self.ccx) {
             Status::Allowed => return,
 
-            Status::Unstable(gate) if self.tcx.features().active(gate) => {
+            Status::Unstable(gate) if self.tcx.features().enabled(gate) => {
                 let unstable_in_stable = self.ccx.is_const_stable_const_fn()
                     && !super::rustc_allow_const_fn_unstable(self.tcx, self.def_id(), gate);
                 if unstable_in_stable {
@@ -700,10 +700,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     // Calling an unstable function *always* requires that the corresponding gate
                     // (or implied gate) be enabled, even if the function has
                     // `#[rustc_allow_const_fn_unstable(the_gate)]`.
-                    let gate_declared = |gate| tcx.features().declared(gate);
-                    let feature_gate_declared = gate_declared(gate);
-                    let implied_gate_declared = implied_by.is_some_and(gate_declared);
-                    if !feature_gate_declared && !implied_gate_declared {
+                    let gate_enabled = |gate| tcx.features().enabled(gate);
+                    let feature_gate_enabled = gate_enabled(gate);
+                    let implied_gate_enabled = implied_by.is_some_and(gate_enabled);
+                    if !feature_gate_enabled && !implied_gate_enabled {
                         self.check_op(ops::FnCallUnstable(callee, Some(gate)));
                         return;
                     }
@@ -717,7 +717,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
                     // Otherwise, we are something const-stable calling a const-unstable fn.
                     if super::rustc_allow_const_fn_unstable(tcx, caller, gate) {
-                        trace!("rustc_allow_const_fn_unstable gate active");
+                        trace!("rustc_allow_const_fn_unstable gate enabled");
                         return;
                     }
 
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index 7358a6c6d22..547030a1854 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -6,13 +6,10 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_hir::LangItem;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir::*;
-use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty};
 use rustc_middle::{bug, mir};
-use rustc_trait_selection::traits::{
-    ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
-};
-use tracing::{instrument, trace};
+use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
+use tracing::instrument;
 
 use super::ConstCx;
 
@@ -195,50 +192,8 @@ impl Qualif for NeedsNonConstDrop {
             return false;
         }
 
-        // FIXME(effects): If `destruct` is not a `const_trait`,
-        // or effects are disabled in this crate, then give up.
-        let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span));
-        if !cx.tcx.has_host_param(destruct_def_id) || !cx.tcx.features().effects {
-            return NeedsDrop::in_any_value_of_ty(cx, ty);
-        }
-
-        let obligation = Obligation::new(
-            cx.tcx,
-            ObligationCause::dummy_with_span(cx.body.span),
-            cx.param_env,
-            ty::TraitRef::new(cx.tcx, destruct_def_id, [
-                ty::GenericArg::from(ty),
-                ty::GenericArg::from(cx.tcx.expected_host_effect_param_for_body(cx.def_id())),
-            ]),
-        );
-
-        let infcx = cx.tcx.infer_ctxt().build();
-        let mut selcx = SelectionContext::new(&infcx);
-        let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
-            // If we couldn't select a const destruct candidate, then it's bad
-            return true;
-        };
-
-        trace!(?impl_src);
-
-        if !matches!(
-            impl_src,
-            ImplSource::Builtin(BuiltinImplSource::Misc, _) | ImplSource::Param(_)
-        ) {
-            // If our const destruct candidate is not ConstDestruct or implied by the param env,
-            // then it's bad
-            return true;
-        }
-
-        if impl_src.borrow_nested_obligations().is_empty() {
-            return false;
-        }
-
-        // If we had any errors, then it's bad
-        let ocx = ObligationCtxt::new(&infcx);
-        ocx.register_obligations(impl_src.nested_obligations());
-        let errors = ocx.select_all_or_error();
-        !errors.is_empty()
+        // FIXME(effects): Reimplement const drop checking.
+        NeedsDrop::in_any_value_of_ty(cx, ty)
     }
 
     fn in_adt_inherently<'tcx>(
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index ba19f642795..e2e4754a45c 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -43,7 +43,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
 
     // We go to `usize` as we cannot allocate anything bigger anyway.
     let (field_count, variant, down) = match ty.kind() {
-        ty::Array(_, len) => (len.eval_target_usize(tcx.tcx, param_env) as usize, None, op),
+        ty::Array(_, len) => (len.try_to_target_usize(tcx.tcx)? as usize, None, op),
         ty::Adt(def, _) if def.variants().is_empty() => {
             return None;
         }
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index 1def3d08328..64b15611316 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -391,7 +391,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let ptr = self.read_pointer(src)?;
                 let val = Immediate::new_slice(
                     ptr,
-                    length.eval_target_usize(*self.tcx, self.param_env),
+                    length
+                        .try_to_target_usize(*self.tcx)
+                        .expect("expected monomorphic const in const eval"),
                     self,
                 );
                 self.write_immediate(val, dest)
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 39e2d3b4ebb..0490195caf4 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -10,7 +10,6 @@
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
 #![feature(slice_ptr_get)]
-#![feature(strict_provenance)]
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(unqualified_local_imports)]
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index d73cf11ee64..5a477143a62 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -13,7 +13,7 @@ ena = "0.14.3"
 indexmap = { version = "2.4.0" }
 jobserver_crate = { version = "0.1.28", package = "jobserver" }
 measureme = "11"
-rustc-hash = "1.1.0"
+rustc-hash = "2.0.0"
 rustc-rayon = { version = "0.5.0", optional = true }
 rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
 rustc_arena = { path = "../rustc_arena" }
diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
index 7cb013fdbd8..85b030c1a48 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
@@ -9,8 +9,6 @@
 //! Thomas Lengauer and Robert Endre Tarjan.
 //! <https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf>
 
-use std::cmp::Ordering;
-
 use rustc_index::{Idx, IndexSlice, IndexVec};
 
 use super::ControlFlowGraph;
@@ -64,9 +62,6 @@ fn is_small_path_graph<G: ControlFlowGraph>(g: &G) -> bool {
 }
 
 fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
-    // compute the post order index (rank) for each node
-    let mut post_order_rank = IndexVec::from_elem_n(0, graph.num_nodes());
-
     // We allocate capacity for the full set of nodes, because most of the time
     // most of the nodes *are* reachable.
     let mut parent: IndexVec<PreorderIndex, PreorderIndex> =
@@ -83,12 +78,10 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
     pre_order_to_real.push(graph.start_node());
     parent.push(PreorderIndex::ZERO); // the parent of the root node is the root for now.
     real_to_pre_order[graph.start_node()] = Some(PreorderIndex::ZERO);
-    let mut post_order_idx = 0;
 
     // Traverse the graph, collecting a number of things:
     //
     // * Preorder mapping (to it, and back to the actual ordering)
-    // * Postorder mapping (used exclusively for `cmp_in_dominator_order` on the final product)
     // * Parents for each vertex in the preorder tree
     //
     // These are all done here rather than through one of the 'standard'
@@ -104,8 +97,6 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
                 continue 'recurse;
             }
         }
-        post_order_rank[pre_order_to_real[frame.pre_order_idx]] = post_order_idx;
-        post_order_idx += 1;
 
         stack.pop();
     }
@@ -282,7 +273,7 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
 
     let time = compute_access_time(start_node, &immediate_dominators);
 
-    Inner { post_order_rank, immediate_dominators, time }
+    Inner { immediate_dominators, time }
 }
 
 /// Evaluate the link-eval virtual forest, providing the currently minimum semi
@@ -348,7 +339,6 @@ fn compress(
 /// Tracks the list of dominators for each node.
 #[derive(Clone, Debug)]
 struct Inner<N: Idx> {
-    post_order_rank: IndexVec<N, usize>,
     // Even though we track only the immediate dominator of each node, it's
     // possible to get its full list of dominators by looking up the dominator
     // of each dominator.
@@ -379,17 +369,6 @@ impl<Node: Idx> Dominators<Node> {
         }
     }
 
-    /// Provide deterministic ordering of nodes such that, if any two nodes have a dominator
-    /// relationship, the dominator will always precede the dominated. (The relative ordering
-    /// of two unrelated nodes will also be consistent, but otherwise the order has no
-    /// meaning.) This method cannot be used to determine if either Node dominates the other.
-    pub fn cmp_in_dominator_order(&self, lhs: Node, rhs: Node) -> Ordering {
-        match &self.kind {
-            Kind::Path => lhs.index().cmp(&rhs.index()),
-            Kind::General(g) => g.post_order_rank[rhs].cmp(&g.post_order_rank[lhs]),
-        }
-    }
-
     /// Returns true if `a` dominates `b`.
     ///
     /// # Panics
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index fba2707922b..afac08ae6f8 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -33,7 +33,6 @@
 #![feature(ptr_alignment_type)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![feature(strict_provenance)]
 #![feature(test)]
 #![feature(thread_id_value)]
 #![feature(type_alias_impl_trait)]
diff --git a/compiler/rustc_error_codes/src/error_codes/E0636.md b/compiler/rustc_error_codes/src/error_codes/E0636.md
index 57cf72db556..41fd701a8ed 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0636.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0636.md
@@ -1,9 +1,9 @@
-A `#![feature]` attribute was declared multiple times.
+The same feature is enabled multiple times with `#![feature]` attributes
 
 Erroneous code example:
 
 ```compile_fail,E0636
 #![allow(stable_features)]
 #![feature(rust1)]
-#![feature(rust1)] // error: the feature `rust1` has already been declared
+#![feature(rust1)] // error: the feature `rust1` has already been enabled
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0705.md b/compiler/rustc_error_codes/src/error_codes/E0705.md
index 317f3a47eff..e7d7d74cc4c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0705.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0705.md
@@ -1,6 +1,6 @@
 #### Note: this error code is no longer emitted by the compiler.
 
-A `#![feature]` attribute was declared for a feature that is stable in the
+A `#![feature]` attribute was used for a feature that is stable in the
 current edition, but not in all editions.
 
 Erroneous code example:
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index f0cfe133a49..bed500c3032 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1,5 +1,6 @@
 use std::default::Default;
 use std::iter;
+use std::path::Component::Prefix;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
 
@@ -1293,7 +1294,12 @@ pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PRe
         base_path.push(path);
         Ok(base_path)
     } else {
-        Ok(path)
+        // This ensures that Windows verbatim paths are fixed if mixed path separators are used,
+        // which can happen when `concat!` is used to join paths.
+        match path.components().next() {
+            Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
+            _ => Ok(path),
+        }
     }
 }
 
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index ea06415801f..a6b7291ee8f 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -52,7 +52,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
 
     let mut features = Features::default();
 
-    // Process all features declared in the code.
+    // Process all features enabled in the code.
     for attr in krate_attrs {
         for mi in feature_list(attr) {
             let name = match mi.ident() {
@@ -76,7 +76,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
                 }
             };
 
-            // If the declared feature has been removed, issue an error.
+            // If the enabled feature has been removed, issue an error.
             if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) {
                 sess.dcx().emit_err(FeatureRemoved {
                     span: mi.span(),
@@ -85,14 +85,14 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
                 continue;
             }
 
-            // If the declared feature is stable, record it.
+            // If the enabled feature is stable, record it.
             if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
                 let since = Some(Symbol::intern(f.since));
-                features.set_declared_lang_feature(name, mi.span(), since);
+                features.set_enabled_lang_feature(name, mi.span(), since, None);
                 continue;
             }
 
-            // If `-Z allow-features` is used and the declared feature is
+            // If `-Z allow-features` is used and the enabled feature is
             // unstable and not also listed as one of the allowed features,
             // issue an error.
             if let Some(allowed) = sess.opts.unstable_opts.allow_features.as_ref() {
@@ -102,9 +102,8 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
                 }
             }
 
-            // If the declared feature is unstable, record it.
+            // If the enabled feature is unstable, record it.
             if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) {
-                (f.set_enabled)(&mut features);
                 // When the ICE comes from core, alloc or std (approximation of the standard
                 // library), there's a chance that the person hitting the ICE may be using
                 // -Zbuild-std or similar with an untested target. The bug is probably in the
@@ -115,13 +114,13 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
                 {
                     sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
                 }
-                features.set_declared_lang_feature(name, mi.span(), None);
+                features.set_enabled_lang_feature(name, mi.span(), None, Some(f));
                 continue;
             }
 
-            // Otherwise, the feature is unknown. Record it as a lib feature.
-            // It will be checked later.
-            features.set_declared_lib_feature(name, mi.span());
+            // Otherwise, the feature is unknown. Enable it as a lib feature.
+            // It will be checked later whether the feature really exists.
+            features.set_enabled_lib_feature(name, mi.span());
 
             // Similar to above, detect internal lib features to suppress
             // the ICE message that asks for a report.
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index 2edd289625e..e518b27e419 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -119,7 +119,7 @@ pub(super) fn parse(
     result
 }
 
-/// Asks for the `macro_metavar_expr` feature if it is not already declared
+/// Asks for the `macro_metavar_expr` feature if it is not enabled
 fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &Session, span: Span) {
     if !features.macro_metavar_expr {
         let msg = "meta-variable expressions are unstable";
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 0c5fe6e8d8b..53445804694 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -353,6 +353,9 @@ declare_features! (
     (accepted, repr_packed, "1.33.0", Some(33158)),
     /// Allows `#[repr(transparent)]` attribute on newtype structs.
     (accepted, repr_transparent, "1.28.0", Some(43036)),
+    /// Allows enums like Result<T, E> to be used across FFI, if T's niche value can
+    /// be used to describe E or vice-versa.
+    (accepted, result_ffi_guarantees, "CURRENT_RUSTC_VERSION", Some(110503)),
     /// Allows return-position `impl Trait` in traits.
     (accepted, return_position_impl_trait_in_trait, "1.75.0", Some(91611)),
     /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 1067156958d..0606f2914c3 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -8,7 +8,7 @@ use super::{Feature, to_nonzero};
 
 pub struct UnstableFeature {
     pub feature: Feature,
-    pub set_enabled: fn(&mut Features),
+    set_enabled: fn(&mut Features),
 }
 
 #[derive(PartialEq)]
@@ -54,14 +54,13 @@ macro_rules! declare_features {
         #[derive(Clone, Default, Debug)]
         pub struct Features {
             /// `#![feature]` attrs for language features, for error reporting.
-            /// "declared" here means that the feature is actually enabled in the current crate.
-            pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
+            enabled_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
             /// `#![feature]` attrs for non-language (library) features.
-            /// "declared" here means that the feature is actually enabled in the current crate.
-            pub declared_lib_features: Vec<(Symbol, Span)>,
-            /// `declared_lang_features` + `declared_lib_features`.
-            pub declared_features: FxHashSet<Symbol>,
-            /// Active state of individual features (unstable only).
+            enabled_lib_features: Vec<(Symbol, Span)>,
+            /// `enabled_lang_features` + `enabled_lib_features`.
+            enabled_features: FxHashSet<Symbol>,
+            /// State of individual features (unstable lang features only).
+            /// This is `true` if and only if the corresponding feature is listed in `enabled_lang_features`.
             $(
                 $(#[doc = $doc])*
                 pub $feature: bool
@@ -69,46 +68,71 @@ macro_rules! declare_features {
         }
 
         impl Features {
-            pub fn set_declared_lang_feature(
+            pub fn set_enabled_lang_feature(
                 &mut self,
-                symbol: Symbol,
+                name: Symbol,
                 span: Span,
-                since: Option<Symbol>
+                since: Option<Symbol>,
+                feature: Option<&UnstableFeature>,
             ) {
-                self.declared_lang_features.push((symbol, span, since));
-                self.declared_features.insert(symbol);
+                self.enabled_lang_features.push((name, span, since));
+                self.enabled_features.insert(name);
+                if let Some(feature) = feature {
+                    assert_eq!(feature.feature.name, name);
+                    (feature.set_enabled)(self);
+                } else {
+                    // Ensure we don't skip a `set_enabled` call.
+                    debug_assert!(UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_none());
+                }
             }
 
-            pub fn set_declared_lib_feature(&mut self, symbol: Symbol, span: Span) {
-                self.declared_lib_features.push((symbol, span));
-                self.declared_features.insert(symbol);
+            pub fn set_enabled_lib_feature(&mut self, name: Symbol, span: Span) {
+                self.enabled_lib_features.push((name, span));
+                self.enabled_features.insert(name);
+                // Ensure we don't skip a `set_enabled` call.
+                debug_assert!(UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_none());
             }
 
-            /// This is intended for hashing the set of active features.
+            /// This is intended for hashing the set of enabled language features.
             ///
             /// The expectation is that this produces much smaller code than other alternatives.
             ///
             /// Note that the total feature count is pretty small, so this is not a huge array.
             #[inline]
-            pub fn all_features(&self) -> [u8; NUM_FEATURES] {
+            pub fn all_lang_features(&self) -> [u8; NUM_FEATURES] {
                 [$(self.$feature as u8),+]
             }
 
-            /// Is the given feature explicitly declared, i.e. named in a
-            /// `#![feature(...)]` within the code?
-            pub fn declared(&self, feature: Symbol) -> bool {
-                self.declared_features.contains(&feature)
+            pub fn enabled_lang_features(&self) -> &Vec<(Symbol, Span, Option<Symbol>)> {
+                &self.enabled_lang_features
             }
 
-            /// Is the given feature active (enabled by the user)?
-            ///
-            /// Panics if the symbol doesn't correspond to a declared feature.
-            pub fn active(&self, feature: Symbol) -> bool {
-                match feature {
-                    $( sym::$feature => self.$feature, )*
+            pub fn enabled_lib_features(&self) -> &Vec<(Symbol, Span)> {
+                &self.enabled_lib_features
+            }
 
-                    _ => panic!("`{}` was not listed in `declare_features`", feature),
+            pub fn enabled_features(&self) -> &FxHashSet<Symbol> {
+                &self.enabled_features
+            }
+
+            /// Is the given feature enabled (via `#[feature(...)]`)?
+            pub fn enabled(&self, feature: Symbol) -> bool {
+                let e = self.enabled_features.contains(&feature);
+                if cfg!(debug_assertions) {
+                    // Ensure this matches `self.$feature`, if that exists.
+                    let e2 = match feature {
+                        $( sym::$feature => Some(self.$feature), )*
+                        _ => None,
+                    };
+                    if let Some(e2) = e2 {
+                        assert_eq!(
+                            e, e2,
+                            "mismatch in feature state for `{feature}`: \
+                            `enabled_features` says {e} but `self.{feature}` says {e2}"
+                        );
+                    }
                 }
+                e
             }
 
             /// Some features are known to be incomplete and using them is likely to have
@@ -119,8 +143,11 @@ macro_rules! declare_features {
                     $(
                         sym::$feature => status_to_enum!($status) == FeatureStatus::Incomplete,
                     )*
-                    // Accepted/removed features aren't in this file but are never incomplete.
-                    _ if self.declared_features.contains(&feature) => false,
+                    _ if self.enabled_features.contains(&feature) => {
+                        // Accepted/removed features and library features aren't in this file but
+                        // are never incomplete.
+                        false
+                    }
                     _ => panic!("`{}` was not listed in `declare_features`", feature),
                 }
             }
@@ -132,7 +159,7 @@ macro_rules! declare_features {
                     $(
                         sym::$feature => status_to_enum!($status) == FeatureStatus::Internal,
                     )*
-                    _ if self.declared_features.contains(&feature) => {
+                    _ if self.enabled_features.contains(&feature) => {
                         // This could be accepted/removed, or a libs feature.
                         // Accepted/removed features aren't in this file but are never internal
                         // (a removed feature might have been internal, but that's now irrelevant).
@@ -580,9 +607,6 @@ declare_features! (
     (incomplete, repr128, "1.16.0", Some(56071)),
     /// Allows `repr(simd)` and importing the various simd intrinsics.
     (unstable, repr_simd, "1.4.0", Some(27731)),
-    /// Allows enums like Result<T, E> to be used across FFI, if T's niche value can
-    /// be used to describe E or vise-versa.
-    (unstable, result_ffi_guarantees, "1.80.0", Some(110503)),
     /// Allows bounding the return type of AFIT/RPITIT.
     (unstable, return_type_notation, "1.70.0", Some(109417)),
     /// Allows `extern "rust-cold"`.
@@ -598,7 +622,7 @@ declare_features! (
     /// Allows attributes on expressions and non-item statements.
     (unstable, stmt_expr_attributes, "1.6.0", Some(15701)),
     /// Allows lints part of the strict provenance effort.
-    (unstable, strict_provenance, "1.61.0", Some(95228)),
+    (unstable, strict_provenance_lints, "1.61.0", Some(130351)),
     /// Allows string patterns to dereference values to match them.
     (unstable, string_deref_patterns, "1.67.0", Some(87121)),
     /// Allows the use of `#[target_feature]` on safe functions.
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index 7f4ab352ef2..9a2c38e51e2 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -51,7 +51,7 @@ impl<'tcx> Bounds<'tcx> {
         bound_trait_ref: ty::PolyTraitRef<'tcx>,
         span: Span,
         polarity: ty::PredicatePolarity,
-        constness: ty::BoundConstness,
+        constness: Option<ty::BoundConstness>,
         predicate_filter: PredicateFilter,
     ) {
         let clause = (
@@ -88,19 +88,20 @@ impl<'tcx> Bounds<'tcx> {
         // associated type of `<T as Tr>` and make sure that the effect is compatible.
         let compat_val = match (tcx.def_kind(defining_def_id), constness) {
             // FIXME(effects): revisit the correctness of this
-            (_, ty::BoundConstness::Const) => tcx.consts.false_,
+            (_, Some(ty::BoundConstness::Const)) => tcx.consts.false_,
             // body owners that can have trait bounds
-            (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => {
-                tcx.expected_host_effect_param_for_body(defining_def_id)
-            }
+            (
+                DefKind::Const | DefKind::Fn | DefKind::AssocFn,
+                Some(ty::BoundConstness::ConstIfConst),
+            ) => tcx.expected_host_effect_param_for_body(defining_def_id),
 
-            (_, ty::BoundConstness::NotConst) => {
+            (_, None) => {
                 if !tcx.is_const_trait(bound_trait_ref.def_id()) {
                     return;
                 }
                 tcx.consts.true_
             }
-            (DefKind::Trait, ty::BoundConstness::ConstIfConst) => {
+            (DefKind::Trait, Some(ty::BoundConstness::ConstIfConst)) => {
                 // we are in a trait, where `bound_trait_ref` could be:
                 // (1) a super trait `trait Foo: ~const Bar`.
                 //     - This generates `<Self as Foo>::Effects: TyCompat<<Self as Bar>::Effects>`
@@ -138,7 +139,7 @@ impl<'tcx> Bounds<'tcx> {
                 return;
             }
 
-            (DefKind::Impl { of_trait: true }, ty::BoundConstness::ConstIfConst) => {
+            (DefKind::Impl { of_trait: true }, Some(ty::BoundConstness::ConstIfConst)) => {
                 // this is a where clause on an impl header.
                 // push `<T as Tr>::Effects` into the set for the `Min` bound.
                 let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
@@ -172,12 +173,12 @@ impl<'tcx> Bounds<'tcx> {
             //
             // FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor
             // that uses a `Bar` that implements `Trait` with `Maybe` effects.
-            (DefKind::AssocTy, ty::BoundConstness::ConstIfConst) => {
+            (DefKind::AssocTy, Some(ty::BoundConstness::ConstIfConst)) => {
                 // FIXME(effects): implement this
                 return;
             }
             // probably illegal in this position.
-            (_, ty::BoundConstness::ConstIfConst) => {
+            (_, Some(ty::BoundConstness::ConstIfConst)) => {
                 tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered");
                 return;
             }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 94da3d4ea84..2aeeb9450ce 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{
     AdtDef, GenericArgKind, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable,
     TypeVisitableExt,
 };
-use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
+use rustc_session::lint::builtin::UNINHABITED_STATIC;
 use rustc_target::abi::FieldIdx;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
@@ -36,36 +36,25 @@ use super::compare_impl_item::{check_type_bounds, compare_impl_method, compare_i
 use super::*;
 use crate::check::intrinsicck::InlineAsmCtxt;
 
-pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
-    match tcx.sess.target.is_abi_supported(abi) {
-        Some(true) => (),
-        Some(false) => {
-            struct_span_code_err!(
-                tcx.dcx(),
-                span,
-                E0570,
-                "`{abi}` is not a supported ABI for the current target",
-            )
-            .emit();
-        }
-        None => {
-            tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
-                lint.primary_message("use of calling convention not supported on this target");
-            });
-        }
+pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
+    if !tcx.sess.target.is_abi_supported(abi) {
+        struct_span_code_err!(
+            tcx.dcx(),
+            span,
+            E0570,
+            "`{abi}` is not a supported ABI for the current target",
+        )
+        .emit();
     }
 }
 
 pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
-    match tcx.sess.target.is_abi_supported(abi) {
-        Some(true) => (),
-        Some(false) | None => {
-            tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
-                lint.primary_message(format!(
-                    "the calling convention {abi} is not supported on this target"
-                ));
-            });
-        }
+    if !tcx.sess.target.is_abi_supported(abi) {
+        tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
+            lint.primary_message(format!(
+                "the calling convention {abi} is not supported on this target"
+            ));
+        });
     }
 }
 
@@ -705,7 +694,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
                 return;
             };
-            check_abi(tcx, it.hir_id(), it.span, abi);
+            check_abi(tcx, it.span, abi);
 
             match abi {
                 Abi::RustIntrinsic => {
@@ -1037,7 +1026,11 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
             return;
         }
 
-        if let Some(len) = len_const.try_eval_target_usize(tcx, tcx.param_env(def.did())) {
+        // FIXME(repr_simd): This check is nice, but perhaps unnecessary due to the fact
+        // we do not expect users to implement their own `repr(simd)` types. If they could,
+        // this check is easily side-steppable by hiding the const behind normalization.
+        // The consequence is that the error is, in general, only observable post-mono.
+        if let Some(len) = len_const.try_to_target_usize(tcx) {
             if len == 0 {
                 struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
                 return;
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index 71eb368185e..bbff00cd3b3 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -76,9 +76,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
 
                 let (size, ty) = match elem_ty.kind() {
                     ty::Array(ty, len) => {
-                        if let Some(len) =
-                            len.try_eval_target_usize(self.tcx, self.tcx.param_env(adt.did()))
-                        {
+                        if let Some(len) = len.try_to_target_usize(self.tcx) {
                             (len, *ty)
                         } else {
                             return None;
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 4346504450d..69ebd3a928a 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -13,6 +13,7 @@ use tracing::{debug, instrument};
 
 use super::ItemCtxt;
 use super::predicates_of::assert_only_contains_predicates_from;
+use crate::bounds::Bounds;
 use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
 
 /// For associated types we include both bounds written on the type
@@ -36,7 +37,8 @@ fn associated_type_bounds<'tcx>(
     );
 
     let icx = ItemCtxt::new(tcx, assoc_item_def_id);
-    let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter);
+    let mut bounds = Bounds::default();
+    icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
     // Associated types are implicitly sized unless a `?Sized` bound is found
     icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
 
@@ -303,7 +305,8 @@ fn opaque_type_bounds<'tcx>(
 ) -> &'tcx [(ty::Clause<'tcx>, Span)] {
     ty::print::with_reduced_queries!({
         let icx = ItemCtxt::new(tcx, opaque_def_id);
-        let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter);
+        let mut bounds = Bounds::default();
+        icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
         // Opaque types are implicitly sized unless a `?Sized` bound is found
         icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
         debug!(?bounds);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 421ba40aa88..9bd8c70dcfe 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -181,9 +181,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     // on a trait we must also consider the bounds that follow the trait's name,
     // like `trait Foo: A + B + C`.
     if let Some(self_bounds) = is_trait {
-        let bounds = icx.lowerer().lower_mono_bounds(
+        let mut bounds = Bounds::default();
+        icx.lowerer().lower_bounds(
             tcx.types.self_param,
             self_bounds,
+            &mut bounds,
+            ty::List::empty(),
             PredicateFilter::All,
         );
         predicates.extend(bounds.clauses(tcx));
@@ -265,9 +268,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                 }
 
                 let mut bounds = Bounds::default();
-                icx.lowerer().lower_poly_bounds(
+                icx.lowerer().lower_bounds(
                     ty,
-                    bound_pred.bounds.iter(),
+                    bound_pred.bounds,
                     &mut bounds,
                     bound_vars,
                     PredicateFilter::All,
@@ -626,7 +629,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
         bug!("trait_def_id {trait_def_id:?} is not an item");
     };
 
-    let (generics, bounds) = match item.kind {
+    let (generics, superbounds) = match item.kind {
         hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
         hir::ItemKind::TraitAlias(generics, supertraits) => (generics, supertraits),
         _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
@@ -635,7 +638,8 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
     let icx = ItemCtxt::new(tcx, trait_def_id);
 
     let self_param_ty = tcx.types.self_param;
-    let superbounds = icx.lowerer().lower_mono_bounds(self_param_ty, bounds, filter);
+    let mut bounds = Bounds::default();
+    icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
 
     let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics(
         generics,
@@ -646,7 +650,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
 
     // Combine the two lists to form the complete set of superbounds:
     let implied_bounds =
-        &*tcx.arena.alloc_from_iter(superbounds.clauses(tcx).chain(where_bounds_that_match));
+        &*tcx.arena.alloc_from_iter(bounds.clauses(tcx).chain(where_bounds_that_match));
     debug!(?implied_bounds);
 
     // Now require that immediate supertraits are lowered, which will, in
@@ -834,9 +838,9 @@ impl<'tcx> ItemCtxt<'tcx> {
             };
 
             let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
-            self.lowerer().lower_poly_bounds(
+            self.lowerer().lower_bounds(
                 bound_ty,
-                predicate.bounds.iter(),
+                predicate.bounds,
                 &mut bounds,
                 bound_vars,
                 filter,
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 310f648b980..4721a3a0cf5 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -142,7 +142,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// There is an implied binder around `param_ty` and `hir_bounds`.
     /// See `lower_poly_trait_ref` for more details.
     #[instrument(level = "debug", skip(self, hir_bounds, bounds))]
-    pub(crate) fn lower_poly_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'tcx>>>(
+    pub(crate) fn lower_bounds<'hir, I: IntoIterator<Item = &'hir hir::GenericBound<'tcx>>>(
         &self,
         param_ty: Ty<'tcx>,
         hir_bounds: I,
@@ -171,16 +171,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 hir::GenericBound::Trait(poly_trait_ref) => {
                     let (constness, polarity) = match poly_trait_ref.modifiers {
                         hir::TraitBoundModifier::Const => {
-                            (ty::BoundConstness::Const, ty::PredicatePolarity::Positive)
-                        }
-                        hir::TraitBoundModifier::MaybeConst => {
-                            (ty::BoundConstness::ConstIfConst, ty::PredicatePolarity::Positive)
-                        }
-                        hir::TraitBoundModifier::None => {
-                            (ty::BoundConstness::NotConst, ty::PredicatePolarity::Positive)
+                            (Some(ty::BoundConstness::Const), ty::PredicatePolarity::Positive)
                         }
+                        hir::TraitBoundModifier::MaybeConst => (
+                            Some(ty::BoundConstness::ConstIfConst),
+                            ty::PredicatePolarity::Positive,
+                        ),
+                        hir::TraitBoundModifier::None => (None, ty::PredicatePolarity::Positive),
                         hir::TraitBoundModifier::Negative => {
-                            (ty::BoundConstness::NotConst, ty::PredicatePolarity::Negative)
+                            (None, ty::PredicatePolarity::Negative)
                         }
                         hir::TraitBoundModifier::Maybe => continue,
                     };
@@ -212,35 +211,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
     }
 
-    /// Lower HIR bounds into `bounds` given the self type `param_ty` and *no* overarching late-bound vars.
-    ///
-    /// ### Example
-    ///
-    /// ```ignore (illustrative)
-    /// fn foo<T: Bar + Baz>() { }
-    /// //     ^  ^^^^^^^^^ hir_bounds
-    /// //     param_ty
-    /// ```
-    pub(crate) fn lower_mono_bounds(
-        &self,
-        param_ty: Ty<'tcx>,
-        hir_bounds: &[hir::GenericBound<'tcx>],
-        predicate_filter: PredicateFilter,
-    ) -> Bounds<'tcx> {
-        let mut bounds = Bounds::default();
-
-        self.lower_poly_bounds(
-            param_ty,
-            hir_bounds.iter(),
-            &mut bounds,
-            ty::List::empty(),
-            predicate_filter,
-        );
-        debug!(?bounds);
-
-        bounds
-    }
-
     /// Lower an associated item constraint from the HIR into `bounds`.
     ///
     /// ### A Note on Binders
@@ -444,9 +414,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         // parameter to have a skipped binder.
                         let param_ty =
                             Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
-                        self.lower_poly_bounds(
+                        self.lower_bounds(
                             param_ty,
-                            hir_bounds.iter(),
+                            hir_bounds,
                             bounds,
                             projection_ty.bound_vars(),
                             predicate_filter,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 2cf97e29060..4cb55ec8c89 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -51,7 +51,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             } = self.lower_poly_trait_ref(
                 &trait_bound.trait_ref,
                 trait_bound.span,
-                ty::BoundConstness::NotConst,
+                None,
                 ty::PredicatePolarity::Positive,
                 dummy_self,
                 &mut bounds,
@@ -259,7 +259,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         }
                     })
                     .collect();
-                let args = tcx.mk_args(&args);
 
                 let span = i.bottom().1;
                 let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
@@ -292,7 +291,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     .emit();
                 }
 
-                ty::ExistentialTraitRef { def_id: trait_ref.def_id, args }
+                ty::ExistentialTraitRef::new(tcx, trait_ref.def_id, args)
             })
         });
 
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 828809726d2..fe0cd572609 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -652,7 +652,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         trait_ref: &hir::TraitRef<'tcx>,
         span: Span,
-        constness: ty::BoundConstness,
+        constness: Option<ty::BoundConstness>,
         polarity: ty::PredicatePolarity,
         self_ty: Ty<'tcx>,
         bounds: &mut Bounds<'tcx>,
@@ -675,7 +675,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             Some(self_ty),
         );
 
-        if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness
+        if let Some(constness) = constness
             && !self.tcx().is_const_trait(trait_def_id)
         {
             self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 13ba615d4c9..fa6a86c6911 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -537,40 +537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 //
                 // This check is here because there is currently no way to express a trait bound for `FnDef` types only.
                 if let ty::FnDef(def_id, _args) = *arg_ty.kind() {
-                    let fn_once_def_id =
-                        self.tcx.require_lang_item(hir::LangItem::FnOnce, Some(span));
-                    let fn_once_output_def_id =
-                        self.tcx.require_lang_item(hir::LangItem::FnOnceOutput, Some(span));
-                    if self.tcx.has_host_param(fn_once_def_id) {
-                        let const_param: ty::GenericArg<'tcx> =
-                            ([self.tcx.consts.false_, self.tcx.consts.true_])[idx].into();
-                        self.register_predicate(traits::Obligation::new(
-                            self.tcx,
-                            self.misc(span),
-                            self.param_env,
-                            ty::TraitRef::new(self.tcx, fn_once_def_id, [
-                                arg_ty.into(),
-                                fn_sig.inputs()[0].into(),
-                                const_param,
-                            ]),
-                        ));
-
-                        self.register_predicate(traits::Obligation::new(
-                            self.tcx,
-                            self.misc(span),
-                            self.param_env,
-                            ty::ProjectionPredicate {
-                                projection_term: ty::AliasTerm::new(
-                                    self.tcx,
-                                    fn_once_output_def_id,
-                                    [arg_ty.into(), fn_sig.inputs()[0].into(), const_param],
-                                ),
-                                term: fn_sig.output().into(),
-                            },
-                        ));
-
-                        self.select_obligations_where_possible(|_| {});
-                    } else if idx == 0 && !self.tcx.is_const_fn_raw(def_id) {
+                    if idx == 0 && !self.tcx.is_const_fn_raw(def_id) {
                         self.dcx().emit_err(errors::ConstSelectMustBeConst { span });
                     }
                 } else {
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index f4d7b59e9c8..a1813782e29 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -10,7 +10,8 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, StashKey, Subdiagnostic, pluralize, struct_span_code_err,
+    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, Subdiagnostic, pluralize,
+    struct_span_code_err,
 };
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -2763,12 +2764,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             field_ident.span,
             "field not available in `impl Future`, but it is available in its `Output`",
         );
-        err.span_suggestion_verbose(
-            base.span.shrink_to_hi(),
-            "consider `await`ing on the `Future` and access the field of its `Output`",
-            ".await",
-            Applicability::MaybeIncorrect,
-        );
+        match self.tcx.coroutine_kind(self.body_id) {
+            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
+                err.span_suggestion_verbose(
+                    base.span.shrink_to_hi(),
+                    "consider `await`ing on the `Future` to access the field",
+                    ".await",
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            _ => {
+                let mut span: MultiSpan = base.span.into();
+                span.push_span_label(self.tcx.def_span(self.body_id), "this is not `async`");
+                err.span_note(
+                    span,
+                    "this implements `Future` and its output type has the field, \
+                    but the future cannot be awaited in a synchronous function",
+                );
+            }
+        }
     }
 
     fn ban_nonexisting_field(
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index eccb18ad6c4..2bc84d1ac67 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1487,7 +1487,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
         } else if self.tcx.features().generic_const_exprs {
-            ct.normalize(self.tcx, self.param_env)
+            ct.normalize_internal(self.tcx, self.param_env)
         } else {
             ct
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index bf8cc462189..f29d6199a87 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1097,6 +1097,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut only_extras_so_far = errors
             .peek()
             .is_some_and(|first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0));
+        let mut prev_extra_idx = None;
         let mut suggestions = vec![];
         while let Some(error) = errors.next() {
             only_extras_so_far &= matches!(error, Error::Extra(_));
@@ -1165,11 +1166,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         //     fn f() {}
                         //   - f(0, 1,)
                         //   + f()
-                        if only_extras_so_far
-                            && !errors
-                                .peek()
-                                .is_some_and(|next_error| matches!(next_error, Error::Extra(_)))
-                        {
+                        let trim_next_comma = match errors.peek() {
+                            Some(Error::Extra(provided_idx))
+                                if only_extras_so_far
+                                    && provided_idx.index() > arg_idx.index() + 1 =>
+                            // If the next Error::Extra ("next") doesn't next to current ("current"),
+                            // fn foo(_: (), _: u32) {}
+                            // - foo("current", (), 1u32, "next")
+                            // + foo((), 1u32)
+                            // If the previous error is not a `Error::Extra`, then do not trim the next comma
+                            // - foo((), "current", 42u32, "next")
+                            // + foo((), 42u32)
+                            {
+                                prev_extra_idx.map_or(true, |prev_extra_idx| {
+                                    prev_extra_idx + 1 == arg_idx.index()
+                                })
+                            }
+                            // If no error left, we need to delete the next comma
+                            None if only_extras_so_far => true,
+                            // Not sure if other error type need to be handled as well
+                            _ => false,
+                        };
+
+                        if trim_next_comma {
                             let next = provided_arg_tys
                                 .get(arg_idx + 1)
                                 .map(|&(_, sp)| sp)
@@ -1192,6 +1211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             SuggestionText::Remove(_) => SuggestionText::Remove(true),
                             _ => SuggestionText::DidYouMean,
                         };
+                        prev_extra_idx = Some(arg_idx.index())
                     }
                 }
                 Error::Missing(expected_idx) => {
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 9e36f7a9aea..85ee0a5cf7d 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -155,7 +155,7 @@ fn typeck_with_fallback<'tcx>(
             tcx.fn_sig(def_id).instantiate_identity()
         };
 
-        check_abi(tcx, id, span, fn_sig.abi());
+        check_abi(tcx, span, fn_sig.abi());
 
         // Compute the function signature from point of view of inside the fn.
         let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 3189620e969..d3762e739db 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -836,6 +836,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(profile_emit, Some(PathBuf::from("abc")));
     tracked!(profile_sample_use, Some(PathBuf::from("abc")));
     tracked!(profiler_runtime, "abc".to_string());
+    tracked!(regparm, Some(3));
     tracked!(relax_elf_relocations, Some(true));
     tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
     tracked!(sanitizer, SanitizerSet::ADDRESS);
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 8bd9c899a62..125fe9b3f16 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -2288,10 +2288,10 @@ impl EarlyLintPass for IncompleteInternalFeatures {
     fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
         let features = cx.builder.features();
         features
-            .declared_lang_features
+            .enabled_lang_features()
             .iter()
             .map(|(name, span, _)| (name, span))
-            .chain(features.declared_lib_features.iter().map(|(name, span)| (name, span)))
+            .chain(features.enabled_lib_features().iter().map(|(name, span)| (name, span)))
             .filter(|(&name, _)| features.incomplete(name) || features.internal(name))
             .for_each(|(&name, &span)| {
                 if features.incomplete(name) {
@@ -2601,7 +2601,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
                     ty.tuple_fields().iter().find_map(|field| ty_find_init_error(cx, field, init))
                 }
                 Array(ty, len) => {
-                    if matches!(len.try_eval_target_usize(cx.tcx, cx.param_env), Some(v) if v > 0) {
+                    if matches!(len.try_to_target_usize(cx.tcx), Some(v) if v > 0) {
                         // Array length known at array non-empty -- recurse.
                         ty_find_init_error(cx, *ty, init)
                     } else {
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 89a67fc0d89..ff2ae69e1db 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -493,7 +493,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         //
         // This means that this only errors if we're truly lowering the lint
         // level from forbid.
-        if self.lint_added_lints && level != Level::Forbid && old_level == Level::Forbid {
+        if self.lint_added_lints && level == Level::Deny && old_level == Level::Forbid {
+            // Having a deny inside a forbid is fine and is ignored, so we skip this check.
+            return;
+        } else if self.lint_added_lints && level != Level::Forbid && old_level == Level::Forbid {
             // Backwards compatibility check:
             //
             // We used to not consider `forbid(lint_group)`
@@ -855,7 +858,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     #[track_caller]
     fn check_gated_lint(&self, lint_id: LintId, span: Span, lint_from_cli: bool) -> bool {
         let feature = if let Some(feature) = lint_id.lint.feature_gate
-            && !self.features.active(feature)
+            && !self.features.enabled(feature)
         {
             // Lint is behind a feature that is not enabled; eventually return false.
             feature
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 81352af3d48..a7faab0868d 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -598,6 +598,7 @@ fn register_builtins(store: &mut LintStore) {
         "converted into hard error, see PR #125380 \
          <https://github.com/rust-lang/rust/pull/125380> for more information",
     );
+    store.register_removed("unsupported_calling_conventions", "converted into hard error");
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index e9c61a41d6d..60ff925b40e 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -730,7 +730,6 @@ fn is_niche_optimization_candidate<'tcx>(
 /// can, return the type that `ty` can be safely converted to, otherwise return `None`.
 /// Currently restricted to function pointers, boxes, references, `core::num::NonZero`,
 /// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
-/// FIXME: This duplicates code in codegen.
 pub(crate) fn repr_nullable_ptr<'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
@@ -743,10 +742,6 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
             [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
                 ([], [field]) | ([field], []) => field.ty(tcx, args),
                 ([field1], [field2]) => {
-                    if !tcx.features().result_ffi_guarantees {
-                        return None;
-                    }
-
                     let ty1 = field1.ty(tcx, args);
                     let ty2 = field2.ty(tcx, args);
 
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 1a007250961..ddc18c755a8 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -346,7 +346,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                         None
                     }
                 }
-                ty::Array(ty, len) => match len.try_eval_target_usize(cx.tcx, cx.param_env) {
+                ty::Array(ty, len) => match len.try_to_target_usize(cx.tcx) {
                     // If the array is empty we don't lint, to avoid false positives
                     Some(0) | None => None,
                     // If the array is definitely non-empty, we can do `#[must_use]` checking.
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 45a5ce0ca20..a4c49a15905 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -123,7 +123,6 @@ declare_lint_pass! {
         UNSAFE_OP_IN_UNSAFE_FN,
         UNSTABLE_NAME_COLLISIONS,
         UNSTABLE_SYNTAX_PRE_EXPANSION,
-        UNSUPPORTED_CALLING_CONVENTIONS,
         UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
         UNUSED_ASSIGNMENTS,
         UNUSED_ASSOCIATED_TYPE_BOUNDS,
@@ -156,7 +155,7 @@ declare_lint! {
     ///
     /// ```rust
     /// #![forbid(warnings)]
-    /// #![deny(bad_style)]
+    /// #![warn(bad_style)]
     ///
     /// fn main() {}
     /// ```
@@ -2667,7 +2666,6 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust
-    /// #![feature(strict_provenance)]
     /// #![warn(fuzzy_provenance_casts)]
     ///
     /// fn main() {
@@ -2701,7 +2699,7 @@ declare_lint! {
     pub FUZZY_PROVENANCE_CASTS,
     Allow,
     "a fuzzy integer to pointer cast is used",
-    @feature_gate = strict_provenance;
+    @feature_gate = strict_provenance_lints;
 }
 
 declare_lint! {
@@ -2711,7 +2709,6 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust
-    /// #![feature(strict_provenance)]
     /// #![warn(lossy_provenance_casts)]
     ///
     /// fn main() {
@@ -2747,7 +2744,7 @@ declare_lint! {
     pub LOSSY_PROVENANCE_CASTS,
     Allow,
     "a lossy pointer to integer cast is used",
-    @feature_gate = strict_provenance;
+    @feature_gate = strict_provenance_lints;
 }
 
 declare_lint! {
@@ -3790,53 +3787,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `unsupported_calling_conventions` lint is output whenever there is a use of the
-    /// `stdcall`, `fastcall`, `thiscall`, `vectorcall` calling conventions (or their unwind
-    /// variants) on targets that cannot meaningfully be supported for the requested target.
-    ///
-    /// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
-    /// code, because this calling convention was never specified for those targets.
-    ///
-    /// Historically MSVC toolchains have fallen back to the regular C calling convention for
-    /// targets other than x86, but Rust doesn't really see a similar need to introduce a similar
-    /// hack across many more targets.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,ignore (needs specific targets)
-    /// extern "stdcall" fn stdcall() {}
-    /// ```
-    ///
-    /// This will produce:
-    ///
-    /// ```text
-    /// warning: use of calling convention not supported on this target
-    ///   --> $DIR/unsupported.rs:39:1
-    ///    |
-    /// LL | extern "stdcall" fn stdcall() {}
-    ///    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-    ///    |
-    ///    = note: `#[warn(unsupported_calling_conventions)]` on by default
-    ///    = warning: this was previously accepted by the compiler but is being phased out;
-    ///               it will become a hard error in a future release!
-    ///    = note: for more information, see issue ...
-    /// ```
-    ///
-    /// ### Explanation
-    ///
-    /// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
-    /// defined at all, but was previously accepted due to a bug in the implementation of the
-    /// compiler.
-    pub UNSUPPORTED_CALLING_CONVENTIONS,
-    Warn,
-    "use of unsupported calling convention",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
-        reference: "issue #87678 <https://github.com/rust-lang/rust/issues/87678>",
-    };
-}
-
-declare_lint! {
     /// The `unsupported_fn_ptr_calling_conventions` lint is output whenever there is a use of
     /// a target dependent calling convention on a target that does not support this calling
     /// convention on a function pointer.
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 69707fdbe8f..7bb40996d58 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -437,9 +437,6 @@ provide! { tcx, def_id, other, cdata,
 
 pub(in crate::rmeta) fn provide(providers: &mut Providers) {
     provide_cstore_hooks(providers);
-    // FIXME(#44234) - almost all of these queries have no sub-queries and
-    // therefore no actual inputs, they're just reading tables calculated in
-    // resolve! Does this work? Unsure! That's what the issue is about
     providers.queries = rustc_middle::query::Providers {
         allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(),
         alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(),
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index e9b73d25ba2..04a06ba7464 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -56,7 +56,6 @@
 #![feature(ptr_alignment_type)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![feature(strict_provenance)]
 #![feature(trait_upcasting)]
 #![feature(trusted_len)]
 #![feature(try_blocks)]
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index ee34ccd889f..c0688aff183 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -422,15 +422,15 @@ impl<'tcx> TyCtxt<'tcx> {
                     debug!("stability: skipping span={:?} since it is internal", span);
                     return EvalResult::Allow;
                 }
-                if self.features().declared(feature) {
+                if self.features().enabled(feature) {
                     return EvalResult::Allow;
                 }
 
                 // If this item was previously part of a now-stabilized feature which is still
-                // active (i.e. the user hasn't removed the attribute for the stabilized feature
+                // enabled (i.e. the user hasn't removed the attribute for the stabilized feature
                 // yet) then allow use of this item.
                 if let Some(implied_by) = implied_by
-                    && self.features().declared(implied_by)
+                    && self.features().enabled(implied_by)
                 {
                     return EvalResult::Allow;
                 }
@@ -509,7 +509,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     debug!("body stability: skipping span={:?} since it is internal", span);
                     return EvalResult::Allow;
                 }
-                if self.features().declared(feature) {
+                if self.features().enabled(feature) {
                     return EvalResult::Allow;
                 }
 
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 4262460d928..465aa0eee03 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -1,5 +1,6 @@
 use std::fmt::{self, Debug, Display, Formatter};
 
+use either::Either;
 use rustc_hir::def_id::DefId;
 use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_session::RemapFileNameExt;
@@ -320,8 +321,14 @@ impl<'tcx> Const<'tcx> {
             Const::Ty(_, c) => {
                 // We want to consistently have a "clean" value for type system constants (i.e., no
                 // data hidden in the padding), so we always go through a valtree here.
-                let (ty, val) = c.eval(tcx, param_env, span)?;
-                Ok(tcx.valtree_to_const_val((ty, val)))
+                match c.eval_valtree(tcx, param_env, span) {
+                    Ok((ty, val)) => Ok(tcx.valtree_to_const_val((ty, val))),
+                    Err(Either::Left(_bad_ty)) => Err(tcx
+                        .dcx()
+                        .delayed_bug("`mir::Const::eval` called on a non-valtree-compatible type")
+                        .into()),
+                    Err(Either::Right(e)) => Err(e),
+                }
             }
             Const::Unevaluated(uneval, _) => {
                 // FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 8d57d0d8654..476e352ed92 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -55,7 +55,7 @@ impl<'tcx> PlaceTy<'tcx> {
     /// `PlaceElem`, where we can just use the `Ty` that is already
     /// stored inline on field projection elems.
     pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> {
-        self.projection_ty_core(tcx, ty::ParamEnv::empty(), &elem, |_, _, ty| ty, |_, ty| ty)
+        self.projection_ty_core(tcx, &elem, |_, _, ty| ty, |_, ty| ty)
     }
 
     /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
@@ -66,7 +66,6 @@ impl<'tcx> PlaceTy<'tcx> {
     pub fn projection_ty_core<V, T>(
         self,
         tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
         elem: &ProjectionElem<V, T>,
         mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>,
         mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>,
@@ -93,7 +92,9 @@ impl<'tcx> PlaceTy<'tcx> {
                     ty::Slice(..) => self.ty,
                     ty::Array(inner, _) if !from_end => Ty::new_array(tcx, *inner, to - from),
                     ty::Array(inner, size) if from_end => {
-                        let size = size.eval_target_usize(tcx, param_env);
+                        let size = size
+                            .try_to_target_usize(tcx)
+                            .expect("expected subslice projection on fixed-size array");
                         let len = size - from - to;
                         Ty::new_array(tcx, *inner, len)
                     }
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index 66035464fa5..05556ae38a8 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -161,9 +161,7 @@ pub enum SelectionCandidate<'tcx> {
 
     /// Implementation of a `Fn`-family trait by one of the anonymous
     /// types generated for a fn pointer type (e.g., `fn(int) -> int`)
-    FnPointerCandidate {
-        fn_host_effect: ty::Const<'tcx>,
-    },
+    FnPointerCandidate,
 
     TraitAliasCandidate,
 
@@ -180,9 +178,6 @@ pub enum SelectionCandidate<'tcx> {
     BuiltinObjectCandidate,
 
     BuiltinUnsizeCandidate,
-
-    /// Implementation of `const Destruct`, optionally from a custom `impl const Drop`.
-    ConstDestructCandidate(Option<DefId>),
 }
 
 /// The result of trait evaluation. The order is important
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 389d20f315f..5ab85a69ce6 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -109,6 +109,7 @@ impl<'tcx> Const<'tcx> {
 
     #[inline]
     pub fn new_unevaluated(tcx: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Const<'tcx> {
+        tcx.debug_assert_args_compatible(uv.def, uv.args);
         Const::new(tcx, ty::ConstKind::Unevaluated(uv))
     }
 
@@ -398,133 +399,65 @@ impl<'tcx> Const<'tcx> {
         }
     }
 
-    /// Returns the evaluated constant
-    #[inline]
-    pub fn eval(
-        self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ParamEnv<'tcx>,
-        span: Span,
-    ) -> Result<(Ty<'tcx>, ValTree<'tcx>), ErrorHandled> {
-        self.eval_valtree(tcx, param_env, span).map_err(|err| {
-            match err {
-                Either::Right(err) => err,
-                Either::Left(_bad_ty) => {
-                    // This can happen when we run on ill-typed code.
-                    let e = tcx.dcx().span_delayed_bug(
-                        span,
-                        "`ty::Const::eval` called on a non-valtree-compatible type",
-                    );
-                    e.into()
-                }
-            }
-        })
-    }
-
     /// Normalizes the constant to a value or an error if possible.
     #[inline]
-    pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
-        match self.eval(tcx, param_env, DUMMY_SP) {
+    pub fn normalize_internal(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
+        match self.eval_valtree(tcx, param_env, DUMMY_SP) {
             Ok((ty, val)) => Self::new_value(tcx, val, ty),
-            Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into()),
-            Err(ErrorHandled::TooGeneric(_span)) => self,
+            Err(Either::Left(_bad_ty)) => {
+                // This can happen when we run on ill-typed code.
+                Self::new_error(
+                    tcx,
+                    tcx.dcx()
+                        .delayed_bug("`ty::Const::eval` called on a non-valtree-compatible type"),
+                )
+            }
+            Err(Either::Right(ErrorHandled::Reported(r, _span))) => Self::new_error(tcx, r.into()),
+            Err(Either::Right(ErrorHandled::TooGeneric(_span))) => self,
         }
     }
 
-    #[inline]
-    pub fn try_eval_scalar(
-        self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Option<(Ty<'tcx>, Scalar)> {
-        let (ty, val) = self.eval(tcx, param_env, DUMMY_SP).ok()?;
-        let val = val.try_to_scalar()?;
-        Some((ty, val))
-    }
-
-    #[inline]
-    /// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
-    /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
-    /// contains const generic parameters or pointers).
-    pub fn try_eval_scalar_int(
-        self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ParamEnv<'tcx>,
-    ) -> Option<(Ty<'tcx>, ScalarInt)> {
-        let (ty, scalar) = self.try_eval_scalar(tcx, param_env)?;
-        let val = scalar.try_to_scalar_int().ok()?;
-        Some((ty, val))
-    }
-
-    #[inline]
-    /// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
-    /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
-    /// contains const generic parameters or pointers).
-    pub fn try_eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u128> {
-        let (ty, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
-        let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
-        // if `ty` does not depend on generic parameters, use an empty param_env
-        Some(scalar.to_bits(size))
-    }
-
-    #[inline]
-    /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
-    pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u128 {
-        self.try_eval_bits(tcx, param_env)
-            .unwrap_or_else(|| bug!("failed to evalate {:#?} to bits", self))
-    }
-
-    #[inline]
-    pub fn try_eval_target_usize(
-        self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ParamEnv<'tcx>,
-    ) -> Option<u64> {
-        let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
-        Some(scalar.to_target_usize(tcx))
-    }
-
-    #[inline]
-    pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
-        let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
-        scalar.try_into().ok()
-    }
-
-    #[inline]
-    /// Panics if the value cannot be evaluated or doesn't contain a valid `usize`.
-    pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
-        self.try_eval_target_usize(tcx, param_env)
-            .unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
-    }
-
     /// Panics if self.kind != ty::ConstKind::Value
-    pub fn to_valtree(self) -> ty::ValTree<'tcx> {
+    pub fn to_valtree(self) -> (ty::ValTree<'tcx>, Ty<'tcx>) {
         match self.kind() {
-            ty::ConstKind::Value(_, valtree) => valtree,
+            ty::ConstKind::Value(ty, valtree) => (valtree, ty),
             _ => bug!("expected ConstKind::Value, got {:?}", self.kind()),
         }
     }
 
     /// Attempts to convert to a `ValTree`
-    pub fn try_to_valtree(self) -> Option<ty::ValTree<'tcx>> {
+    pub fn try_to_valtree(self) -> Option<(ty::ValTree<'tcx>, Ty<'tcx>)> {
         match self.kind() {
-            ty::ConstKind::Value(_, valtree) => Some(valtree),
+            ty::ConstKind::Value(ty, valtree) => Some((valtree, ty)),
             _ => None,
         }
     }
 
     #[inline]
-    pub fn try_to_scalar(self) -> Option<Scalar> {
-        self.try_to_valtree()?.try_to_scalar()
+    pub fn try_to_scalar(self) -> Option<(Scalar, Ty<'tcx>)> {
+        let (valtree, ty) = self.try_to_valtree()?;
+        Some((valtree.try_to_scalar()?, ty))
     }
 
     pub fn try_to_bool(self) -> Option<bool> {
-        self.try_to_valtree()?.try_to_scalar_int()?.try_to_bool().ok()
+        self.try_to_valtree()?.0.try_to_scalar_int()?.try_to_bool().ok()
     }
 
     #[inline]
     pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> {
-        self.try_to_valtree()?.try_to_target_usize(tcx)
+        self.try_to_valtree()?.0.try_to_target_usize(tcx)
+    }
+
+    #[inline]
+    /// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
+    /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
+    /// contains const generic parameters or pointers).
+    pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u128> {
+        let (scalar, ty) = self.try_to_scalar()?;
+        let scalar = scalar.try_to_scalar_int().ok()?;
+        let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
+        // if `ty` does not depend on generic parameters, use an empty param_env
+        Some(scalar.to_bits(size))
     }
 
     pub fn is_ct_infer(self) -> bool {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index c2a55060490..9ffdcf646ac 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -279,6 +279,26 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.debug_assert_args_compatible(def_id, args);
     }
 
+    /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
+    /// are compatible with the `DefId`. Since we're missing a `Self` type, stick on
+    /// a dummy self type and forward to `debug_assert_args_compatible`.
+    fn debug_assert_existential_args_compatible(
+        self,
+        def_id: Self::DefId,
+        args: Self::GenericArgs,
+    ) {
+        // FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible`
+        // to avoid needing to reintern the set of args...
+        if cfg!(debug_assertions) {
+            self.debug_assert_args_compatible(
+                def_id,
+                self.mk_args_from_iter(
+                    [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
+                ),
+            );
+        }
+    }
+
     fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
     where
         I: Iterator<Item = T>,
@@ -3093,7 +3113,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 Some(stability) if stability.is_const_unstable() => {
                     // has a `rustc_const_unstable` attribute, check whether the user enabled the
                     // corresponding feature gate.
-                    self.features().declared(stability.feature)
+                    self.features().enabled(stability.feature)
                 }
                 // functions without const stability are either stable user written
                 // const fn or the user is using feature gates and we thus don't
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index 54b8507babf..bf741f63a3d 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -85,7 +85,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
         match self {
             Self::False => Ok(false),
             Self::True => Ok(true),
-            Self::ConstIsZero(const_) => match const_.try_eval_target_usize(tcx, param_env) {
+            Self::ConstIsZero(const_) => match const_.try_to_target_usize(tcx) {
                 None | Some(0) => Ok(true),
                 Some(1..) => Ok(false),
             },
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 6c12b691c26..dbf88e643c5 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -21,7 +21,9 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
 use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::{FieldIdx, TyAbiInterface, VariantIdx, call};
 use rustc_target::spec::abi::Abi as SpecAbi;
-use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, PanicStrategy, Target, WasmCAbi};
+use rustc_target::spec::{
+    HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, PanicStrategy, Target, WasmCAbi, X86Abi,
+};
 use tracing::debug;
 use {rustc_abi as abi, rustc_hir as hir};
 
@@ -397,7 +399,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
                 }
             }
             ty::Array(inner, len) if tcx.features().transmute_generic_consts => {
-                let len_eval = len.try_eval_target_usize(tcx, param_env);
+                let len_eval = len.try_to_target_usize(tcx);
                 if len_eval == Some(0) {
                     return Ok(SizeSkeleton::Known(Size::from_bytes(0), None));
                 }
@@ -544,6 +546,12 @@ impl<'tcx> HasWasmCAbiOpt for TyCtxt<'tcx> {
     }
 }
 
+impl<'tcx> HasX86AbiOpt for TyCtxt<'tcx> {
+    fn x86_abi_opt(&self) -> X86Abi {
+        X86Abi { regparm: self.sess.opts.unstable_opts.regparm }
+    }
+}
+
 impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> {
     #[inline]
     fn tcx(&self) -> TyCtxt<'tcx> {
@@ -595,6 +603,12 @@ impl<'tcx> HasWasmCAbiOpt for LayoutCx<'tcx> {
     }
 }
 
+impl<'tcx> HasX86AbiOpt for LayoutCx<'tcx> {
+    fn x86_abi_opt(&self) -> X86Abi {
+        self.calc.cx.x86_abi_opt()
+    }
+}
+
 impl<'tcx> HasTyCtxt<'tcx> for LayoutCx<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.calc.cx
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 7ada5fd93ba..b5495fa282b 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1956,7 +1956,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         define_scoped_cx!(self);
 
         match constness {
-            ty::BoundConstness::NotConst => {}
             ty::BoundConstness::Const => {
                 p!("const ");
             }
@@ -2948,7 +2947,10 @@ impl<'tcx> ty::TraitPredicate<'tcx> {
 }
 
 #[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
-pub struct TraitPredPrintWithBoundConstness<'tcx>(ty::TraitPredicate<'tcx>, ty::BoundConstness);
+pub struct TraitPredPrintWithBoundConstness<'tcx>(
+    ty::TraitPredicate<'tcx>,
+    Option<ty::BoundConstness>,
+);
 
 impl<'tcx> fmt::Debug for TraitPredPrintWithBoundConstness<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -2966,7 +2968,7 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> {
 
     fn print_with_bound_constness(
         self,
-        constness: ty::BoundConstness,
+        constness: Option<ty::BoundConstness>,
     ) -> ty::Binder<'tcx, TraitPredPrintWithBoundConstness<'tcx>> {
         self.map_bound(|trait_pred| TraitPredPrintWithBoundConstness(trait_pred, constness))
     }
@@ -3206,7 +3208,9 @@ define_print_and_forward_display! {
 
     TraitPredPrintWithBoundConstness<'tcx> {
         p!(print(self.0.trait_ref.self_ty()), ": ");
-        p!(pretty_print_bound_constness(self.1));
+        if let Some(constness) = self.1 {
+            p!(pretty_print_bound_constness(constness));
+        }
         if let ty::PredicatePolarity::Negative = self.0.polarity {
             p!("!");
         }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 3f00458d195..74de378c4d7 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1117,7 +1117,12 @@ impl<'tcx> Ty<'tcx> {
         // The way we evaluate the `N` in `[T; N]` here only works since we use
         // `simd_size_and_type` post-monomorphization. It will probably start to ICE
         // if we use it in generic code. See the `simd-array-trait` ui test.
-        (f0_len.eval_target_usize(tcx, ParamEnv::empty()), *f0_elem_ty)
+        (
+            f0_len
+                .try_to_target_usize(tcx)
+                .expect("expected SIMD field to have definite array size"),
+            *f0_elem_ty,
+        )
     }
 
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 0a917120b3b..9a3049f3be6 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -907,24 +907,6 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    /// Constructs generic args for an item, optionally appending a const effect param type
-    pub fn with_opt_host_effect_param(
-        self,
-        caller_def_id: LocalDefId,
-        callee_def_id: DefId,
-        args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
-    ) -> ty::GenericArgsRef<'tcx> {
-        let generics = self.generics_of(callee_def_id);
-        assert_eq!(generics.parent, None);
-
-        let opt_const_param = generics
-            .host_effect_index
-            .is_some()
-            .then(|| ty::GenericArg::from(self.expected_host_effect_param_for_body(caller_def_id)));
-
-        self.mk_args_from_iter(args.into_iter().map(|arg| arg.into()).chain(opt_const_param))
-    }
-
     /// Expand any [weak alias types][weak] contained within the given `value`.
     ///
     /// This should be used over other normalization routines in situations where
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 020c202f965..7170aebee7d 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -454,12 +454,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         };
 
         let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span));
-        let method = trait_method(
-            self.tcx,
-            eq_def_id,
-            sym::eq,
-            self.tcx.with_opt_host_effect_param(self.def_id, eq_def_id, [compare_ty, compare_ty]),
-        );
+        let method = trait_method(self.tcx, eq_def_id, sym::eq, [compare_ty, compare_ty]);
 
         let bool_ty = self.tcx.types.bool;
         let eq_result = self.temp(bool_ty, source_info.span);
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 2c3611afca9..0dfa9168f7c 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -43,7 +43,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 }
 
 struct ConstToPat<'tcx> {
-    id: hir::HirId,
     span: Span,
     param_env: ty::ParamEnv<'tcx>,
 
@@ -62,7 +61,6 @@ impl<'tcx> ConstToPat<'tcx> {
     ) -> Self {
         trace!(?pat_ctxt.typeck_results.hir_owner);
         ConstToPat {
-            id,
             span,
             infcx,
             param_env: pat_ctxt.param_env,
@@ -149,15 +147,7 @@ impl<'tcx> ConstToPat<'tcx> {
             tcx,
             ObligationCause::dummy(),
             self.param_env,
-            ty::TraitRef::new_from_args(
-                tcx,
-                partial_eq_trait_id,
-                tcx.with_opt_host_effect_param(
-                    tcx.hir().enclosing_body_owner(self.id),
-                    partial_eq_trait_id,
-                    [ty, ty],
-                ),
-            ),
+            ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
         );
 
         // This *could* accept a type that isn't actually `PartialEq`, because region bounds get
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index a3b117a3f19..7f2a07e2f5e 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -863,7 +863,7 @@ where
             ty::Adt(def, args) => self.open_drop_for_adt(*def, args),
             ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
             ty::Array(ety, size) => {
-                let size = size.try_eval_target_usize(self.tcx(), self.elaborator.param_env());
+                let size = size.try_to_target_usize(self.tcx());
                 self.open_drop_for_array(*ety, size)
             }
             ty::Slice(ety) => self.drop_loop_pair(*ety),
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 162245cb950..fd8e403ebc2 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -18,18 +18,12 @@ struct MoveDataBuilder<'a, 'tcx, F> {
     body: &'a Body<'tcx>,
     loc: Location,
     tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
     data: MoveData<'tcx>,
     filter: F,
 }
 
 impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
-    fn new(
-        body: &'a Body<'tcx>,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        filter: F,
-    ) -> Self {
+    fn new(body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, filter: F) -> Self {
         let mut move_paths = IndexVec::new();
         let mut path_map = IndexVec::new();
         let mut init_path_map = IndexVec::new();
@@ -59,7 +53,6 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
             body,
             loc: Location::START,
             tcx,
-            param_env,
             data: MoveData {
                 moves: IndexVec::new(),
                 loc_map: LocationMap::new(body),
@@ -308,10 +301,9 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
 pub(super) fn gather_moves<'tcx>(
     body: &Body<'tcx>,
     tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
     filter: impl Fn(Ty<'tcx>) -> bool,
 ) -> MoveData<'tcx> {
-    let mut builder = MoveDataBuilder::new(body, tcx, param_env, filter);
+    let mut builder = MoveDataBuilder::new(body, tcx, filter);
 
     builder.gather_args();
 
@@ -550,7 +542,9 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
             };
             let base_ty = base_place.ty(self.body, self.tcx).ty;
             let len: u64 = match base_ty.kind() {
-                ty::Array(_, size) => size.eval_target_usize(self.tcx, self.param_env),
+                ty::Array(_, size) => size
+                    .try_to_target_usize(self.tcx)
+                    .expect("expected subslice projection on fixed-size array"),
                 _ => bug!("from_end: false slice pattern of non-array type"),
             };
             for offset in from..to {
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
index bc1177976b5..926bd187431 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
@@ -4,7 +4,7 @@ use std::ops::{Index, IndexMut};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::mir::*;
-use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_span::Span;
 use smallvec::SmallVec;
 
@@ -352,10 +352,9 @@ impl<'tcx> MoveData<'tcx> {
     pub fn gather_moves(
         body: &Body<'tcx>,
         tcx: TyCtxt<'tcx>,
-        param_env: ParamEnv<'tcx>,
         filter: impl Fn(Ty<'tcx>) -> bool,
     ) -> MoveData<'tcx> {
-        builder::gather_moves(body, tcx, param_env, filter)
+        builder::gather_moves(body, tcx, filter)
     }
 
     /// For the move path `mpi`, returns the root local variable that starts the path.
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index 75732b19cd0..5727517bd61 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -40,8 +40,7 @@ pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
         debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
     }
 
-    let param_env = tcx.param_env(def_id);
-    let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
+    let move_data = MoveData::gather_moves(body, tcx, |_| true);
 
     if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
         let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 8f032728f6b..0a413d68020 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -1957,7 +1957,8 @@ fn check_must_not_suspend_ty<'tcx>(
             let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix);
             check_must_not_suspend_ty(tcx, ty, hir_id, param_env, SuspendCheckData {
                 descr_pre,
-                plural_len: len.try_eval_target_usize(tcx, param_env).unwrap_or(0) as usize + 1,
+                // FIXME(must_not_suspend): This is wrong. We should handle printing unevaluated consts.
+                plural_len: len.try_to_target_usize(tcx).unwrap_or(0) as usize + 1,
                 ..data
             })
         }
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index 94088156756..9a533ea024d 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::DirectedGraph;
 use rustc_index::IndexVec;
 use rustc_index::bit_set::BitSet;
-use rustc_middle::bug;
 use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op};
 use tracing::{debug, debug_span, instrument};
 
@@ -58,13 +57,13 @@ pub(super) struct CoverageCounters {
     counter_increment_sites: IndexVec<CounterId, CounterIncrementSite>,
 
     /// Coverage counters/expressions that are associated with individual BCBs.
-    bcb_counters: IndexVec<BasicCoverageBlock, Option<BcbCounter>>,
+    node_counters: IndexVec<BasicCoverageBlock, Option<BcbCounter>>,
     /// Coverage counters/expressions that are associated with the control-flow
     /// edge between two BCBs.
     ///
     /// We currently don't iterate over this map, but if we do in the future,
     /// switch it back to `FxIndexMap` to avoid query stability hazards.
-    bcb_edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>,
+    edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>,
 
     /// Table of expression data, associating each expression ID with its
     /// corresponding operator (+ or -) and its LHS/RHS operands.
@@ -78,20 +77,20 @@ impl CoverageCounters {
     /// Ensures that each BCB node needing a counter has one, by creating physical
     /// counters or counter expressions for nodes and edges as required.
     pub(super) fn make_bcb_counters(
-        basic_coverage_blocks: &CoverageGraph,
+        graph: &CoverageGraph,
         bcb_needs_counter: &BitSet<BasicCoverageBlock>,
     ) -> Self {
-        let mut counters = MakeBcbCounters::new(basic_coverage_blocks, bcb_needs_counter);
-        counters.make_bcb_counters();
+        let mut builder = CountersBuilder::new(graph, bcb_needs_counter);
+        builder.make_bcb_counters();
 
-        counters.coverage_counters
+        builder.counters
     }
 
     fn with_num_bcbs(num_bcbs: usize) -> Self {
         Self {
             counter_increment_sites: IndexVec::new(),
-            bcb_counters: IndexVec::from_elem_n(None, num_bcbs),
-            bcb_edge_counters: FxHashMap::default(),
+            node_counters: IndexVec::from_elem_n(None, num_bcbs),
+            edge_counters: FxHashMap::default(),
             expressions: IndexVec::new(),
             expressions_memo: FxHashMap::default(),
         }
@@ -104,24 +103,18 @@ impl CoverageCounters {
         BcbCounter::Counter { id }
     }
 
-    /// Creates a new physical counter attached a BCB node.
-    /// The node must not already have a counter.
+    /// Creates a new physical counter for a BCB node.
     fn make_phys_node_counter(&mut self, bcb: BasicCoverageBlock) -> BcbCounter {
-        let counter = self.make_counter_inner(CounterIncrementSite::Node { bcb });
-        debug!(?bcb, ?counter, "node gets a physical counter");
-        self.set_bcb_counter(bcb, counter)
+        self.make_counter_inner(CounterIncrementSite::Node { bcb })
     }
 
-    /// Creates a new physical counter attached to a BCB edge.
-    /// The edge must not already have a counter.
+    /// Creates a new physical counter for a BCB edge.
     fn make_phys_edge_counter(
         &mut self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
     ) -> BcbCounter {
-        let counter = self.make_counter_inner(CounterIncrementSite::Edge { from_bcb, to_bcb });
-        debug!(?from_bcb, ?to_bcb, ?counter, "edge gets a physical counter");
-        self.set_bcb_edge_counter(from_bcb, to_bcb, counter)
+        self.make_counter_inner(CounterIncrementSite::Edge { from_bcb, to_bcb })
     }
 
     fn make_expression(&mut self, lhs: BcbCounter, op: Op, rhs: BcbCounter) -> BcbCounter {
@@ -193,35 +186,31 @@ impl CoverageCounters {
         self.counter_increment_sites.len()
     }
 
-    fn set_bcb_counter(&mut self, bcb: BasicCoverageBlock, counter_kind: BcbCounter) -> BcbCounter {
-        if let Some(replaced) = self.bcb_counters[bcb].replace(counter_kind) {
-            bug!(
-                "attempt to set a BasicCoverageBlock coverage counter more than once; \
-                {bcb:?} already had counter {replaced:?}",
-            );
-        } else {
-            counter_kind
-        }
+    fn set_node_counter(&mut self, bcb: BasicCoverageBlock, counter: BcbCounter) -> BcbCounter {
+        let existing = self.node_counters[bcb].replace(counter);
+        assert!(
+            existing.is_none(),
+            "node {bcb:?} already has a counter: {existing:?} => {counter:?}"
+        );
+        counter
     }
 
-    fn set_bcb_edge_counter(
+    fn set_edge_counter(
         &mut self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
-        counter_kind: BcbCounter,
+        counter: BcbCounter,
     ) -> BcbCounter {
-        if let Some(replaced) = self.bcb_edge_counters.insert((from_bcb, to_bcb), counter_kind) {
-            bug!(
-                "attempt to set an edge counter more than once; from_bcb: \
-                {from_bcb:?} already had counter {replaced:?}",
-            );
-        } else {
-            counter_kind
-        }
+        let existing = self.edge_counters.insert((from_bcb, to_bcb), counter);
+        assert!(
+            existing.is_none(),
+            "edge ({from_bcb:?} -> {to_bcb:?}) already has a counter: {existing:?} => {counter:?}"
+        );
+        counter
     }
 
     pub(super) fn term_for_bcb(&self, bcb: BasicCoverageBlock) -> Option<CovTerm> {
-        self.bcb_counters[bcb].map(|counter| counter.as_term())
+        self.node_counters[bcb].map(|counter| counter.as_term())
     }
 
     /// Returns an iterator over all the nodes/edges in the coverage graph that
@@ -238,7 +227,7 @@ impl CoverageCounters {
     pub(super) fn bcb_nodes_with_coverage_expressions(
         &self,
     ) -> impl Iterator<Item = (BasicCoverageBlock, ExpressionId)> + Captures<'_> {
-        self.bcb_counters.iter_enumerated().filter_map(|(bcb, &counter_kind)| match counter_kind {
+        self.node_counters.iter_enumerated().filter_map(|(bcb, &counter)| match counter {
             // Yield the BCB along with its associated expression ID.
             Some(BcbCounter::Expression { id }) => Some((bcb, id)),
             // This BCB is associated with a counter or nothing, so skip it.
@@ -265,22 +254,20 @@ impl CoverageCounters {
     }
 }
 
-/// Helper struct that allows counter creation to inspect the BCB graph.
-struct MakeBcbCounters<'a> {
-    coverage_counters: CoverageCounters,
-    basic_coverage_blocks: &'a CoverageGraph,
+/// Helper struct that allows counter creation to inspect the BCB graph, and
+/// the set of nodes that need counters.
+struct CountersBuilder<'a> {
+    counters: CoverageCounters,
+    graph: &'a CoverageGraph,
     bcb_needs_counter: &'a BitSet<BasicCoverageBlock>,
 }
 
-impl<'a> MakeBcbCounters<'a> {
-    fn new(
-        basic_coverage_blocks: &'a CoverageGraph,
-        bcb_needs_counter: &'a BitSet<BasicCoverageBlock>,
-    ) -> Self {
-        assert_eq!(basic_coverage_blocks.num_nodes(), bcb_needs_counter.domain_size());
+impl<'a> CountersBuilder<'a> {
+    fn new(graph: &'a CoverageGraph, bcb_needs_counter: &'a BitSet<BasicCoverageBlock>) -> Self {
+        assert_eq!(graph.num_nodes(), bcb_needs_counter.domain_size());
         Self {
-            coverage_counters: CoverageCounters::with_num_bcbs(basic_coverage_blocks.num_nodes()),
-            basic_coverage_blocks,
+            counters: CoverageCounters::with_num_bcbs(graph.num_nodes()),
+            graph,
             bcb_needs_counter,
         }
     }
@@ -295,7 +282,7 @@ impl<'a> MakeBcbCounters<'a> {
         // nodes within the loop are visited before visiting any nodes outside
         // the loop. It also keeps track of which loop(s) the traversal is
         // currently inside.
-        let mut traversal = TraverseCoverageGraphWithLoops::new(self.basic_coverage_blocks);
+        let mut traversal = TraverseCoverageGraphWithLoops::new(self.graph);
         while let Some(bcb) = traversal.next() {
             let _span = debug_span!("traversal", ?bcb).entered();
             if self.bcb_needs_counter.contains(bcb) {
@@ -322,25 +309,35 @@ impl<'a> MakeBcbCounters<'a> {
         // We might also use that counter to compute one of the out-edge counters.
         let node_counter = self.get_or_make_node_counter(from_bcb);
 
-        let successors = self.basic_coverage_blocks.successors[from_bcb].as_slice();
+        let successors = self.graph.successors[from_bcb].as_slice();
 
         // If this node's out-edges won't sum to the node's counter,
         // then there's no reason to create edge counters here.
-        if !self.basic_coverage_blocks[from_bcb].is_out_summable {
+        if !self.graph[from_bcb].is_out_summable {
             return;
         }
 
-        // Determine the set of out-edges that don't yet have edge counters.
-        let candidate_successors = self.basic_coverage_blocks.successors[from_bcb]
+        // When choosing which out-edge should be given a counter expression, ignore edges that
+        // already have counters, or could use the existing counter of their target node.
+        let out_edge_has_counter = |to_bcb| {
+            if self.counters.edge_counters.contains_key(&(from_bcb, to_bcb)) {
+                return true;
+            }
+            self.graph.sole_predecessor(to_bcb) == Some(from_bcb)
+                && self.counters.node_counters[to_bcb].is_some()
+        };
+
+        // Determine the set of out-edges that could benefit from being given an expression.
+        let candidate_successors = self.graph.successors[from_bcb]
             .iter()
             .copied()
-            .filter(|&to_bcb| self.edge_has_no_counter(from_bcb, to_bcb))
+            .filter(|&to_bcb| !out_edge_has_counter(to_bcb))
             .collect::<Vec<_>>();
         debug!(?candidate_successors);
 
         // If there are out-edges without counters, choose one to be given an expression
         // (computed from this node and the other out-edges) instead of a physical counter.
-        let Some(expression_to_bcb) =
+        let Some(target_bcb) =
             self.choose_out_edge_for_expression(traversal, &candidate_successors)
         else {
             return;
@@ -353,43 +350,44 @@ impl<'a> MakeBcbCounters<'a> {
             .iter()
             .copied()
             // Skip the chosen edge, since we'll calculate its count from this sum.
-            .filter(|&to_bcb| to_bcb != expression_to_bcb)
+            .filter(|&edge_target_bcb| edge_target_bcb != target_bcb)
             .map(|to_bcb| self.get_or_make_edge_counter(from_bcb, to_bcb))
             .collect::<Vec<_>>();
-        let Some(sum_of_all_other_out_edges) =
-            self.coverage_counters.make_sum(&other_out_edge_counters)
+        let Some(sum_of_all_other_out_edges) = self.counters.make_sum(&other_out_edge_counters)
         else {
             return;
         };
 
         // Now create an expression for the chosen edge, by taking the counter
         // for its source node and subtracting the sum of its sibling out-edges.
-        let expression = self.coverage_counters.make_expression(
-            node_counter,
-            Op::Subtract,
-            sum_of_all_other_out_edges,
-        );
+        let expression =
+            self.counters.make_expression(node_counter, Op::Subtract, sum_of_all_other_out_edges);
 
-        debug!("{expression_to_bcb:?} gets an expression: {expression:?}");
-        if let Some(sole_pred) = self.basic_coverage_blocks.sole_predecessor(expression_to_bcb) {
-            // This edge normally wouldn't get its own counter, so attach the expression
-            // to its target node instead, so that `edge_has_no_counter` can see it.
-            assert_eq!(sole_pred, from_bcb);
-            self.coverage_counters.set_bcb_counter(expression_to_bcb, expression);
-        } else {
-            self.coverage_counters.set_bcb_edge_counter(from_bcb, expression_to_bcb, expression);
-        }
+        debug!("{target_bcb:?} gets an expression: {expression:?}");
+        self.counters.set_edge_counter(from_bcb, target_bcb, expression);
     }
 
     #[instrument(level = "debug", skip(self))]
     fn get_or_make_node_counter(&mut self, bcb: BasicCoverageBlock) -> BcbCounter {
         // If the BCB already has a counter, return it.
-        if let Some(counter_kind) = self.coverage_counters.bcb_counters[bcb] {
-            debug!("{bcb:?} already has a counter: {counter_kind:?}");
-            return counter_kind;
+        if let Some(counter) = self.counters.node_counters[bcb] {
+            debug!("{bcb:?} already has a counter: {counter:?}");
+            return counter;
+        }
+
+        let counter = self.make_node_counter_inner(bcb);
+        self.counters.set_node_counter(bcb, counter)
+    }
+
+    fn make_node_counter_inner(&mut self, bcb: BasicCoverageBlock) -> BcbCounter {
+        // If the node's sole in-edge already has a counter, use that.
+        if let Some(sole_pred) = self.graph.sole_predecessor(bcb)
+            && let Some(&edge_counter) = self.counters.edge_counters.get(&(sole_pred, bcb))
+        {
+            return edge_counter;
         }
 
-        let predecessors = self.basic_coverage_blocks.predecessors[bcb].as_slice();
+        let predecessors = self.graph.predecessors[bcb].as_slice();
 
         // Handle cases where we can't compute a node's count from its in-edges:
         // - START_BCB has no in-edges, so taking the sum would panic (or be wrong).
@@ -398,7 +396,9 @@ impl<'a> MakeBcbCounters<'a> {
         //   leading to infinite recursion.
         if predecessors.len() <= 1 || predecessors.contains(&bcb) {
             debug!(?bcb, ?predecessors, "node has <=1 predecessors or is its own predecessor");
-            return self.coverage_counters.make_phys_node_counter(bcb);
+            let counter = self.counters.make_phys_node_counter(bcb);
+            debug!(?bcb, ?counter, "node gets a physical counter");
+            return counter;
         }
 
         // A BCB with multiple incoming edges can compute its count by ensuring that counters
@@ -408,13 +408,11 @@ impl<'a> MakeBcbCounters<'a> {
             .copied()
             .map(|from_bcb| self.get_or_make_edge_counter(from_bcb, bcb))
             .collect::<Vec<_>>();
-        let sum_of_in_edges: BcbCounter = self
-            .coverage_counters
-            .make_sum(&in_edge_counters)
-            .expect("there must be at least one in-edge");
+        let sum_of_in_edges: BcbCounter =
+            self.counters.make_sum(&in_edge_counters).expect("there must be at least one in-edge");
 
         debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}");
-        self.coverage_counters.set_bcb_counter(bcb, sum_of_in_edges)
+        sum_of_in_edges
     }
 
     #[instrument(level = "debug", skip(self))]
@@ -423,9 +421,24 @@ impl<'a> MakeBcbCounters<'a> {
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
     ) -> BcbCounter {
+        // If the edge already has a counter, return it.
+        if let Some(&counter) = self.counters.edge_counters.get(&(from_bcb, to_bcb)) {
+            debug!("Edge {from_bcb:?}->{to_bcb:?} already has a counter: {counter:?}");
+            return counter;
+        }
+
+        let counter = self.make_edge_counter_inner(from_bcb, to_bcb);
+        self.counters.set_edge_counter(from_bcb, to_bcb, counter)
+    }
+
+    fn make_edge_counter_inner(
+        &mut self,
+        from_bcb: BasicCoverageBlock,
+        to_bcb: BasicCoverageBlock,
+    ) -> BcbCounter {
         // If the target node has exactly one in-edge (i.e. this one), then just
         // use the node's counter, since it will have the same value.
-        if let Some(sole_pred) = self.basic_coverage_blocks.sole_predecessor(to_bcb) {
+        if let Some(sole_pred) = self.graph.sole_predecessor(to_bcb) {
             assert_eq!(sole_pred, from_bcb);
             // This call must take care not to invoke `get_or_make_edge` for
             // this edge, since that would result in infinite recursion!
@@ -434,21 +447,15 @@ impl<'a> MakeBcbCounters<'a> {
 
         // If the source node has exactly one out-edge (i.e. this one) and would have
         // the same execution count as that edge, then just use the node's counter.
-        if let Some(simple_succ) = self.basic_coverage_blocks.simple_successor(from_bcb) {
+        if let Some(simple_succ) = self.graph.simple_successor(from_bcb) {
             assert_eq!(simple_succ, to_bcb);
             return self.get_or_make_node_counter(from_bcb);
         }
 
-        // If the edge already has a counter, return it.
-        if let Some(&counter_kind) =
-            self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb))
-        {
-            debug!("Edge {from_bcb:?}->{to_bcb:?} already has a counter: {counter_kind:?}");
-            return counter_kind;
-        }
-
         // Make a new counter to count this edge.
-        self.coverage_counters.make_phys_edge_counter(from_bcb, to_bcb)
+        let counter = self.counters.make_phys_edge_counter(from_bcb, to_bcb);
+        debug!(?from_bcb, ?to_bcb, ?counter, "edge gets a physical counter");
+        counter
     }
 
     /// Given a set of candidate out-edges (represented by their successor node),
@@ -493,9 +500,9 @@ impl<'a> MakeBcbCounters<'a> {
             for &target_bcb in candidate_successors {
                 // An edge is a reloop edge if its target dominates any BCB that has
                 // an edge back to the loop header. (Otherwise it's an exit edge.)
-                let is_reloop_edge = reloop_bcbs.iter().any(|&reloop_bcb| {
-                    self.basic_coverage_blocks.dominates(target_bcb, reloop_bcb)
-                });
+                let is_reloop_edge = reloop_bcbs
+                    .iter()
+                    .any(|&reloop_bcb| self.graph.dominates(target_bcb, reloop_bcb));
                 if is_reloop_edge {
                     // We found a good out-edge to be given an expression.
                     return Some(target_bcb);
@@ -508,21 +515,4 @@ impl<'a> MakeBcbCounters<'a> {
 
         None
     }
-
-    #[inline]
-    fn edge_has_no_counter(
-        &self,
-        from_bcb: BasicCoverageBlock,
-        to_bcb: BasicCoverageBlock,
-    ) -> bool {
-        let edge_counter =
-            if let Some(sole_pred) = self.basic_coverage_blocks.sole_predecessor(to_bcb) {
-                assert_eq!(sole_pred, from_bcb);
-                self.coverage_counters.bcb_counters[to_bcb]
-            } else {
-                self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb)).copied()
-            };
-
-        edge_counter.is_none()
-    }
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index d839f46cfbd..930fa129ef2 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -21,6 +21,10 @@ pub(crate) struct CoverageGraph {
     pub(crate) successors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
     pub(crate) predecessors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
     dominators: Option<Dominators<BasicCoverageBlock>>,
+    /// Allows nodes to be compared in some total order such that _if_
+    /// `a` dominates `b`, then `a < b`. If neither node dominates the other,
+    /// their relative order is consistent but arbitrary.
+    dominator_order_rank: IndexVec<BasicCoverageBlock, u32>,
 }
 
 impl CoverageGraph {
@@ -54,10 +58,27 @@ impl CoverageGraph {
             }
         }
 
-        let mut this = Self { bcbs, bb_to_bcb, successors, predecessors, dominators: None };
+        let num_nodes = bcbs.len();
+        let mut this = Self {
+            bcbs,
+            bb_to_bcb,
+            successors,
+            predecessors,
+            dominators: None,
+            dominator_order_rank: IndexVec::from_elem_n(0, num_nodes),
+        };
+        assert_eq!(num_nodes, this.num_nodes());
 
         this.dominators = Some(dominators::dominators(&this));
 
+        // The dominator rank of each node is just its index in a reverse-postorder traversal.
+        let reverse_post_order = graph::iterate::reverse_post_order(&this, this.start_node());
+        // The coverage graph is created by traversal, so all nodes are reachable.
+        assert_eq!(reverse_post_order.len(), this.num_nodes());
+        for (rank, bcb) in (0u32..).zip(reverse_post_order) {
+            this.dominator_order_rank[bcb] = rank;
+        }
+
         // The coverage graph's entry-point node (bcb0) always starts with bb0,
         // which never has predecessors. Any other blocks merged into bcb0 can't
         // have multiple (coverage-relevant) predecessors, so bcb0 always has
@@ -162,7 +183,7 @@ impl CoverageGraph {
         a: BasicCoverageBlock,
         b: BasicCoverageBlock,
     ) -> Ordering {
-        self.dominators.as_ref().unwrap().cmp_in_dominator_order(a, b)
+        self.dominator_order_rank[a].cmp(&self.dominator_order_rank[b])
     }
 
     /// Returns the source of this node's sole in-edge, if it has exactly one.
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index f4ac4d9fee6..30e1ac05e03 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -58,8 +58,7 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
         let param_env = tcx.param_env_reveal_all_normalized(def_id);
         // For types that do not need dropping, the behaviour is trivial. So we only need to track
         // init/uninit for types that do need dropping.
-        let move_data =
-            MoveData::gather_moves(body, tcx, param_env, |ty| ty.needs_drop(tcx, param_env));
+        let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, param_env));
         let elaborate_patch = {
             let env = MoveDataParamEnv { move_data, param_env };
 
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index 2f97c408f2a..08923748eb2 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -602,7 +602,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             Len(place) => {
                 let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind()
                 {
-                    n.try_eval_target_usize(self.tcx, self.param_env)?
+                    n.try_to_target_usize(self.tcx)?
                 } else {
                     match self.get_const(place)? {
                         Value::Immediate(src) => src.len(&self.ecx).discard_err()?,
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index d963ca5c485..86c4b241a2b 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -329,7 +329,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                     // Determine the type of the thing we are indexing.
                     && let ty::Array(_, len) = place_base.ty(self.body, self.tcx).ty.kind()
                     // It's an array; determine its length.
-                    && let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env)
+                    && let Some(len) = len.try_to_target_usize(self.tcx)
                     // If the index is in-bounds, go ahead.
                     && idx < len
                 {
@@ -407,7 +407,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                 // mutably without consequences. However, only &mut []
                 // is allowed right now.
                 if let ty::Array(_, len) = ty.kind() {
-                    match len.try_eval_target_usize(self.tcx, self.param_env) {
+                    match len.try_to_target_usize(self.tcx) {
                         Some(0) => {}
                         _ => return Err(Unpromotable),
                     }
diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
index e6647edf3f5..09969a4c7cc 100644
--- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
+++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
@@ -19,8 +19,7 @@ pub(super) struct RemoveUninitDrops;
 impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let param_env = tcx.param_env(body.source.def_id());
-        let move_data =
-            MoveData::gather_moves(body, tcx, param_env, |ty| ty.needs_drop(tcx, param_env));
+        let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, param_env));
 
         let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
             .into_engine(tcx, body)
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index f49f3a1a3bf..71ce0cce772 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -16,7 +16,7 @@ use rustc_type_ir::fold::TypeFoldable;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::relate::solver_relating::RelateExt;
 use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, InferCtxtLike, Interner};
-use tracing::{instrument, trace};
+use tracing::{debug, instrument, trace};
 
 use crate::canonicalizer::{CanonicalizeMode, Canonicalizer};
 use crate::delegate::SolverDelegate;
@@ -165,12 +165,22 @@ where
         // HACK: We bail with overflow if the response would have too many non-region
         // inference variables. This tends to only happen if we encounter a lot of
         // ambiguous alias types which get replaced with fresh inference variables
-        // during generalization. This prevents a hang in nalgebra.
-        let num_non_region_vars = canonical.variables.iter().filter(|c| !c.is_region()).count();
-        if num_non_region_vars > self.cx().recursion_limit() {
-            return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
-                suggest_increasing_limit: true,
-            }));
+        // during generalization. This prevents hangs caused by an exponential blowup,
+        // see tests/ui/traits/next-solver/coherence-alias-hang.rs.
+        //
+        // We don't do so for `NormalizesTo` goals as we erased the expected term and
+        // bailing with overflow here would prevent us from detecting a type-mismatch,
+        // causing a coherence error in diesel, see #131969. We still bail with verflow
+        // when later returning from the parent AliasRelate goal.
+        if !self.is_normalizes_to_goal {
+            let num_non_region_vars =
+                canonical.variables.iter().filter(|c| !c.is_region() && c.is_existential()).count();
+            if num_non_region_vars > self.cx().recursion_limit() {
+                debug!(?num_non_region_vars, "too many inference variables -> overflow");
+                return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
+                    suggest_increasing_limit: true,
+                }));
+            }
         }
 
         Ok(canonical)
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index ff91fa13fd0..a475a58e483 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -295,6 +295,37 @@ where
             Ok(ty)
         }
     }
+
+    /// Normalize a const for when it is structurally matched on, or more likely
+    /// when it needs `.try_to_*` called on it (e.g. to turn it into a usize).
+    ///
+    /// This function is necessary in nearly all cases before matching on a const.
+    /// Not doing so is likely to be incomplete and therefore unsound during
+    /// coherence.
+    #[instrument(level = "trace", skip(self, param_env), ret)]
+    fn structurally_normalize_const(
+        &mut self,
+        param_env: I::ParamEnv,
+        ct: I::Const,
+    ) -> Result<I::Const, NoSolution> {
+        if let ty::ConstKind::Unevaluated(..) = ct.kind() {
+            let normalized_ct = self.next_const_infer();
+            let alias_relate_goal = Goal::new(
+                self.cx(),
+                param_env,
+                ty::PredicateKind::AliasRelate(
+                    ct.into(),
+                    normalized_ct.into(),
+                    ty::AliasRelationDirection::Equate,
+                ),
+            );
+            self.add_goal(GoalSource::Misc, alias_relate_goal);
+            self.try_evaluate_added_goals()?;
+            Ok(self.resolve_vars_if_possible(normalized_ct))
+        } else {
+            Ok(ct)
+        }
+    }
 }
 
 fn response_no_constraints_raw<I: Interner>(
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 2cbed0bceb2..a8d6536baad 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -627,11 +627,16 @@ where
         }
 
         ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
+            let assume = ecx.structurally_normalize_const(
+                goal.param_env,
+                goal.predicate.trait_ref.args.const_at(2),
+            )?;
+
             let certainty = ecx.is_transmutable(
                 goal.param_env,
                 goal.predicate.trait_ref.args.type_at(0),
                 goal.predicate.trait_ref.args.type_at(1),
-                goal.predicate.trait_ref.args.const_at(2),
+                assume,
             )?;
             ecx.evaluate_added_goals_and_make_canonical_response(certainty)
         })
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index e5a14f6a156..3f98236595b 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -245,6 +245,19 @@ passes_doc_test_unknown_include =
     unknown `doc` attribute `{$path}`
     .suggestion = use `doc = include_str!` instead
 
+passes_doc_test_unknown_passes =
+    unknown `doc` attribute `{$path}`
+    .note = `doc` attribute `{$path}` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136>
+    .label = no longer functions
+    .help = you may want to use `doc(document_private_items)`
+    .no_op_note = `doc({$path})` is now a no-op
+
+passes_doc_test_unknown_plugins =
+    unknown `doc` attribute `{$path}`
+    .note = `doc` attribute `{$path}` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136> and CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622>
+    .label = no longer functions
+    .no_op_note = `doc({$path})` is now a no-op
+
 passes_doc_test_unknown_spotlight =
     unknown `doc` attribute `{$path}`
     .note = `doc(spotlight)` was renamed to `doc(notable_trait)`
@@ -256,7 +269,7 @@ passes_duplicate_diagnostic_item_in_crate =
     .note = the diagnostic item is first defined in crate `{$orig_crate_name}`
 
 passes_duplicate_feature_err =
-    the feature `{$feature}` has already been declared
+    the feature `{$feature}` has already been enabled
 
 passes_duplicate_lang_item =
     found duplicate lang item `{$lang_item_name}`
@@ -553,9 +566,9 @@ passes_only_has_effect_on =
         *[unspecified] (unspecified--this is a compiler bug)
     }
 
-passes_optimize_not_fn_or_closure =
-    attribute should be applied to function or closure
-    .label = not a function or closure
+passes_optimize_invalid_target =
+    attribute applied to an invalid target
+    .label = invalid target
 
 passes_outer_crate_level_attr =
     crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 4516ea94cad..298c065b059 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -124,7 +124,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 }
                 [sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
                 [sym::coverage, ..] => self.check_coverage(attr, span, target),
-                [sym::optimize, ..] => self.check_optimize(hir_id, attr, target),
+                [sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target),
                 [sym::no_sanitize, ..] => {
                     self.check_applied_to_fn_or_method(hir_id, attr, span, target)
                 }
@@ -433,23 +433,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
 
     /// Checks that `#[optimize(..)]` is applied to a function/closure/method,
     /// or to an impl block or module.
-    // FIXME(#128488): this should probably be elevated to an error?
-    fn check_optimize(&self, hir_id: HirId, attr: &Attribute, target: Target) {
-        match target {
+    fn check_optimize(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
+        let is_valid = matches!(
+            target,
             Target::Fn
-            | Target::Closure
-            | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
-            | Target::Impl
-            | Target::Mod => {}
-
-            _ => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr.span,
-                    errors::OptimizeNotFnOrClosure,
-                );
-            }
+                | Target::Closure
+                | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
+        );
+        if !is_valid {
+            self.dcx().emit_err(errors::OptimizeInvalidTarget {
+                attr_span: attr.span,
+                defn_span: span,
+                on_crate: hir_id == CRATE_HIR_ID,
+            });
         }
     }
 
@@ -1187,15 +1183,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
 
                         sym::masked => self.check_doc_masked(attr, meta, hir_id, target),
 
-                        // no_default_passes: deprecated
-                        // passes: deprecated
-                        // plugins: removed, but rustdoc warns about it itself
-                        sym::cfg
-                        | sym::hidden
-                        | sym::no_default_passes
-                        | sym::notable_trait
-                        | sym::passes
-                        | sym::plugins => {}
+                        sym::cfg | sym::hidden | sym::notable_trait => {}
 
                         sym::rust_logo => {
                             if self.check_attr_crate_level(attr, meta, hir_id)
@@ -1244,6 +1232,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                         sugg: (attr.meta().unwrap().span, applicability),
                                     },
                                 );
+                            } else if i_meta.has_name(sym::passes)
+                                || i_meta.has_name(sym::no_default_passes)
+                            {
+                                self.tcx.emit_node_span_lint(
+                                    INVALID_DOC_ATTRIBUTES,
+                                    hir_id,
+                                    i_meta.span,
+                                    errors::DocTestUnknownPasses { path, span: i_meta.span },
+                                );
+                            } else if i_meta.has_name(sym::plugins) {
+                                self.tcx.emit_node_span_lint(
+                                    INVALID_DOC_ATTRIBUTES,
+                                    hir_id,
+                                    i_meta.span,
+                                    errors::DocTestUnknownPlugins { path, span: i_meta.span },
+                                );
                             } else {
                                 self.tcx.emit_node_span_lint(
                                     INVALID_DOC_ATTRIBUTES,
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 0dad94a9939..ca13ca11673 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -87,7 +87,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
         let is_feature_allowed = |feature_gate| {
             // All features require that the corresponding gate be enabled,
             // even if the function has `#[rustc_allow_const_fn_unstable(the_gate)]`.
-            if !tcx.features().active(feature_gate) {
+            if !tcx.features().enabled(feature_gate) {
                 return false;
             }
 
@@ -135,7 +135,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
 
         let required_gates = required_gates.unwrap_or(&[]);
         let missing_gates: Vec<_> =
-            required_gates.iter().copied().filter(|&g| !features.active(g)).collect();
+            required_gates.iter().copied().filter(|&g| !features.enabled(g)).collect();
 
         match missing_gates.as_slice() {
             [] => {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 6dc3dfba58f..042e50d890e 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -76,9 +76,15 @@ pub(crate) struct CoverageNotFnOrClosure {
     pub defn_span: Span,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_optimize_not_fn_or_closure)]
-pub(crate) struct OptimizeNotFnOrClosure;
+#[derive(Diagnostic)]
+#[diag(passes_optimize_invalid_target)]
+pub(crate) struct OptimizeInvalidTarget {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub defn_span: Span,
+    pub on_crate: bool,
+}
 
 #[derive(Diagnostic)]
 #[diag(passes_should_be_applied_to_fn)]
@@ -318,6 +324,27 @@ pub(crate) struct DocTestUnknownSpotlight {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(passes_doc_test_unknown_passes)]
+#[note]
+#[help]
+#[note(passes_no_op_note)]
+pub(crate) struct DocTestUnknownPasses {
+    pub path: String,
+    #[label]
+    pub span: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(passes_doc_test_unknown_plugins)]
+#[note]
+#[note(passes_no_op_note)]
+pub(crate) struct DocTestUnknownPlugins {
+    pub path: String,
+    #[label]
+    pub span: Span,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(passes_doc_test_unknown_include)]
 pub(crate) struct DocTestUnknownInclude {
     pub path: String,
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index a4c3d789176..27714a0fdcc 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -122,7 +122,9 @@ impl<'k> StatCollector<'k> {
         // We will soon sort, so the initial order does not matter.
         #[allow(rustc::potential_query_instability)]
         let mut nodes: Vec<_> = self.nodes.iter().collect();
-        nodes.sort_by_key(|(_, node)| node.stats.count * node.stats.size);
+        nodes.sort_by_cached_key(|(label, node)| {
+            (node.stats.count * node.stats.size, label.to_owned())
+        });
 
         let total_size = nodes.iter().map(|(_, node)| node.stats.count * node.stats.size).sum();
 
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 056318fbcb7..0ec151ceb45 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -322,7 +322,7 @@ impl<'tcx> ReachableContext<'tcx> {
                     self.visit(ty);
                     // Manually visit to actually see the trait's `DefId`. Type visitors won't see it
                     if let Some(trait_ref) = dyn_ty.principal() {
-                        let ExistentialTraitRef { def_id, args } = trait_ref.skip_binder();
+                        let ExistentialTraitRef { def_id, args, .. } = trait_ref.skip_binder();
                         self.visit_def_id(def_id, "", &"");
                         self.visit(args);
                     }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 751c87a9fe5..80ac2741c38 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -935,9 +935,9 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
         tcx.hir().visit_all_item_likes_in_crate(&mut missing);
     }
 
-    let declared_lang_features = &tcx.features().declared_lang_features;
+    let enabled_lang_features = tcx.features().enabled_lang_features();
     let mut lang_features = UnordSet::default();
-    for &(feature, span, since) in declared_lang_features {
+    for &(feature, span, since) in enabled_lang_features {
         if let Some(since) = since {
             // Warn if the user has enabled an already-stable lang feature.
             unnecessary_stable_feature_lint(tcx, span, feature, since);
@@ -948,9 +948,9 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
         }
     }
 
-    let declared_lib_features = &tcx.features().declared_lib_features;
+    let enabled_lib_features = tcx.features().enabled_lib_features();
     let mut remaining_lib_features = FxIndexMap::default();
-    for (feature, span) in declared_lib_features {
+    for (feature, span) in enabled_lib_features {
         if remaining_lib_features.contains_key(&feature) {
             // Warn if the user enables a lib feature multiple times.
             tcx.dcx().emit_err(errors::DuplicateFeatureErr { span: *span, feature: *feature });
@@ -961,7 +961,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
     // recognise the feature when building std.
     // Likewise, libtest is handled specially, so `test` isn't
     // available as we'd like it to be.
-    // FIXME: only remove `libc` when `stdbuild` is active.
+    // FIXME: only remove `libc` when `stdbuild` is enabled.
     // FIXME: remove special casing for `test`.
     // FIXME(#120456) - is `swap_remove` correct?
     remaining_lib_features.swap_remove(&sym::libc);
@@ -1021,7 +1021,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
     // All local crate implications need to have the feature that implies it confirmed to exist.
     let mut remaining_implications = tcx.stability_implications(LOCAL_CRATE).clone();
 
-    // We always collect the lib features declared in the current crate, even if there are
+    // We always collect the lib features enabled in the current crate, even if there are
     // no unknown features, because the collection also does feature attribute validation.
     let local_defined_features = tcx.lib_features(LOCAL_CRATE);
     if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml
index 0cb47e03441..34fb1bdf6fa 100644
--- a/compiler/rustc_pattern_analysis/Cargo.toml
+++ b/compiler/rustc_pattern_analysis/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-rustc-hash = "1.1.0"
+rustc-hash = "2.0.0"
 rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena", optional = true }
 rustc_data_structures = { path = "../rustc_data_structures", optional = true }
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index f67c4cb922c..7827975d3ca 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -32,8 +32,8 @@ use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility,
 use rustc_middle::query::Providers;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
 use rustc_middle::ty::{
-    self, Const, GenericArgs, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable,
-    TypeVisitable, TypeVisitor,
+    self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
+    TypeVisitor,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
@@ -246,10 +246,10 @@ where
                         ty::ExistentialPredicate::Trait(trait_ref) => trait_ref,
                         ty::ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx),
                         ty::ExistentialPredicate::AutoTrait(def_id) => {
-                            ty::ExistentialTraitRef { def_id, args: GenericArgs::empty() }
+                            ty::ExistentialTraitRef::new(tcx, def_id, ty::GenericArgs::empty())
                         }
                     };
-                    let ty::ExistentialTraitRef { def_id, args: _ } = trait_ref;
+                    let ty::ExistentialTraitRef { def_id, .. } = trait_ref;
                     try_visit!(self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref));
                 }
             }
diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs
index 5e450979273..78c37688d34 100644
--- a/compiler/rustc_query_system/src/ich/impls_syntax.rs
+++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs
@@ -112,10 +112,10 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
         // Unfortunately we cannot exhaustively list fields here, since the
         // struct is macro generated.
-        self.declared_lang_features.hash_stable(hcx, hasher);
-        self.declared_lib_features.hash_stable(hcx, hasher);
+        self.enabled_lang_features().hash_stable(hcx, hasher);
+        self.enabled_lib_features().hash_stable(hcx, hasher);
 
-        self.all_features()[..].hash_stable(hcx, hasher);
+        self.all_lang_features()[..].hash_stable(hcx, hasher);
         for feature in rustc_feature::UNSTABLE_FEATURES.iter() {
             feature.feature.name.hash_stable(hcx, hasher);
         }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 0145ffd3a4b..0ca6bb8c07d 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1193,7 +1193,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         if !ident.as_str().starts_with('_') {
             self.r.unused_macros.insert(def_id, (node_id, ident));
             for (rule_i, rule_span) in &self.r.macro_map[&def_id.to_def_id()].rule_spans {
-                self.r.unused_macro_rules.insert((def_id, *rule_i), (ident, *rule_span));
+                self.r
+                    .unused_macro_rules
+                    .entry(def_id)
+                    .or_default()
+                    .insert(*rule_i, (ident, *rule_span));
             }
         }
     }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 24a0c252e55..35d491cfc18 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1122,7 +1122,8 @@ pub struct Resolver<'ra, 'tcx> {
     local_macro_def_scopes: FxHashMap<LocalDefId, Module<'ra>>,
     ast_transform_scopes: FxHashMap<LocalExpnId, Module<'ra>>,
     unused_macros: FxHashMap<LocalDefId, (NodeId, Ident)>,
-    unused_macro_rules: FxHashMap<(LocalDefId, usize), (Ident, Span)>,
+    /// A map from the macro to all its potentially unused arms.
+    unused_macro_rules: FxIndexMap<LocalDefId, FxHashMap<usize, (Ident, Span)>>,
     proc_macro_stubs: FxHashSet<LocalDefId>,
     /// Traces collected during macro resolution and validated when it's complete.
     single_segment_macro_resolutions:
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index fa2be8216c7..5e38fb5b6c5 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -340,7 +340,9 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
 
     fn record_macro_rule_usage(&mut self, id: NodeId, rule_i: usize) {
         let did = self.local_def_id(id);
-        self.unused_macro_rules.remove(&(did, rule_i));
+        if let Some(rules) = self.unused_macro_rules.get_mut(&did) {
+            rules.remove(&rule_i);
+        }
     }
 
     fn check_unused_macros(&mut self) {
@@ -352,18 +354,24 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
                 BuiltinLintDiag::UnusedMacroDefinition(ident.name),
             );
         }
-        for (&(def_id, arm_i), &(ident, rule_span)) in self.unused_macro_rules.iter() {
-            if self.unused_macros.contains_key(&def_id) {
-                // We already lint the entire macro as unused
-                continue;
+
+        for (&def_id, unused_arms) in self.unused_macro_rules.iter() {
+            let mut unused_arms = unused_arms.iter().collect::<Vec<_>>();
+            unused_arms.sort_by_key(|&(&arm_i, _)| arm_i);
+
+            for (&arm_i, &(ident, rule_span)) in unused_arms {
+                if self.unused_macros.contains_key(&def_id) {
+                    // We already lint the entire macro as unused
+                    continue;
+                }
+                let node_id = self.def_id_to_node_id[def_id];
+                self.lint_buffer.buffer_lint(
+                    UNUSED_MACRO_RULES,
+                    node_id,
+                    rule_span,
+                    BuiltinLintDiag::MacroRuleNeverUsed(arm_i, ident.name),
+                );
             }
-            let node_id = self.def_id_to_node_id[def_id];
-            self.lint_buffer.buffer_lint(
-                UNUSED_MACRO_RULES,
-                node_id,
-                rule_span,
-                BuiltinLintDiag::MacroRuleNeverUsed(arm_i, ident.name),
-            );
         }
     }
 
@@ -999,10 +1007,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             {
                 let feature = stability.feature;
 
-                let is_allowed = |feature| {
-                    self.tcx.features().declared_features.contains(&feature)
-                        || span.allows_unstable(feature)
-                };
+                let is_allowed =
+                    |feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature);
                 let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
                 if !is_allowed(feature) && !allowed_by_implication {
                     let lint_buffer = &mut self.lint_buffer;
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index 53834198f63..ca75952fe3d 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -133,7 +133,9 @@ fn encode_const<'tcx>(
             // bool value false is encoded as 0 and true as 1.
             match ct_ty.kind() {
                 ty::Int(ity) => {
-                    let bits = c.eval_bits(tcx, ty::ParamEnv::reveal_all());
+                    let bits = c
+                        .try_to_bits(tcx, ty::ParamEnv::reveal_all())
+                        .expect("expected monomorphic const in cfi");
                     let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
                     if val < 0 {
                         s.push('n');
@@ -141,7 +143,9 @@ fn encode_const<'tcx>(
                     let _ = write!(s, "{val}");
                 }
                 ty::Uint(_) => {
-                    let val = c.eval_bits(tcx, ty::ParamEnv::reveal_all());
+                    let val = c
+                        .try_to_bits(tcx, ty::ParamEnv::reveal_all())
+                        .expect("expected monomorphic const in cfi");
                     let _ = write!(s, "{val}");
                 }
                 ty::Bool => {
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
index 83dcceeaa84..cba79a02f8b 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
@@ -245,11 +245,15 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
                             alias_ty.to_ty(tcx),
                         );
                         debug!("Resolved {:?} -> {resolved}", alias_ty.to_ty(tcx));
-                        ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
-                            def_id: assoc_ty.def_id,
-                            args: ty::ExistentialTraitRef::erase_self_ty(tcx, super_trait_ref).args,
-                            term: resolved.into(),
-                        })
+                        ty::ExistentialPredicate::Projection(
+                            ty::ExistentialProjection::erase_self_ty(
+                                tcx,
+                                ty::ProjectionPredicate {
+                                    projection_term: alias_ty.into(),
+                                    term: resolved.into(),
+                                },
+                            ),
+                        )
                     })
                 })
         })
@@ -318,10 +322,11 @@ pub(crate) fn transform_instance<'tcx>(
             .lang_items()
             .drop_trait()
             .unwrap_or_else(|| bug!("typeid_for_instance: couldn't get drop_trait lang item"));
-        let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef {
+        let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new_from_args(
+            tcx,
             def_id,
-            args: List::empty(),
-        });
+            ty::List::empty(),
+        ));
         let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
         let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
         instance.args = tcx.mk_args_trait(self_ty, List::empty());
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index 1816d1278fe..893c532f1fb 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -136,3 +136,6 @@ session_unsupported_crate_type_for_target =
     dropping unsupported crate type `{$crate_type}` for target `{$target_triple}`
 
 session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is greater than 5
+
+session_unsupported_regparm = `-Zregparm={$regparm}` is unsupported (valid values 0-3)
+session_unsupported_regparm_arch = `-Zregparm=N` is only supported on x86
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index dbb74d1e244..20e8fb38b88 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -486,6 +486,16 @@ pub(crate) struct FunctionReturnRequiresX86OrX8664;
 pub(crate) struct FunctionReturnThunkExternRequiresNonLargeCodeModel;
 
 #[derive(Diagnostic)]
+#[diag(session_unsupported_regparm)]
+pub(crate) struct UnsupportedRegparm {
+    pub(crate) regparm: u32,
+}
+
+#[derive(Diagnostic)]
+#[diag(session_unsupported_regparm_arch)]
+pub(crate) struct UnsupportedRegparmArch;
+
+#[derive(Diagnostic)]
 #[diag(session_failed_to_create_profiler)]
 pub(crate) struct FailedToCreateProfiler {
     pub(crate) err: String,
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index f9964b59a94..54a4621db24 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -2000,6 +2000,11 @@ options! {
         "enable queries of the dependency graph for regression testing (default: no)"),
     randomize_layout: bool = (false, parse_bool, [TRACKED],
         "randomize the layout of types (default: no)"),
+    regparm: Option<u32> = (None, parse_opt_number, [TRACKED],
+        "On x86-32 targets, setting this to N causes the compiler to pass N arguments \
+        in registers EAX, EDX, and ECX instead of on the stack for\
+        \"C\", \"cdecl\", and \"stdcall\" fn.\
+        It is UNSOUND to link together crates that use different values for this flag!"),
     relax_elf_relocations: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "whether ELF relocations can be relaxed"),
     remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 27879d817b2..1963cf4eb7c 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1337,6 +1337,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
         }
     }
 
+    if let Some(regparm) = sess.opts.unstable_opts.regparm {
+        if regparm > 3 {
+            sess.dcx().emit_err(errors::UnsupportedRegparm { regparm });
+        }
+        if sess.target.arch != "x86" {
+            sess.dcx().emit_err(errors::UnsupportedRegparmArch);
+        }
+    }
+
     // The code model check applies to `thunk` and `thunk-extern`, but not `thunk-inline`, so it is
     // kept as a `match` to force a change if new ones are added, even if we currently only support
     // `thunk-extern` like Clang.
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index e9c3b3ffc1d..7be7db1fd3d 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -380,11 +380,12 @@ impl RustcInternal for ExistentialProjection {
     type T<'tcx> = rustc_ty::ExistentialProjection<'tcx>;
 
     fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
-        rustc_ty::ExistentialProjection {
-            def_id: self.def_id.0.internal(tables, tcx),
-            args: self.generic_args.internal(tables, tcx),
-            term: self.term.internal(tables, tcx),
-        }
+        rustc_ty::ExistentialProjection::new_from_args(
+            tcx,
+            self.def_id.0.internal(tables, tcx),
+            self.generic_args.internal(tables, tcx),
+            self.term.internal(tables, tcx),
+        )
     }
 }
 
@@ -403,10 +404,11 @@ impl RustcInternal for ExistentialTraitRef {
     type T<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>;
 
     fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
-        rustc_ty::ExistentialTraitRef {
-            def_id: self.def_id.0.internal(tables, tcx),
-            args: self.generic_args.internal(tables, tcx),
-        }
+        rustc_ty::ExistentialTraitRef::new_from_args(
+            tcx,
+            self.def_id.0.internal(tables, tcx),
+            self.generic_args.internal(tables, tcx),
+        )
     }
 }
 
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index ed5d2d1e799..8fa8f2ac402 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -406,7 +406,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         let tcx = tables.tcx;
         let mir_const = cnst.internal(&mut *tables, tcx);
         mir_const
-            .try_eval_target_usize(tables.tcx, ParamEnv::empty())
+            .try_to_target_usize(tables.tcx)
             .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
     }
 
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index b9372283feb..ef2ee9a166a 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -68,7 +68,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> {
     type T = stable_mir::ty::ExistentialTraitRef;
 
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
-        let ty::ExistentialTraitRef { def_id, args } = self;
+        let ty::ExistentialTraitRef { def_id, args, .. } = self;
         stable_mir::ty::ExistentialTraitRef {
             def_id: tables.trait_def(*def_id),
             generic_args: args.stable(tables),
@@ -95,7 +95,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> {
     type T = stable_mir::ty::ExistentialProjection;
 
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
-        let ty::ExistentialProjection { def_id, args, term } = self;
+        let ty::ExistentialProjection { def_id, args, term, .. } = self;
         stable_mir::ty::ExistentialProjection {
             def_id: tables.trait_def(*def_id),
             generic_args: args.stable(tables),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 6f62b4f82d7..3ab482072b8 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1913,7 +1913,7 @@ symbols! {
         str_trim,
         str_trim_end,
         str_trim_start,
-        strict_provenance,
+        strict_provenance_lints,
         string_as_mut_str,
         string_as_str,
         string_deref_patterns,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index f3da7ff1ca7..d092fa8f082 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -555,7 +555,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
 
     fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
         // We only mangle a typed value if the const can be evaluated.
-        let ct = ct.normalize(self.tcx, ty::ParamEnv::reveal_all());
         let (ct_ty, valtree) = match ct.kind() {
             ty::ConstKind::Value(ty, val) => (ty, val),
 
@@ -592,7 +591,9 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
                 ct_ty.print(self)?;
 
-                let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all());
+                let mut bits = ct
+                    .try_to_bits(self.tcx, ty::ParamEnv::reveal_all())
+                    .expect("expected const to be monomorphic");
 
                 // Negative integer values are mangled using `n` as a "sign prefix".
                 if let ty::Int(ity) = ct_ty.kind() {
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index 832246495bc..5d120a68059 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -6,7 +6,7 @@ use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
 use crate::abi::{self, Abi, Align, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
-use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt, WasmCAbi};
+use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, WasmCAbi};
 
 mod aarch64;
 mod amdgpu;
@@ -631,7 +631,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
     ) -> Result<(), AdjustForForeignAbiError>
     where
         Ty: TyAbiInterface<'a, C> + Copy,
-        C: HasDataLayout + HasTargetSpec + HasWasmCAbiOpt,
+        C: HasDataLayout + HasTargetSpec + HasWasmCAbiOpt + HasX86AbiOpt,
     {
         if abi == spec::abi::Abi::X86Interrupt {
             if let Some(arg) = self.args.first_mut() {
@@ -643,14 +643,18 @@ impl<'a, Ty> FnAbi<'a, Ty> {
         let spec = cx.target_spec();
         match &spec.arch[..] {
             "x86" => {
-                let flavor = if let spec::abi::Abi::Fastcall { .. }
-                | spec::abi::Abi::Vectorcall { .. } = abi
-                {
-                    x86::Flavor::FastcallOrVectorcall
-                } else {
-                    x86::Flavor::General
+                let (flavor, regparm) = match abi {
+                    spec::abi::Abi::Fastcall { .. } | spec::abi::Abi::Vectorcall { .. } => {
+                        (x86::Flavor::FastcallOrVectorcall, None)
+                    }
+                    spec::abi::Abi::C { .. }
+                    | spec::abi::Abi::Cdecl { .. }
+                    | spec::abi::Abi::Stdcall { .. } => {
+                        (x86::Flavor::General, cx.x86_abi_opt().regparm)
+                    }
+                    _ => (x86::Flavor::General, None),
                 };
-                x86::compute_abi_info(cx, self, flavor);
+                x86::compute_abi_info(cx, self, x86::X86Options { flavor, regparm });
             }
             "x86_64" => match abi {
                 spec::abi::Abi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs
index d9af83d3205..40c3e7a891a 100644
--- a/compiler/rustc_target/src/callconv/x86.rs
+++ b/compiler/rustc_target/src/callconv/x86.rs
@@ -8,7 +8,12 @@ pub(crate) enum Flavor {
     FastcallOrVectorcall,
 }
 
-pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
+pub(crate) struct X86Options {
+    pub flavor: Flavor,
+    pub regparm: Option<u32>,
+}
+
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, opts: X86Options)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
@@ -128,58 +133,77 @@ where
         }
     }
 
-    if flavor == Flavor::FastcallOrVectorcall {
-        // Mark arguments as InReg like clang does it,
-        // so our fastcall/vectorcall is compatible with C/C++ fastcall/vectorcall.
+    fill_inregs(cx, fn_abi, opts, false);
+}
 
-        // Clang reference: lib/CodeGen/TargetInfo.cpp
-        // See X86_32ABIInfo::shouldPrimitiveUseInReg(), X86_32ABIInfo::updateFreeRegs()
+pub(crate) fn fill_inregs<'a, Ty, C>(
+    cx: &C,
+    fn_abi: &mut FnAbi<'a, Ty>,
+    opts: X86Options,
+    rust_abi: bool,
+) where
+    Ty: TyAbiInterface<'a, C> + Copy,
+{
+    if opts.flavor != Flavor::FastcallOrVectorcall && opts.regparm.is_none_or(|x| x == 0) {
+        return;
+    }
+    // Mark arguments as InReg like clang does it,
+    // so our fastcall/vectorcall is compatible with C/C++ fastcall/vectorcall.
 
-        // IsSoftFloatABI is only set to true on ARM platforms,
-        // which in turn can't be x86?
+    // Clang reference: lib/CodeGen/TargetInfo.cpp
+    // See X86_32ABIInfo::shouldPrimitiveUseInReg(), X86_32ABIInfo::updateFreeRegs()
 
-        let mut free_regs = 2;
+    // IsSoftFloatABI is only set to true on ARM platforms,
+    // which in turn can't be x86?
 
-        for arg in fn_abi.args.iter_mut() {
-            let attrs = match arg.mode {
-                PassMode::Ignore
-                | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
-                    continue;
-                }
-                PassMode::Direct(ref mut attrs) => attrs,
-                PassMode::Pair(..)
-                | PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ }
-                | PassMode::Cast { .. } => {
-                    unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode)
-                }
-            };
+    // 2 for fastcall/vectorcall, regparm limited by 3 otherwise
+    let mut free_regs = opts.regparm.unwrap_or(2).into();
+
+    // For types generating PassMode::Cast, InRegs will not be set.
+    // Maybe, this is a FIXME
+    let has_casts = fn_abi.args.iter().any(|arg| matches!(arg.mode, PassMode::Cast { .. }));
+    if has_casts && rust_abi {
+        return;
+    }
 
-            // At this point we know this must be a primitive of sorts.
-            let unit = arg.layout.homogeneous_aggregate(cx).unwrap().unit().unwrap();
-            assert_eq!(unit.size, arg.layout.size);
-            if unit.kind == RegKind::Float {
+    for arg in fn_abi.args.iter_mut() {
+        let attrs = match arg.mode {
+            PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
                 continue;
             }
+            PassMode::Direct(ref mut attrs) => attrs,
+            PassMode::Pair(..)
+            | PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ }
+            | PassMode::Cast { .. } => {
+                unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode)
+            }
+        };
 
-            let size_in_regs = (arg.layout.size.bits() + 31) / 32;
+        // At this point we know this must be a primitive of sorts.
+        let unit = arg.layout.homogeneous_aggregate(cx).unwrap().unit().unwrap();
+        assert_eq!(unit.size, arg.layout.size);
+        if matches!(unit.kind, RegKind::Float | RegKind::Vector) {
+            continue;
+        }
 
-            if size_in_regs == 0 {
-                continue;
-            }
+        let size_in_regs = (arg.layout.size.bits() + 31) / 32;
 
-            if size_in_regs > free_regs {
-                break;
-            }
+        if size_in_regs == 0 {
+            continue;
+        }
 
-            free_regs -= size_in_regs;
+        if size_in_regs > free_regs {
+            break;
+        }
 
-            if arg.layout.size.bits() <= 32 && unit.kind == RegKind::Integer {
-                attrs.set(ArgAttribute::InReg);
-            }
+        free_regs -= size_in_regs;
 
-            if free_regs == 0 {
-                break;
-            }
+        if arg.layout.size.bits() <= 32 && unit.kind == RegKind::Integer {
+            attrs.set(ArgAttribute::InReg);
+        }
+
+        if free_regs == 0 {
+            break;
         }
     }
 }
diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_target/src/spec/abi/mod.rs
index cac0cf9959d..c2095155afa 100644
--- a/compiler/rustc_target/src/spec/abi/mod.rs
+++ b/compiler/rustc_target/src/spec/abi/mod.rs
@@ -184,7 +184,7 @@ pub fn is_enabled(
 ) -> Result<(), AbiDisabled> {
     let s = is_stable(name);
     if let Err(AbiDisabled::Unstable { feature, .. }) = s {
-        if features.active(feature) || span.allows_unstable(feature) {
+        if features.enabled(feature) || span.allows_unstable(feature) {
             return Ok(());
         }
     }
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index f4b45a08195..5ca2a339f72 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2096,6 +2096,18 @@ pub trait HasWasmCAbiOpt {
     fn wasm_c_abi_opt(&self) -> WasmCAbi;
 }
 
+/// x86 (32-bit) abi options.
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct X86Abi {
+    /// On x86-32 targets, the regparm N causes the compiler to pass arguments
+    /// in registers EAX, EDX, and ECX instead of on the stack.
+    pub regparm: Option<u32>,
+}
+
+pub trait HasX86AbiOpt {
+    fn x86_abi_opt(&self) -> X86Abi;
+}
+
 type StaticCow<T> = Cow<'static, T>;
 
 /// Optional aspects of a target specification.
@@ -2757,10 +2769,9 @@ impl Target {
         }
     }
 
-    /// Returns a None if the UNSUPPORTED_CALLING_CONVENTIONS lint should be emitted
-    pub fn is_abi_supported(&self, abi: Abi) -> Option<bool> {
+    pub fn is_abi_supported(&self, abi: Abi) -> bool {
         use Abi::*;
-        Some(match abi {
+        match abi {
             Rust
             | C { .. }
             | System { .. }
@@ -2819,9 +2830,9 @@ impl Target {
             // architectures for which these calling conventions are actually well defined.
             Stdcall { .. } | Fastcall { .. } if self.arch == "x86" => true,
             Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => true,
-            // Return a `None` for other cases so that we know to emit a future compat lint.
-            Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } => return None,
-        })
+            // Reject these calling conventions everywhere else.
+            Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } => false,
+        }
     }
 
     /// Minimum integer size in bits that this target can perform atomic
diff --git a/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs
index 1995de9dd2d..0e0e13fd1d8 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs
@@ -20,6 +20,7 @@ pub(crate) fn target() -> Target {
             max_atomic_width: Some(32),
             atomic_cas: false,
             features: "+forced-atomics".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs
index bd37cf80b48..669c1702fda 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs
@@ -29,6 +29,7 @@ pub(crate) fn target() -> Target {
             atomic_cas: true,
 
             features: "+m".into(),
+            llvm_abiname: "ilp32".into(),
             executables: true,
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs
index 32df30ddb5e..477a6c0e9eb 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs
@@ -20,6 +20,7 @@ pub(crate) fn target() -> Target {
             max_atomic_width: Some(32),
             atomic_cas: false,
             features: "+m,+forced-atomics".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs
index 61c887031bc..68146788d20 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs
@@ -19,6 +19,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv32".into(),
             max_atomic_width: Some(32),
             features: "+m,+a".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs
index 9795af56569..e12c3af6f8f 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs
@@ -27,6 +27,7 @@ pub(crate) fn target() -> Target {
             atomic_cas: true,
 
             features: "+m,+a,+c".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs
index cc28198e3ff..adc76f3cdb5 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs
@@ -19,6 +19,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv32".into(),
             max_atomic_width: Some(32),
             features: "+m,+a,+c".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs
index 62397dcae9a..31c9180c509 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs
@@ -21,6 +21,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv32".into(),
             max_atomic_width: Some(32),
             features: "+m,+a,+c".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Unwind,
             relocation_model: RelocModel::Static,
             ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs
index 0eaabc60cbc..88d112a012d 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs
@@ -20,6 +20,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv32".into(),
             max_atomic_width: Some(32),
             features: "+m,+a,+c".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Unwind,
             relocation_model: RelocModel::Static,
             ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs
index 9ae84ace457..cec97f86538 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs
@@ -30,6 +30,7 @@ pub(crate) fn target() -> Target {
             atomic_cas: true,
 
             features: "+m,+c".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs
index 0ae49debc3a..0e00fc69b41 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs
@@ -20,6 +20,7 @@ pub(crate) fn target() -> Target {
             max_atomic_width: Some(32),
             atomic_cas: false,
             features: "+m,+c,+forced-atomics".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs
index 5f3917edf70..e86549806dd 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs
@@ -21,6 +21,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv32".into(),
             max_atomic_width: Some(32),
             features: "+m,+c".into(),
+            llvm_abiname: "ilp32".into(),
             panic_strategy: PanicStrategy::Unwind,
             relocation_model: RelocModel::Static,
             ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs
index d514f8efcd0..d62ecc07a5d 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs
@@ -22,6 +22,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv64".into(),
             max_atomic_width: Some(64),
             features: "+m,+a,+c".into(),
+            llvm_abiname: "lp64".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
index a737e46de1b..9c181665581 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
@@ -24,6 +24,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv64".into(),
             max_atomic_width: Some(64),
             features: "+m,+a,+c".into(),
+            llvm_abiname: "lp64".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs
index fc5bd846e02..7ed21954fba 100644
--- a/compiler/rustc_target/src/spec/tests/tests_impl.rs
+++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs
@@ -152,6 +152,17 @@ impl Target {
         if self.crt_static_default || self.crt_static_allows_dylibs {
             assert!(self.crt_static_respected);
         }
+
+        // Check that RISC-V targets always specify which ABI they use.
+        match &*self.arch {
+            "riscv32" => {
+                assert_matches!(&*self.llvm_abiname, "ilp32" | "ilp32f" | "ilp32d" | "ilp32e")
+            }
+            "riscv64" => {
+                assert_matches!(&*self.llvm_abiname, "lp64" | "lp64f" | "lp64d" | "lp64q")
+            }
+            _ => {}
+        }
     }
 
     // Add your target to the whitelist if it has `std` library
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 44373ca4866..549beafd196 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
@@ -290,7 +290,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         }
 
                         if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop)
-                            && matches!(predicate_constness, ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const)
+                            && matches!(predicate_constness, Some(ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const))
                         {
                             err.note("`~const Drop` was renamed to `~const Destruct`");
                             err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details");
@@ -2192,7 +2192,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         &self,
         trait_predicate: ty::PolyTraitPredicate<'tcx>,
         message: Option<String>,
-        predicate_constness: ty::BoundConstness,
+        predicate_constness: Option<ty::BoundConstness>,
         append_const_msg: Option<AppendConstMessage>,
         post_message: String,
     ) -> String {
@@ -2200,19 +2200,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             .and_then(|cannot_do_this| {
                 match (predicate_constness, append_const_msg) {
                     // do nothing if predicate is not const
-                    (ty::BoundConstness::NotConst, _) => Some(cannot_do_this),
+                    (None, _) => Some(cannot_do_this),
                     // suggested using default post message
                     (
-                        ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst,
+                        Some(ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst),
                         Some(AppendConstMessage::Default),
                     ) => Some(format!("{cannot_do_this} in const contexts")),
                     // overridden post message
                     (
-                        ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst,
+                        Some(ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst),
                         Some(AppendConstMessage::Custom(custom_msg, _)),
                     ) => Some(format!("{cannot_do_this}{custom_msg}")),
                     // fallback to generic message
-                    (ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst, None) => None,
+                    (Some(ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst), None) => {
+                        None
+                    }
                 }
             })
             .unwrap_or_else(|| {
@@ -2230,124 +2232,143 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         span: Span,
     ) -> GetSafeTransmuteErrorAndReason {
         use rustc_transmute::Answer;
+        self.probe(|_| {
+            // We don't assemble a transmutability candidate for types that are generic
+            // and we should have ambiguity for types that still have non-region infer.
+            if obligation.predicate.has_non_region_param() || obligation.has_non_region_infer() {
+                return GetSafeTransmuteErrorAndReason::Default;
+            }
 
-        // We don't assemble a transmutability candidate for types that are generic
-        // and we should have ambiguity for types that still have non-region infer.
-        if obligation.predicate.has_non_region_param() || obligation.has_non_region_infer() {
-            return GetSafeTransmuteErrorAndReason::Default;
-        }
+            // Erase regions because layout code doesn't particularly care about regions.
+            let trait_ref =
+                self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref));
 
-        // Erase regions because layout code doesn't particularly care about regions.
-        let trait_ref =
-            self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref));
+            let src_and_dst = rustc_transmute::Types {
+                dst: trait_ref.args.type_at(0),
+                src: trait_ref.args.type_at(1),
+            };
 
-        let src_and_dst = rustc_transmute::Types {
-            dst: trait_ref.args.type_at(0),
-            src: trait_ref.args.type_at(1),
-        };
-        let Some(assume) = rustc_transmute::Assume::from_const(
-            self.infcx.tcx,
-            obligation.param_env,
-            trait_ref.args.const_at(2),
-        ) else {
-            self.dcx().span_delayed_bug(
-                span,
-                "Unable to construct rustc_transmute::Assume where it was previously possible",
-            );
-            return GetSafeTransmuteErrorAndReason::Silent;
-        };
+            let ocx = ObligationCtxt::new(self);
+            let Ok(assume) = ocx.structurally_normalize_const(
+                &obligation.cause,
+                obligation.param_env,
+                trait_ref.args.const_at(2),
+            ) else {
+                self.dcx().span_delayed_bug(
+                    span,
+                    "Unable to construct rustc_transmute::Assume where it was previously possible",
+                );
+                return GetSafeTransmuteErrorAndReason::Silent;
+            };
 
-        let dst = trait_ref.args.type_at(0);
-        let src = trait_ref.args.type_at(1);
+            let Some(assume) =
+                rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, assume)
+            else {
+                self.dcx().span_delayed_bug(
+                    span,
+                    "Unable to construct rustc_transmute::Assume where it was previously possible",
+                );
+                return GetSafeTransmuteErrorAndReason::Silent;
+            };
 
-        let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`");
+            let dst = trait_ref.args.type_at(0);
+            let src = trait_ref.args.type_at(1);
+            let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`");
 
-        match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
-            obligation.cause,
-            src_and_dst,
-            assume,
-        ) {
-            Answer::No(reason) => {
-                let safe_transmute_explanation = match reason {
-                    rustc_transmute::Reason::SrcIsNotYetSupported => {
-                        format!("analyzing the transmutability of `{src}` is not yet supported")
-                    }
+            match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
+                obligation.cause,
+                src_and_dst,
+                assume,
+            ) {
+                Answer::No(reason) => {
+                    let safe_transmute_explanation = match reason {
+                        rustc_transmute::Reason::SrcIsNotYetSupported => {
+                            format!("analyzing the transmutability of `{src}` is not yet supported")
+                        }
 
-                    rustc_transmute::Reason::DstIsNotYetSupported => {
-                        format!("analyzing the transmutability of `{dst}` is not yet supported")
-                    }
+                        rustc_transmute::Reason::DstIsNotYetSupported => {
+                            format!("analyzing the transmutability of `{dst}` is not yet supported")
+                        }
 
-                    rustc_transmute::Reason::DstIsBitIncompatible => {
-                        format!("at least one value of `{src}` isn't a bit-valid value of `{dst}`")
-                    }
+                        rustc_transmute::Reason::DstIsBitIncompatible => {
+                            format!(
+                                "at least one value of `{src}` isn't a bit-valid value of `{dst}`"
+                            )
+                        }
 
-                    rustc_transmute::Reason::DstUninhabited => {
-                        format!("`{dst}` is uninhabited")
-                    }
+                        rustc_transmute::Reason::DstUninhabited => {
+                            format!("`{dst}` is uninhabited")
+                        }
 
-                    rustc_transmute::Reason::DstMayHaveSafetyInvariants => {
-                        format!("`{dst}` may carry safety invariants")
-                    }
-                    rustc_transmute::Reason::DstIsTooBig => {
-                        format!("the size of `{src}` is smaller than the size of `{dst}`")
-                    }
-                    rustc_transmute::Reason::DstRefIsTooBig { src, dst } => {
-                        let src_size = src.size;
-                        let dst_size = dst.size;
-                        format!(
-                            "the referent size of `{src}` ({src_size} bytes) is smaller than that of `{dst}` ({dst_size} bytes)"
-                        )
-                    }
-                    rustc_transmute::Reason::SrcSizeOverflow => {
-                        format!(
-                            "values of the type `{src}` are too big for the target architecture"
-                        )
-                    }
-                    rustc_transmute::Reason::DstSizeOverflow => {
-                        format!(
-                            "values of the type `{dst}` are too big for the target architecture"
-                        )
-                    }
-                    rustc_transmute::Reason::DstHasStricterAlignment {
-                        src_min_align,
-                        dst_min_align,
-                    } => {
-                        format!(
-                            "the minimum alignment of `{src}` ({src_min_align}) should be greater than that of `{dst}` ({dst_min_align})"
-                        )
-                    }
-                    rustc_transmute::Reason::DstIsMoreUnique => {
-                        format!("`{src}` is a shared reference, but `{dst}` is a unique reference")
-                    }
-                    // Already reported by rustc
-                    rustc_transmute::Reason::TypeError => {
-                        return GetSafeTransmuteErrorAndReason::Silent;
-                    }
-                    rustc_transmute::Reason::SrcLayoutUnknown => {
-                        format!("`{src}` has an unknown layout")
-                    }
-                    rustc_transmute::Reason::DstLayoutUnknown => {
-                        format!("`{dst}` has an unknown layout")
+                        rustc_transmute::Reason::DstMayHaveSafetyInvariants => {
+                            format!("`{dst}` may carry safety invariants")
+                        }
+                        rustc_transmute::Reason::DstIsTooBig => {
+                            format!("the size of `{src}` is smaller than the size of `{dst}`")
+                        }
+                        rustc_transmute::Reason::DstRefIsTooBig { src, dst } => {
+                            let src_size = src.size;
+                            let dst_size = dst.size;
+                            format!(
+                                "the referent size of `{src}` ({src_size} bytes) \
+                        is smaller than that of `{dst}` ({dst_size} bytes)"
+                            )
+                        }
+                        rustc_transmute::Reason::SrcSizeOverflow => {
+                            format!(
+                                "values of the type `{src}` are too big for the target architecture"
+                            )
+                        }
+                        rustc_transmute::Reason::DstSizeOverflow => {
+                            format!(
+                                "values of the type `{dst}` are too big for the target architecture"
+                            )
+                        }
+                        rustc_transmute::Reason::DstHasStricterAlignment {
+                            src_min_align,
+                            dst_min_align,
+                        } => {
+                            format!(
+                                "the minimum alignment of `{src}` ({src_min_align}) should \
+                        be greater than that of `{dst}` ({dst_min_align})"
+                            )
+                        }
+                        rustc_transmute::Reason::DstIsMoreUnique => {
+                            format!(
+                                "`{src}` is a shared reference, but `{dst}` is a unique reference"
+                            )
+                        }
+                        // Already reported by rustc
+                        rustc_transmute::Reason::TypeError => {
+                            return GetSafeTransmuteErrorAndReason::Silent;
+                        }
+                        rustc_transmute::Reason::SrcLayoutUnknown => {
+                            format!("`{src}` has an unknown layout")
+                        }
+                        rustc_transmute::Reason::DstLayoutUnknown => {
+                            format!("`{dst}` has an unknown layout")
+                        }
+                    };
+                    GetSafeTransmuteErrorAndReason::Error {
+                        err_msg,
+                        safe_transmute_explanation: Some(safe_transmute_explanation),
                     }
-                };
-                GetSafeTransmuteErrorAndReason::Error {
-                    err_msg,
-                    safe_transmute_explanation: Some(safe_transmute_explanation),
                 }
+                // Should never get a Yes at this point! We already ran it before, and did not get a Yes.
+                Answer::Yes => span_bug!(
+                    span,
+                    "Inconsistent rustc_transmute::is_transmutable(...) result, got Yes",
+                ),
+                // Reached when a different obligation (namely `Freeze`) causes the
+                // transmutability analysis to fail. In this case, silence the
+                // transmutability error message in favor of that more specific
+                // error.
+                Answer::If(_) => GetSafeTransmuteErrorAndReason::Error {
+                    err_msg,
+                    safe_transmute_explanation: None,
+                },
             }
-            // Should never get a Yes at this point! We already ran it before, and did not get a Yes.
-            Answer::Yes => span_bug!(
-                span,
-                "Inconsistent rustc_transmute::is_transmutable(...) result, got Yes",
-            ),
-            // Reached when a different obligation (namely `Freeze`) causes the
-            // transmutability analysis to fail. In this case, silence the
-            // transmutability error message in favor of that more specific
-            // error.
-            Answer::If(_) => {
-                GetSafeTransmuteErrorAndReason::Error { err_msg, safe_transmute_explanation: None }
-            }
-        }
+        })
     }
 
     /// For effects predicates such as `<u32 as Add>::Effects: Compat<host>`, pretend that the
@@ -2358,26 +2379,27 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         p: ty::PolyTraitPredicate<'tcx>,
         leaf: ty::PolyTraitPredicate<'tcx>,
         span: Span,
-    ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) {
+    ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, Option<ty::BoundConstness>)
+    {
         let trait_ref = p.to_poly_trait_ref();
         if !self.tcx.is_lang_item(trait_ref.def_id(), LangItem::EffectsCompat) {
-            return (p, leaf, ty::BoundConstness::NotConst);
+            return (p, leaf, None);
         }
 
         let Some(ty::Alias(ty::AliasTyKind::Projection, projection)) =
             trait_ref.self_ty().no_bound_vars().map(Ty::kind)
         else {
-            return (p, leaf, ty::BoundConstness::NotConst);
+            return (p, leaf, None);
         };
 
         let constness = trait_ref.skip_binder().args.const_at(1);
 
         let constness = if constness == self.tcx.consts.true_ || constness.is_ct_infer() {
-            ty::BoundConstness::NotConst
+            None
         } else if constness == self.tcx.consts.false_ {
-            ty::BoundConstness::Const
+            Some(ty::BoundConstness::Const)
         } else if matches!(constness.kind(), ty::ConstKind::Param(_)) {
-            ty::BoundConstness::ConstIfConst
+            Some(ty::BoundConstness::ConstIfConst)
         } else {
             self.dcx().span_bug(span, format!("Unknown constness argument: {constness:?}"));
         };
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index cd41ab9fa6c..7f42c932fcf 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -231,7 +231,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             // Arrays give us `[]`, `[{ty}; _]` and `[{ty}; N]`
             if let ty::Array(aty, len) = self_ty.kind() {
                 flags.push((sym::_Self, Some("[]".to_string())));
-                let len = len.try_to_valtree().and_then(|v| v.try_to_target_usize(self.tcx));
+                let len = len.try_to_target_usize(self.tcx);
                 flags.push((sym::_Self, Some(format!("[{aty}; _]"))));
                 if let Some(n) = len {
                     flags.push((sym::_Self, Some(format!("[{aty}; {n}]"))));
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 733baaa99e5..ff542cfbec1 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3594,52 +3594,64 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
         span: Span,
     ) {
-        if let Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =
-            self.tcx.coroutine_kind(obligation.cause.body_id)
-        {
-            let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
+        let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
 
-            let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
-            let impls_future = self.type_implements_trait(
-                future_trait,
-                [self.tcx.instantiate_bound_regions_with_erased(self_ty)],
-                obligation.param_env,
-            );
-            if !impls_future.must_apply_modulo_regions() {
-                return;
-            }
+        let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
+        let impls_future = self.type_implements_trait(
+            future_trait,
+            [self.tcx.instantiate_bound_regions_with_erased(self_ty)],
+            obligation.param_env,
+        );
+        if !impls_future.must_apply_modulo_regions() {
+            return;
+        }
 
-            let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
-            // `<T as Future>::Output`
-            let projection_ty = trait_pred.map_bound(|trait_pred| {
-                Ty::new_projection(
-                    self.tcx,
-                    item_def_id,
-                    // Future::Output has no args
-                    [trait_pred.self_ty()],
-                )
-            });
-            let InferOk { value: projection_ty, .. } =
-                self.at(&obligation.cause, obligation.param_env).normalize(projection_ty);
+        let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
+        // `<T as Future>::Output`
+        let projection_ty = trait_pred.map_bound(|trait_pred| {
+            Ty::new_projection(
+                self.tcx,
+                item_def_id,
+                // Future::Output has no args
+                [trait_pred.self_ty()],
+            )
+        });
+        let InferOk { value: projection_ty, .. } =
+            self.at(&obligation.cause, obligation.param_env).normalize(projection_ty);
 
-            debug!(
-                normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty)
-            );
-            let try_obligation = self.mk_trait_obligation_with_new_self_ty(
-                obligation.param_env,
-                trait_pred.map_bound(|trait_pred| (trait_pred, projection_ty.skip_binder())),
-            );
-            debug!(try_trait_obligation = ?try_obligation);
-            if self.predicate_may_hold(&try_obligation)
-                && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
-                && snippet.ends_with('?')
-            {
-                err.span_suggestion_verbose(
-                    span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(),
-                    "consider `await`ing on the `Future`",
-                    ".await",
-                    Applicability::MaybeIncorrect,
-                );
+        debug!(
+            normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty)
+        );
+        let try_obligation = self.mk_trait_obligation_with_new_self_ty(
+            obligation.param_env,
+            trait_pred.map_bound(|trait_pred| (trait_pred, projection_ty.skip_binder())),
+        );
+        debug!(try_trait_obligation = ?try_obligation);
+        if self.predicate_may_hold(&try_obligation)
+            && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
+            && snippet.ends_with('?')
+        {
+            match self.tcx.coroutine_kind(obligation.cause.body_id) {
+                Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
+                    err.span_suggestion_verbose(
+                        span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(),
+                        "consider `await`ing on the `Future`",
+                        ".await",
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                _ => {
+                    let mut span: MultiSpan = span.with_lo(span.hi() - BytePos(1)).into();
+                    span.push_span_label(
+                        self.tcx.def_span(obligation.cause.body_id),
+                        "this is not `async`",
+                    );
+                    err.span_note(
+                        span,
+                        "this implements `Future` and its output type supports \
+                        `?`, but the future cannot be awaited in a synchronous function",
+                    );
+                }
             }
         }
     }
@@ -3701,12 +3713,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         }
                         _ => None,
                     };
-                    // Also add host param, if present
-                    let host = self.tcx.generics_of(trait_pred.def_id()).host_effect_index.map(|idx| trait_pred.skip_binder().trait_ref.args[idx]);
                     let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
                         trait_ref: ty::TraitRef::new(self.tcx,
                             trait_pred.def_id(),
-                            [field_ty].into_iter().chain(trait_args).chain(host),
+                            [field_ty].into_iter().chain(trait_args),
                         ),
                         ..*tr
                     });
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index f4a2483cebf..f8fb297e36c 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -298,6 +298,7 @@ fn equate_impl_headers<'tcx>(
 }
 
 /// The result of [fn impl_intersection_has_impossible_obligation].
+#[derive(Debug)]
 enum IntersectionHasImpossibleObligations<'tcx> {
     Yes,
     No {
@@ -328,6 +329,7 @@ enum IntersectionHasImpossibleObligations<'tcx> {
 /// of the two impls above to be empty.
 ///
 /// Importantly, this works even if there isn't a `impl !Error for MyLocalType`.
+#[instrument(level = "debug", skip(selcx), ret)]
 fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligations: &'a [PredicateObligation<'tcx>],
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index a45ec8b3c44..5e270b62b00 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -329,4 +329,15 @@ where
             .at(cause, param_env)
             .structurally_normalize(value, &mut **self.engine.borrow_mut())
     }
+
+    pub fn structurally_normalize_const(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        value: ty::Const<'tcx>,
+    ) -> Result<ty::Const<'tcx>, Vec<E>> {
+        self.infcx
+            .at(cause, param_env)
+            .structurally_normalize_const(value, &mut **self.engine.borrow_mut())
+    }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 0fb795fc184..cffb9b59841 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -368,7 +368,7 @@ pub fn normalize_param_env_or_error<'tcx>(
                     // should actually be okay since without `feature(generic_const_exprs)` the only
                     // const arguments that have a non-empty param env are array repeat counts. These
                     // do not appear in the type system though.
-                    c.normalize(self.0, ty::ParamEnv::empty())
+                    c.normalize_internal(self.0, ty::ParamEnv::empty())
                 }
             }
 
@@ -562,11 +562,20 @@ fn is_impossible_associated_item(
 
     let generics = tcx.generics_of(trait_item_def_id);
     let predicates = tcx.predicates_of(trait_item_def_id);
+
+    // Be conservative in cases where we have `W<T: ?Sized>` and a method like `Self: Sized`,
+    // since that method *may* have some substitutions where the predicates hold.
+    //
+    // This replicates the logic we use in coherence.
+    let infcx =
+        tcx.infer_ctxt().ignoring_regions().with_next_trait_solver(true).intercrate(true).build();
+    let param_env = ty::ParamEnv::empty();
+    let fresh_args = infcx.fresh_args_for_item(tcx.def_span(impl_def_id), impl_def_id);
+
     let impl_trait_ref = tcx
         .impl_trait_ref(impl_def_id)
         .expect("expected impl to correspond to trait")
-        .instantiate_identity();
-    let param_env = tcx.param_env(impl_def_id);
+        .instantiate(tcx, fresh_args);
 
     let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id };
     let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| {
@@ -580,16 +589,9 @@ fn is_impossible_associated_item(
         })
     });
 
-    let infcx = tcx.infer_ctxt().ignoring_regions().build();
-    for obligation in predicates_for_trait {
-        // Ignore overflow error, to be conservative.
-        if let Ok(result) = infcx.evaluate_obligation(&obligation)
-            && !result.may_apply()
-        {
-            return true;
-        }
-    }
-    false
+    let ocx = ObligationCtxt::new(&infcx);
+    ocx.register_obligations(predicates_for_trait);
+    !ocx.select_where_possible().is_empty()
 }
 
 pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 7eac3559348..d246d37f748 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -413,7 +413,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                 self.selcx.infcx,
                 &mut self.universes,
                 constant,
-                |constant| constant.normalize(tcx, self.param_env),
+                |constant| constant.normalize_internal(tcx, self.param_env),
             )
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 7f7c9bced18..cc634b65a0b 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1642,24 +1642,9 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>(
         sig,
     );
 
-    let host_effect_param = match *fn_type.kind() {
-        ty::FnDef(def_id, args) => tcx
-            .generics_of(def_id)
-            .host_effect_index
-            .map_or(tcx.consts.true_, |idx| args.const_at(idx)),
-        ty::FnPtr(..) => tcx.consts.true_,
-        _ => unreachable!("only expected FnPtr or FnDef in `confirm_fn_pointer_candidate`"),
-    };
-
-    confirm_callable_candidate(
-        selcx,
-        obligation,
-        sig,
-        util::TupleArgumentsFlag::Yes,
-        host_effect_param,
-    )
-    .with_addl_obligations(nested)
-    .with_addl_obligations(obligations)
+    confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
+        .with_addl_obligations(nested)
+        .with_addl_obligations(obligations)
 }
 
 fn confirm_closure_candidate<'cx, 'tcx>(
@@ -1739,16 +1724,9 @@ fn confirm_closure_candidate<'cx, 'tcx>(
 
     debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate");
 
-    confirm_callable_candidate(
-        selcx,
-        obligation,
-        closure_sig,
-        util::TupleArgumentsFlag::No,
-        // FIXME(effects): This doesn't handle const closures correctly!
-        selcx.tcx().consts.true_,
-    )
-    .with_addl_obligations(nested)
-    .with_addl_obligations(obligations)
+    confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
+        .with_addl_obligations(nested)
+        .with_addl_obligations(obligations)
 }
 
 fn confirm_callable_candidate<'cx, 'tcx>(
@@ -1756,7 +1734,6 @@ fn confirm_callable_candidate<'cx, 'tcx>(
     obligation: &ProjectionTermObligation<'tcx>,
     fn_sig: ty::PolyFnSig<'tcx>,
     flag: util::TupleArgumentsFlag,
-    fn_host_effect: ty::Const<'tcx>,
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
 
@@ -1771,7 +1748,6 @@ fn confirm_callable_candidate<'cx, 'tcx>(
         obligation.predicate.self_ty(),
         fn_sig,
         flag,
-        fn_host_effect,
     )
     .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
         projection_term: ty::AliasTerm::new_from_args(tcx, fn_once_output_def_id, trait_ref.args),
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 18412b844ff..01e6516302c 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -340,7 +340,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
             self.infcx,
             &mut self.universes,
             constant,
-            |constant| constant.normalize(self.infcx.tcx, self.param_env),
+            |constant| constant.normalize_internal(self.infcx.tcx, self.param_env),
         );
         debug!(?constant, ?self.param_env);
         constant.try_super_fold_with(self)
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 aa313a526c1..ac38c9e24a2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -543,23 +543,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // Provide an impl, but only for suitable `fn` pointers.
             ty::FnPtr(sig_tys, hdr) => {
                 if sig_tys.with(hdr).is_fn_trait_compatible() {
-                    candidates
-                        .vec
-                        .push(FnPointerCandidate { fn_host_effect: self.tcx().consts.true_ });
+                    candidates.vec.push(FnPointerCandidate);
                 }
             }
             // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
-            ty::FnDef(def_id, args) => {
+            ty::FnDef(def_id, _args) => {
                 let tcx = self.tcx();
                 if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
                     && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
                 {
-                    candidates.vec.push(FnPointerCandidate {
-                        fn_host_effect: tcx
-                            .generics_of(def_id)
-                            .host_effect_index
-                            .map_or(tcx.consts.true_, |idx| args.const_at(idx)),
-                    });
+                    candidates.vec.push(FnPointerCandidate);
                 }
             }
             _ => {}
@@ -1170,103 +1163,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn assemble_const_destruct_candidates(
         &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
+        _obligation: &PolyTraitObligation<'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
     ) {
-        // If the predicate is `~const Destruct` in a non-const environment, we don't actually need
-        // to check anything. We'll short-circuit checking any obligations in confirmation, too.
-        let Some(host_effect_index) =
-            self.tcx().generics_of(obligation.predicate.def_id()).host_effect_index
-        else {
-            candidates.vec.push(BuiltinCandidate { has_nested: false });
-            return;
-        };
-        // If the obligation has `host = true`, then the obligation is non-const and it's always
-        // trivially implemented.
-        if obligation.predicate.skip_binder().trait_ref.args.const_at(host_effect_index)
-            == self.tcx().consts.true_
-        {
-            candidates.vec.push(BuiltinCandidate { has_nested: false });
-            return;
-        }
-
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
-        match self_ty.kind() {
-            ty::Alias(..)
-            | ty::Dynamic(..)
-            | ty::Error(_)
-            | ty::Bound(..)
-            | ty::Param(_)
-            | ty::Placeholder(_) => {
-                // We don't know if these are `~const Destruct`, at least
-                // not structurally... so don't push a candidate.
-            }
-
-            ty::Bool
-            | ty::Char
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Infer(ty::IntVar(_))
-            | ty::Infer(ty::FloatVar(_))
-            | ty::Str
-            | ty::RawPtr(_, _)
-            | ty::Ref(..)
-            | ty::FnDef(..)
-            | ty::FnPtr(..)
-            | ty::Never
-            | ty::Foreign(_)
-            | ty::Array(..)
-            | ty::Pat(..)
-            | ty::Slice(_)
-            | ty::Closure(..)
-            | ty::CoroutineClosure(..)
-            | ty::Coroutine(..)
-            | ty::Tuple(_)
-            | ty::CoroutineWitness(..) => {
-                // These are built-in, and cannot have a custom `impl const Destruct`.
-                candidates.vec.push(ConstDestructCandidate(None));
-            }
-
-            ty::Adt(..) => {
-                let mut relevant_impl = None;
-                self.tcx().for_each_relevant_impl(
-                    self.tcx().require_lang_item(LangItem::Drop, None),
-                    obligation.predicate.skip_binder().trait_ref.self_ty(),
-                    |impl_def_id| {
-                        if let Some(old_impl_def_id) = relevant_impl {
-                            self.tcx()
-                                .dcx()
-                                .struct_span_err(
-                                    self.tcx().def_span(impl_def_id),
-                                    "multiple drop impls found",
-                                )
-                                .with_span_note(
-                                    self.tcx().def_span(old_impl_def_id),
-                                    "other impl here",
-                                )
-                                .delay_as_bug();
-                        }
-
-                        relevant_impl = Some(impl_def_id);
-                    },
-                );
-
-                if let Some(impl_def_id) = relevant_impl {
-                    // Check that `impl Drop` is actually const, if there is a custom impl
-                    if self.tcx().constness(impl_def_id) == hir::Constness::Const {
-                        candidates.vec.push(ConstDestructCandidate(Some(impl_def_id)));
-                    }
-                } else {
-                    // Otherwise check the ADT like a built-in type (structurally)
-                    candidates.vec.push(ConstDestructCandidate(None));
-                }
-            }
-
-            ty::Infer(_) => {
-                candidates.ambiguous = true;
-            }
-        }
+        // FIXME(effects): Destruct is not const yet, and it is implemented
+        // by all types today in non-const setting.
+        candidates.vec.push(BuiltinCandidate { has_nested: false });
     }
 
     fn assemble_candidate_for_tuple(
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 0ba3b4e6e55..9a49fd7e77e 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -28,9 +28,9 @@ use super::{BuiltinImplConditions, PredicateObligations, SelectionContext};
 use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
 use crate::traits::util::{self, closure_trait_ref_and_return_type};
 use crate::traits::{
-    ImplDerivedCause, ImplSource, ImplSourceUserDefinedData, Normalized, Obligation,
-    ObligationCause, PolyTraitObligation, PredicateObligation, Selection, SelectionError,
-    SignatureMismatch, TraitDynIncompatible, TraitObligation, Unimplemented,
+    ImplSource, ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause,
+    PolyTraitObligation, PredicateObligation, Selection, SelectionError, SignatureMismatch,
+    TraitDynIncompatible, TraitObligation, Unimplemented,
 };
 
 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
@@ -109,8 +109,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator)
             }
 
-            FnPointerCandidate { fn_host_effect } => {
-                let data = self.confirm_fn_pointer_candidate(obligation, fn_host_effect)?;
+            FnPointerCandidate => {
+                let data = self.confirm_fn_pointer_candidate(obligation)?;
                 ImplSource::Builtin(BuiltinImplSource::Misc, data)
             }
 
@@ -131,11 +131,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             TraitUpcastingUnsizeCandidate(idx) => {
                 self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?
             }
-
-            ConstDestructCandidate(def_id) => {
-                let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
-                ImplSource::Builtin(BuiltinImplSource::Misc, data)
-            }
         };
 
         // The obligations returned by confirmation are recursively evaluated
@@ -405,11 +400,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let predicate = obligation.predicate.skip_binder();
 
-        let Some(assume) = rustc_transmute::Assume::from_const(
-            self.infcx.tcx,
-            obligation.param_env,
-            predicate.trait_ref.args.const_at(2),
-        ) else {
+        let mut assume = predicate.trait_ref.args.const_at(2);
+        // FIXME(min_generic_const_exprs): We should shallowly normalize this.
+        if self.tcx().features().generic_const_exprs {
+            assume = assume.normalize_internal(self.tcx(), obligation.param_env);
+        }
+        let Some(assume) =
+            rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, assume)
+        else {
             return Err(Unimplemented);
         };
 
@@ -708,7 +706,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn confirm_fn_pointer_candidate(
         &mut self,
         obligation: &PolyTraitObligation<'tcx>,
-        fn_host_effect: ty::Const<'tcx>,
     ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
         debug!(?obligation, "confirm_fn_pointer_candidate");
         let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
@@ -722,7 +719,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             self_ty,
             sig,
             util::TupleArgumentsFlag::Yes,
-            fn_host_effect,
         )
         .map_bound(|(trait_ref, _)| trait_ref);
 
@@ -904,11 +900,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let self_ty: Ty<'_> = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
 
         let trait_ref = match *self_ty.kind() {
-            ty::Closure(..) => self.closure_trait_ref_unnormalized(
-                self_ty,
-                obligation.predicate.def_id(),
-                self.tcx().consts.true_,
-            ),
+            ty::Closure(..) => {
+                self.closure_trait_ref_unnormalized(self_ty, obligation.predicate.def_id())
+            }
             ty::CoroutineClosure(_, args) => {
                 args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
                     ty::TraitRef::new(self.tcx(), obligation.predicate.def_id(), [
@@ -1341,170 +1335,4 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             _ => bug!("source: {source}, target: {target}"),
         })
     }
-
-    fn confirm_const_destruct_candidate(
-        &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
-        impl_def_id: Option<DefId>,
-    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
-        let Some(host_effect_index) =
-            self.tcx().generics_of(obligation.predicate.def_id()).host_effect_index
-        else {
-            bug!()
-        };
-        let host_effect_param: ty::GenericArg<'tcx> =
-            obligation.predicate.skip_binder().trait_ref.args.const_at(host_effect_index).into();
-
-        let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None);
-
-        let tcx = self.tcx();
-        let self_ty = obligation.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty));
-
-        let mut nested = PredicateObligations::new();
-        let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
-
-        // If we have a custom `impl const Drop`, then
-        // first check it like a regular impl candidate.
-        // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand.
-        if let Some(impl_def_id) = impl_def_id {
-            let mut new_obligation = obligation.clone();
-            new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| {
-                trait_pred.trait_ref.def_id = drop_trait;
-                trait_pred
-            });
-            let args = self.rematch_impl(impl_def_id, &new_obligation);
-            debug!(?args, "impl args");
-
-            let cause = obligation.derived_cause(|derived| {
-                ObligationCauseCode::ImplDerived(Box::new(ImplDerivedCause {
-                    derived,
-                    impl_or_alias_def_id: impl_def_id,
-                    impl_def_predicate_index: None,
-                    span: obligation.cause.span,
-                }))
-            });
-            let obligations = ensure_sufficient_stack(|| {
-                self.vtable_impl(
-                    impl_def_id,
-                    args,
-                    &cause,
-                    new_obligation.recursion_depth + 1,
-                    new_obligation.param_env,
-                    obligation.predicate,
-                )
-            });
-            nested.extend(obligations.nested);
-        }
-
-        // We want to confirm the ADT's fields if we have an ADT
-        let mut stack = match *self_ty.skip_binder().kind() {
-            ty::Adt(def, args) => def.all_fields().map(|f| f.ty(tcx, args)).collect(),
-            _ => vec![self_ty.skip_binder()],
-        };
-
-        while let Some(nested_ty) = stack.pop() {
-            match *nested_ty.kind() {
-                // We know these types are trivially drop
-                ty::Bool
-                | ty::Char
-                | ty::Int(_)
-                | ty::Uint(_)
-                | ty::Float(_)
-                | ty::Infer(ty::IntVar(_))
-                | ty::Infer(ty::FloatVar(_))
-                | ty::Str
-                | ty::RawPtr(_, _)
-                | ty::Ref(..)
-                | ty::FnDef(..)
-                | ty::FnPtr(..)
-                | ty::Never
-                | ty::Foreign(_) => {}
-
-                // `ManuallyDrop` is trivially drop
-                ty::Adt(def, _) if def.is_manually_drop() => {}
-
-                // These types are built-in, so we can fast-track by registering
-                // nested predicates for their constituent type(s)
-                ty::Array(ty, _) | ty::Slice(ty) | ty::Pat(ty, _) => {
-                    stack.push(ty);
-                }
-                ty::Tuple(tys) => {
-                    stack.extend(tys.iter());
-                }
-                ty::Closure(_, args) => {
-                    stack.push(args.as_closure().tupled_upvars_ty());
-                }
-                ty::Coroutine(_, args) => {
-                    let coroutine = args.as_coroutine();
-                    stack.extend([coroutine.tupled_upvars_ty(), coroutine.witness()]);
-                }
-                ty::CoroutineWitness(def_id, args) => {
-                    let tcx = self.tcx();
-                    stack.extend(tcx.bound_coroutine_hidden_types(def_id).map(|bty| {
-                        self.infcx.enter_forall_and_leak_universe(bty.instantiate(tcx, args))
-                    }))
-                }
-
-                // If we have a projection type, make sure to normalize it so we replace it
-                // with a fresh infer variable
-                ty::Alias(ty::Projection | ty::Inherent, ..) => {
-                    let predicate = normalize_with_depth_to(
-                        self,
-                        obligation.param_env,
-                        cause.clone(),
-                        obligation.recursion_depth + 1,
-                        self_ty.rebind(ty::TraitPredicate {
-                            trait_ref: ty::TraitRef::new(
-                                self.tcx(),
-                                self.tcx().require_lang_item(LangItem::Destruct, Some(cause.span)),
-                                [nested_ty.into(), host_effect_param],
-                            ),
-                            polarity: ty::PredicatePolarity::Positive,
-                        }),
-                        &mut nested,
-                    );
-
-                    nested.push(Obligation::with_depth(
-                        tcx,
-                        cause.clone(),
-                        obligation.recursion_depth + 1,
-                        obligation.param_env,
-                        predicate,
-                    ));
-                }
-
-                // If we have any other type (e.g. an ADT), just register a nested obligation
-                // since it's either not `const Drop` (and we raise an error during selection),
-                // or it's an ADT (and we need to check for a custom impl during selection)
-                ty::Error(_)
-                | ty::Dynamic(..)
-                | ty::CoroutineClosure(..)
-                | ty::Param(_)
-                | ty::Bound(..)
-                | ty::Adt(..)
-                | ty::Alias(ty::Opaque | ty::Weak, _)
-                | ty::Infer(_)
-                | ty::Placeholder(_) => {
-                    let predicate = self_ty.rebind(ty::TraitPredicate {
-                        trait_ref: ty::TraitRef::new(
-                            self.tcx(),
-                            self.tcx().require_lang_item(LangItem::Destruct, Some(cause.span)),
-                            [nested_ty.into(), host_effect_param],
-                        ),
-                        polarity: ty::PredicatePolarity::Positive,
-                    });
-
-                    nested.push(Obligation::with_depth(
-                        tcx,
-                        cause.clone(),
-                        obligation.recursion_depth + 1,
-                        obligation.param_env,
-                        predicate,
-                    ));
-                }
-            }
-        }
-
-        Ok(nested)
-    }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 621babe9104..4757430a21c 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1831,12 +1831,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             (TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => DropVictim::No,
 
             // (*)
-            (BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => {
-                DropVictim::Yes
-            }
-            (_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => {
-                DropVictim::No
-            }
+            (BuiltinCandidate { has_nested: false }, _) => DropVictim::Yes,
+            (_, BuiltinCandidate { has_nested: false }) => DropVictim::No,
 
             (ParamCandidate(other), ParamCandidate(victim)) => {
                 let same_except_bound_vars = other.skip_binder().trait_ref
@@ -1855,11 +1851,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 }
             }
 
-            // Drop otherwise equivalent non-const fn pointer candidates
-            (FnPointerCandidate { .. }, FnPointerCandidate { fn_host_effect }) => {
-                DropVictim::drop_if(*fn_host_effect == self.tcx().consts.true_)
-            }
-
             (
                 ParamCandidate(other_cand),
                 ImplCandidate(..)
@@ -2766,7 +2757,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         &mut self,
         self_ty: Ty<'tcx>,
         fn_trait_def_id: DefId,
-        fn_host_effect: ty::Const<'tcx>,
     ) -> ty::PolyTraitRef<'tcx> {
         let ty::Closure(_, args) = *self_ty.kind() else {
             bug!("expected closure, found {self_ty}");
@@ -2779,7 +2769,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             self_ty,
             closure_sig,
             util::TupleArgumentsFlag::No,
-            fn_host_effect,
         )
         .map_bound(|(trait_ref, _)| trait_ref)
     }
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index 3814f8112e9..f8d98eb856e 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -82,6 +82,8 @@ impl<'tcx> At<'_, 'tcx> {
             }
 
             Ok(self.infcx.resolve_vars_if_possible(new_infer_ct))
+        } else if self.infcx.tcx.features().generic_const_exprs {
+            Ok(ct.normalize_internal(self.infcx.tcx, self.param_env))
         } else {
             Ok(self.normalize(ct).into_value_registering_obligations(self.infcx, fulfill_cx))
         }
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index aed2e3d61aa..b7a2f20b769 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -215,22 +215,13 @@ pub(crate) fn closure_trait_ref_and_return_type<'tcx>(
     self_ty: Ty<'tcx>,
     sig: ty::PolyFnSig<'tcx>,
     tuple_arguments: TupleArgumentsFlag,
-    fn_host_effect: ty::Const<'tcx>,
 ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> {
     assert!(!self_ty.has_escaping_bound_vars());
     let arguments_tuple = match tuple_arguments {
         TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
         TupleArgumentsFlag::Yes => Ty::new_tup(tcx, sig.skip_binder().inputs()),
     };
-    let trait_ref = if tcx.has_host_param(fn_trait_def_id) {
-        ty::TraitRef::new(tcx, fn_trait_def_id, [
-            ty::GenericArg::from(self_ty),
-            ty::GenericArg::from(arguments_tuple),
-            ty::GenericArg::from(fn_host_effect),
-        ])
-    } else {
-        ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty, arguments_tuple])
-    };
+    let trait_ref = ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty, arguments_tuple]);
     sig.map_bound(|sig| (trait_ref, sig.output()))
 }
 
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index c1d0b704ab2..f7651e49cdd 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -85,7 +85,6 @@ mod rustc {
     use rustc_macros::TypeVisitable;
     use rustc_middle::traits::ObligationCause;
     use rustc_middle::ty::{Const, ParamEnv, Ty, TyCtxt, ValTree};
-    use rustc_span::DUMMY_SP;
 
     use super::*;
 
@@ -134,13 +133,8 @@ mod rustc {
             use rustc_middle::ty::ScalarInt;
             use rustc_span::symbol::sym;
 
-            let Ok((ty, cv)) = c.eval(tcx, param_env, DUMMY_SP) else {
-                return Some(Self {
-                    alignment: true,
-                    lifetimes: true,
-                    safety: true,
-                    validity: true,
-                });
+            let Some((cv, ty)) = c.try_to_valtree() else {
+                return None;
             };
 
             let adt_def = ty.ty_adt_def()?;
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index afdfa2e80c1..e755e90aa65 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -30,7 +30,8 @@ use {rustc_abi as abi, rustc_hir as hir};
 use crate::errors::{
     MultipleArrayFieldsSimdType, NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType,
 };
-use crate::layout_sanity_check::sanity_check_layout;
+
+mod invariant;
 
 pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { layout_of, ..*providers };
@@ -79,7 +80,7 @@ fn layout_of<'tcx>(
         record_layout_for_printing(&cx, layout);
     }
 
-    sanity_check_layout(&cx, &layout);
+    invariant::partially_check_layout(&cx, &layout);
 
     Ok(layout)
 }
@@ -115,6 +116,11 @@ fn map_error<'tcx>(
             cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
             LayoutError::Unknown(ty)
         }
+        LayoutCalculatorError::ReprConflict => {
+            // packed enums are the only known trigger of this, but others might arise
+            cx.tcx().dcx().delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
+            LayoutError::Unknown(ty)
+        }
     };
     error(cx, err)
 }
@@ -170,12 +176,12 @@ fn layout_of_uncached<'tcx>(
                     if let Abi::Scalar(scalar) | Abi::ScalarPair(scalar, _) = &mut layout.abi {
                         if let Some(start) = start {
                             scalar.valid_range_mut().start = start
-                                .try_eval_bits(tcx, param_env)
+                                .try_to_bits(tcx, param_env)
                                 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
                         }
                         if let Some(end) = end {
                             let mut end = end
-                                .try_eval_bits(tcx, param_env)
+                                .try_to_bits(tcx, param_env)
                                 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
                             if !include_end {
                                 end = end.wrapping_sub(1);
@@ -315,7 +321,7 @@ fn layout_of_uncached<'tcx>(
             }
 
             let count = count
-                .try_eval_target_usize(tcx, param_env)
+                .try_to_target_usize(tcx)
                 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
             let element = cx.layout_of(element)?;
             let size = element
diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs
index be0a7c5ee89..6cf114b74c1 100644
--- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs
+++ b/compiler/rustc_ty_utils/src/layout/invariant.rs
@@ -5,7 +5,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, TyAndLayout};
 use rustc_target::abi::*;
 
 /// Enforce some basic invariants on layouts.
-pub(super) fn sanity_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) {
+pub(super) fn partially_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) {
     let tcx = cx.tcx();
 
     // Type-level uninhabitedness should always imply ABI uninhabitedness.
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index dc5303317a8..8be1611bb9a 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -29,7 +29,6 @@ mod errors;
 mod implied_bounds;
 mod instance;
 mod layout;
-mod layout_sanity_check;
 mod needs_drop;
 mod opaque_types;
 mod representability;
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index f06017d7e5c..4184e9e313f 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -15,9 +15,7 @@ use crate::solve::{
     CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult, SolverMode,
 };
 use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
-use crate::{
-    search_graph, {self as ty},
-};
+use crate::{self as ty, search_graph};
 
 pub trait Interner:
     Sized
@@ -173,6 +171,10 @@ pub trait Interner:
 
     fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
 
+    /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
+    /// are compatible with the `DefId`.
+    fn debug_assert_existential_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
+
     fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
     where
         I: Iterator<Item = T>,
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index 8146181df6c..e8ce39be3e5 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -289,9 +289,26 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
 pub struct ExistentialTraitRef<I: Interner> {
     pub def_id: I::DefId,
     pub args: I::GenericArgs,
+    /// This field exists to prevent the creation of `ExistentialTraitRef` without
+    /// calling [`ExistentialTraitRef::new_from_args`].
+    _use_existential_trait_ref_new_instead: (),
 }
 
 impl<I: Interner> ExistentialTraitRef<I> {
+    pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
+        interner.debug_assert_existential_args_compatible(trait_def_id, args);
+        Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
+    }
+
+    pub fn new(
+        interner: I,
+        trait_def_id: I::DefId,
+        args: impl IntoIterator<Item: Into<I::GenericArg>>,
+    ) -> Self {
+        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
+        Self::new_from_args(interner, trait_def_id, args)
+    }
+
     pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
         // Assert there is a Self.
         trait_ref.args.type_at(0);
@@ -299,6 +316,7 @@ impl<I: Interner> ExistentialTraitRef<I> {
         ExistentialTraitRef {
             def_id: trait_ref.def_id,
             args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
+            _use_existential_trait_ref_new_instead: (),
         }
     }
 
@@ -336,9 +354,33 @@ pub struct ExistentialProjection<I: Interner> {
     pub def_id: I::DefId,
     pub args: I::GenericArgs,
     pub term: I::Term,
+
+    /// This field exists to prevent the creation of `ExistentialProjection`
+    /// without using [`ExistentialProjection::new_from_args`].
+    use_existential_projection_new_instead: (),
 }
 
 impl<I: Interner> ExistentialProjection<I> {
+    pub fn new_from_args(
+        interner: I,
+        def_id: I::DefId,
+        args: I::GenericArgs,
+        term: I::Term,
+    ) -> ExistentialProjection<I> {
+        interner.debug_assert_existential_args_compatible(def_id, args);
+        Self { def_id, args, term, use_existential_projection_new_instead: () }
+    }
+
+    pub fn new(
+        interner: I,
+        def_id: I::DefId,
+        args: impl IntoIterator<Item: Into<I::GenericArg>>,
+        term: I::Term,
+    ) -> ExistentialProjection<I> {
+        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
+        Self::new_from_args(interner, def_id, args, term)
+    }
+
     /// Extracts the underlying existential trait reference from this projection.
     /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
     /// then this function would return an `exists T. T: Iterator` existential trait
@@ -347,7 +389,7 @@ impl<I: Interner> ExistentialProjection<I> {
         let def_id = interner.parent(self.def_id);
         let args_count = interner.generics_of(def_id).count() - 1;
         let args = interner.mk_args(&self.args.as_slice()[..args_count]);
-        ExistentialTraitRef { def_id, args }
+        ExistentialTraitRef { def_id, args, _use_existential_trait_ref_new_instead: () }
     }
 
     pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
@@ -372,6 +414,7 @@ impl<I: Interner> ExistentialProjection<I> {
             def_id: projection_predicate.projection_term.def_id,
             args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
             term: projection_predicate.term,
+            use_existential_projection_new_instead: (),
         }
     }
 }
@@ -726,9 +769,9 @@ pub struct CoercePredicate<I: Interner> {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 #[cfg_attr(feature = "nightly", derive(HashStable_NoContext, TyEncodable, TyDecodable))]
 pub enum BoundConstness {
-    /// `Type: Trait`
-    NotConst,
     /// `Type: const Trait`
+    ///
+    /// A bound is required to be unconditionally const, even in a runtime function.
     Const,
     /// `Type: ~const Trait`
     ///
@@ -739,7 +782,6 @@ pub enum BoundConstness {
 impl BoundConstness {
     pub fn as_str(self) -> &'static str {
         match self {
-            Self::NotConst => "",
             Self::Const => "const",
             Self::ConstIfConst => "~const",
         }
@@ -749,7 +791,6 @@ impl BoundConstness {
 impl fmt::Display for BoundConstness {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            Self::NotConst => f.write_str("normal"),
             Self::Const => f.write_str("const"),
             Self::ConstIfConst => f.write_str("~const"),
         }
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index e1f3e493e36..a0b93064694 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -333,7 +333,7 @@ impl<I: Interner> Relate<I> for ty::ExistentialProjection<I> {
                 a.args,
                 b.args,
             )?;
-            Ok(ty::ExistentialProjection { def_id: a.def_id, args, term })
+            Ok(ty::ExistentialProjection::new_from_args(relation.cx(), a.def_id, args, term))
         }
     }
 }
@@ -373,7 +373,7 @@ impl<I: Interner> Relate<I> for ty::ExistentialTraitRef<I> {
             }))
         } else {
             let args = relate_args_invariantly(relation, a.args, b.args)?;
-            Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
+            Ok(ty::ExistentialTraitRef::new_from_args(relation.cx(), a.def_id, args))
         }
     }
 }
diff --git a/library/alloc/benches/lib.rs b/library/alloc/benches/lib.rs
index ae9608ec7bd..c1907361f93 100644
--- a/library/alloc/benches/lib.rs
+++ b/library/alloc/benches/lib.rs
@@ -4,7 +4,8 @@
 #![feature(iter_next_chunk)]
 #![feature(repr_simd)]
 #![feature(slice_partition_dedup)]
-#![feature(strict_provenance)]
+#![cfg_attr(bootstrap, feature(strict_provenance))]
+#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 #![feature(test)]
 #![deny(fuzzy_provenance_casts)]
 
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index ae9b3739858..50a5f3c5b1e 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -147,7 +147,6 @@
 #![feature(slice_range)]
 #![feature(std_internals)]
 #![feature(str_internals)]
-#![feature(strict_provenance)]
 #![feature(trusted_fused)]
 #![feature(trusted_len)]
 #![feature(trusted_random_access)]
@@ -162,6 +161,8 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(strict_provenance))]
+#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 #![cfg_attr(not(test), feature(coroutine_trait))]
 #![cfg_attr(test, feature(panic_update_hook))]
 #![cfg_attr(test, feature(test))]
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 301126b5d4d..699a8e6776e 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -32,7 +32,8 @@
 #![feature(panic_update_hook)]
 #![feature(pointer_is_aligned_to)]
 #![feature(thin_box)]
-#![feature(strict_provenance)]
+#![cfg_attr(bootstrap, feature(strict_provenance))]
+#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 #![feature(drain_keep_rest)]
 #![feature(local_waker)]
 #![feature(vec_pop_if)]
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index eee4a9e4c6c..af6f0da88de 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -94,11 +94,11 @@ pub struct Argument<'a> {
 }
 
 #[rustc_diagnostic_item = "ArgumentMethods"]
-impl<'a> Argument<'a> {
+impl Argument<'_> {
     #[inline(always)]
-    fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'b> {
+    fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> {
         Argument {
-            // INVARIANT: this creates an `ArgumentType<'b>` from a `&'b T` and
+            // INVARIANT: this creates an `ArgumentType<'a>` from a `&'a T` and
             // a `fn(&T, ...)`, so the invariant is maintained.
             ty: ArgumentType::Placeholder {
                 value: NonNull::from(x).cast(),
@@ -110,43 +110,43 @@ impl<'a> Argument<'a> {
     }
 
     #[inline(always)]
-    pub fn new_display<'b, T: Display>(x: &'b T) -> Argument<'b> {
+    pub fn new_display<T: Display>(x: &T) -> Argument<'_> {
         Self::new(x, Display::fmt)
     }
     #[inline(always)]
-    pub fn new_debug<'b, T: Debug>(x: &'b T) -> Argument<'b> {
+    pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
         Self::new(x, Debug::fmt)
     }
     #[inline(always)]
-    pub fn new_debug_noop<'b, T: Debug>(x: &'b T) -> Argument<'b> {
+    pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
         Self::new(x, |_, _| Ok(()))
     }
     #[inline(always)]
-    pub fn new_octal<'b, T: Octal>(x: &'b T) -> Argument<'b> {
+    pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
         Self::new(x, Octal::fmt)
     }
     #[inline(always)]
-    pub fn new_lower_hex<'b, T: LowerHex>(x: &'b T) -> Argument<'b> {
+    pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
         Self::new(x, LowerHex::fmt)
     }
     #[inline(always)]
-    pub fn new_upper_hex<'b, T: UpperHex>(x: &'b T) -> Argument<'b> {
+    pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
         Self::new(x, UpperHex::fmt)
     }
     #[inline(always)]
-    pub fn new_pointer<'b, T: Pointer>(x: &'b T) -> Argument<'b> {
+    pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
         Self::new(x, Pointer::fmt)
     }
     #[inline(always)]
-    pub fn new_binary<'b, T: Binary>(x: &'b T) -> Argument<'b> {
+    pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
         Self::new(x, Binary::fmt)
     }
     #[inline(always)]
-    pub fn new_lower_exp<'b, T: LowerExp>(x: &'b T) -> Argument<'b> {
+    pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
         Self::new(x, LowerExp::fmt)
     }
     #[inline(always)]
-    pub fn new_upper_exp<'b, T: UpperExp>(x: &'b T) -> Argument<'b> {
+    pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
         Self::new(x, UpperExp::fmt)
     }
     #[inline(always)]
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 38e858626b9..97e727633c5 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2794,7 +2794,6 @@ where
 /// #![feature(is_val_statically_known)]
 /// #![feature(core_intrinsics)]
 /// # #![allow(internal_features)]
-/// #![feature(strict_provenance)]
 /// use std::intrinsics::is_val_statically_known;
 ///
 /// fn foo(x: &i32) -> bool {
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index ad034d3e576..16877566765 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -163,7 +163,6 @@
 #![feature(str_internals)]
 #![feature(str_split_inclusive_remainder)]
 #![feature(str_split_remainder)]
-#![feature(strict_provenance)]
 #![feature(ub_checks)]
 #![feature(unchecked_neg)]
 #![feature(unchecked_shifts)]
@@ -174,6 +173,8 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(strict_provenance))]
+#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 22fd47b0596..95fa6c9c950 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1784,9 +1784,11 @@ mod prim_ref {}
 ///   unique field that doesn't have size 0 and alignment 1 (if there is such a field).
 /// - `i32` is ABI-compatible with `NonZero<i32>`, and similar for all other integer types.
 /// - If `T` is guaranteed to be subject to the [null pointer
-///   optimization](option/index.html#representation), then `T` and `Option<T>` are ABI-compatible.
-///   Furthermore, if `U` satisfies the requirements [outlined here](result/index.html#representation),
-///   then `T` and `Result<T, U>` and `Result<U, T>` are all ABI-compatible.
+///   optimization](option/index.html#representation), and `E` is an enum satisfying the following
+///   requirements, then `T` and `E` are ABI-compatible. Such an enum `E` is called "option-like".
+///   - The enum `E` has exactly two variants.
+///   - One variant has exactly one field, of type `T`.
+///   - All fields of the other variant are zero-sized with 1-byte alignment.
 ///
 /// Furthermore, ABI compatibility satisfies the following general properties:
 ///
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 72f4bc2c9da..9ee0fb5948e 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -137,10 +137,11 @@ impl<T: ?Sized> *const T {
 
     /// Gets the "address" portion of the pointer.
     ///
-    /// This is similar to `self as usize`, which semantically discards *provenance* and
-    /// *address-space* information. However, unlike `self as usize`, casting the returned address
-    /// back to a pointer yields a [pointer without provenance][without_provenance], which is undefined behavior to dereference. To
-    /// properly restore the lost information and obtain a dereferenceable pointer, use
+    /// This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
+    /// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
+    /// casting the returned address back to a pointer yields a [pointer without
+    /// provenance][without_provenance], which is undefined behavior to dereference. To properly
+    /// restore the lost information and obtain a dereferenceable pointer, use
     /// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
     ///
     /// If using those APIs is not possible because there is no way to preserve a pointer with the
@@ -155,90 +156,81 @@ impl<T: ?Sized> *const T {
     /// perform a change of representation to produce a value containing only the address
     /// portion of the pointer. What that means is up to the platform to define.
     ///
-    /// This API and its claimed semantics are part of the Strict Provenance experiment, and as such
-    /// might change in the future (including possibly weakening this so it becomes wholly
-    /// equivalent to `self as usize`). See the [module documentation][crate::ptr] for details.
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline(always)]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn addr(self) -> usize {
-        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
+        // A pointer-to-integer transmute currently has exactly the right semantics: it returns the
+        // address without exposing the provenance. Note that this is *not* a stable guarantee about
+        // transmute semantics, it relies on sysroot crates having special status.
         // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
         // provenance).
         unsafe { mem::transmute(self.cast::<()>()) }
     }
 
-    /// Exposes the "provenance" part of the pointer for future use in
-    /// [`with_exposed_provenance`][] and returns the "address" portion.
+    /// Exposes the ["provenance"][crate::ptr#provenance] part of the pointer for future use in
+    /// [`with_exposed_provenance`] and returns the "address" portion.
     ///
-    /// This is equivalent to `self as usize`, which semantically discards *provenance* and
-    /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
-    /// side-effect of marking the provenance as 'exposed', so on platforms that support it you can
-    /// later call [`with_exposed_provenance`][] to reconstitute the original pointer including its
-    /// provenance. (Reconstructing address space information, if required, is your responsibility.)
+    /// This is equivalent to `self as usize`, which semantically discards provenance information.
+    /// Furthermore, this (like the `as` cast) has the implicit side-effect of marking the
+    /// provenance as 'exposed', so on platforms that support it you can later call
+    /// [`with_exposed_provenance`] to reconstitute the original pointer including its provenance.
     ///
-    /// Using this method means that code is *not* following [Strict
-    /// Provenance][super#strict-provenance] rules. Supporting
-    /// [`with_exposed_provenance`][] complicates specification and reasoning and may not be supported by
-    /// tools that help you to stay conformant with the Rust memory model, so it is recommended to
-    /// use [`addr`][pointer::addr] wherever possible.
+    /// Due to its inherent ambiguity, [`with_exposed_provenance`] may not be supported by tools
+    /// that help you to stay conformant with the Rust memory model. It is recommended to use
+    /// [Strict Provenance][crate::ptr#strict-provenance] APIs such as [`with_addr`][pointer::with_addr]
+    /// wherever possible, in which case [`addr`][pointer::addr] should be used instead of `expose_provenance`.
     ///
     /// On most platforms this will produce a value with the same bytes as the original pointer,
     /// because all the bytes are dedicated to describing the address. Platforms which need to store
     /// additional information in the pointer may not support this operation, since the 'expose'
-    /// side-effect which is required for [`with_exposed_provenance`][] to work is typically not
+    /// side-effect which is required for [`with_exposed_provenance`] to work is typically not
     /// available.
     ///
-    /// It is unclear whether this method can be given a satisfying unambiguous specification. This
-    /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].
+    /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
     ///
     /// [`with_exposed_provenance`]: with_exposed_provenance
     #[must_use]
     #[inline(always)]
-    #[unstable(feature = "exposed_provenance", issue = "95228")]
+    #[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn expose_provenance(self) -> usize {
-        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         self.cast::<()>() as usize
     }
 
-    /// Creates a new pointer with the given address.
+    /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
+    /// `self`.
     ///
-    /// This performs the same operation as an `addr as ptr` cast, but copies
-    /// the *address-space* and *provenance* of `self` to the new pointer.
-    /// This allows us to dynamically preserve and propagate this important
-    /// information in a way that is otherwise impossible with a unary cast.
+    /// This is similar to a `addr as *const T` cast, but copies
+    /// the *provenance* of `self` to the new pointer.
+    /// This avoids the inherent ambiguity of the unary cast.
     ///
     /// This is equivalent to using [`wrapping_offset`][pointer::wrapping_offset] to offset
     /// `self` to the given address, and therefore has all the same capabilities and restrictions.
     ///
-    /// This API and its claimed semantics are part of the Strict Provenance experiment,
-    /// see the [module documentation][crate::ptr] for details.
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn with_addr(self, addr: usize) -> Self {
-        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
-        //
-        // In the mean-time, this operation is defined to be "as if" it was
-        // a wrapping_offset, so we can emulate it as such. This should properly
-        // restore pointer provenance even under today's compiler.
+        // This should probably be an intrinsic to avoid doing any sort of arithmetic, but
+        // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's
+        // provenance.
         let self_addr = self.addr() as isize;
         let dest_addr = addr as isize;
         let offset = dest_addr.wrapping_sub(self_addr);
-
-        // This is the canonical desugaring of this operation
         self.wrapping_byte_offset(offset)
     }
 
-    /// Creates a new pointer by mapping `self`'s address to a new one.
+    /// Creates a new pointer by mapping `self`'s address to a new one, preserving the
+    /// [provenance][crate::ptr#provenance] of `self`.
     ///
     /// This is a convenience for [`with_addr`][pointer::with_addr], see that method for details.
     ///
-    /// This API and its claimed semantics are part of the Strict Provenance experiment,
-    /// see the [module documentation][crate::ptr] for details.
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self {
         self.with_addr(f(self.addr()))
     }
@@ -379,7 +371,7 @@ impl<T: ?Sized> *const T {
     /// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
     ///   "wrapping around"), must fit in an `isize`.
     ///
-    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
     ///   [allocated object], and the entire memory range between `self` and the result must be in
     ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
     ///   of the address space.
@@ -560,7 +552,7 @@ impl<T: ?Sized> *const T {
     /// ## Examples
     ///
     /// ```
-    /// #![feature(ptr_mask, strict_provenance)]
+    /// #![feature(ptr_mask)]
     /// let v = 17_u32;
     /// let ptr: *const u32 = &v;
     ///
@@ -611,7 +603,7 @@ impl<T: ?Sized> *const T {
     /// * `self` and `origin` must either
     ///
     ///   * point to the same address, or
-    ///   * both be *derived from* a pointer to the same [allocated object], and the memory range between
+    ///   * both be [derived from][crate::ptr#provenance] a pointer to the same [allocated object], and the memory range between
     ///     the two pointers must be in bounds of that object. (See below for an example.)
     ///
     /// * The distance between the pointers, in bytes, must be an exact multiple
@@ -871,7 +863,7 @@ impl<T: ?Sized> *const T {
     /// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
     ///   "wrapping around"), must fit in an `isize`.
     ///
-    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
     ///   [allocated object], and the entire memory range between `self` and the result must be in
     ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
     ///   of the address space.
@@ -978,7 +970,7 @@ impl<T: ?Sized> *const T {
     /// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
     ///   "wrapping around"), must fit in an `isize`.
     ///
-    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
     ///   [allocated object], and the entire memory range between `self` and the result must be in
     ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
     ///   of the address space.
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index f7036f30a99..f769b515877 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -18,10 +18,11 @@
 //! * For operations of [size zero][zst], *every* pointer is valid, including the [null] pointer.
 //!   The following points are only concerned with non-zero-sized accesses.
 //! * A [null] pointer is *never* valid.
-//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer
-//!   be *dereferenceable*: the memory range of the given size starting at the pointer must all be
-//!   within the bounds of a single allocated object. Note that in Rust,
-//!   every (stack-allocated) variable is considered a separate allocated object.
+//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer be
+//!   *dereferenceable*. The [provenance] of the pointer is used to determine which [allocated
+//!   object] it is derived from; a pointer is dereferenceable if the memory range of the given size
+//!   starting at the pointer is entirely contained within the bounds of that allocated object. Note
+//!   that in Rust, every (stack-allocated) variable is considered a separate allocated object.
 //! * All accesses performed by functions in this module are *non-atomic* in the sense
 //!   of [atomic operations] used to synchronize between threads. This means it is
 //!   undefined behavior to perform two concurrent accesses to the same location from different
@@ -130,123 +131,130 @@
 //!
 //! [`null()`]: null
 //!
-//! # Strict Provenance
-//!
-//! **The following text is non-normative, insufficiently formal, and is an extremely strict
-//! interpretation of provenance. It's ok if your code doesn't strictly conform to it.**
-//!
-//! [Strict Provenance][] is an experimental set of APIs that help tools that try
-//! to validate the memory-safety of your program's execution. Notably this includes [Miri][]
-//! and [CHERI][], which can detect when you access out of bounds memory or otherwise violate
-//! Rust's memory model.
-//!
-//! Provenance must exist in some form for any programming
-//! language compiled for modern computer architectures, but specifying a model for provenance
-//! in a way that is useful to both compilers and programmers is an ongoing challenge.
-//! The [Strict Provenance][] experiment seeks to explore the question: *what if we just said you
-//! couldn't do all the nasty operations that make provenance so messy?*
-//!
-//! What APIs would have to be removed? What APIs would have to be added? How much would code
-//! have to change, and is it worse or better now? Would any patterns become truly inexpressible?
-//! Could we carve out special exceptions for those patterns? Should we?
-//!
-//! A secondary goal of this project is to see if we can disambiguate the many functions of
-//! pointer<->integer casts enough for the definition of `usize` to be loosened so that it
-//! isn't *pointer*-sized but address-space/offset/allocation-sized (we'll probably continue
-//! to conflate these notions). This would potentially make it possible to more efficiently
-//! target platforms where pointers are larger than offsets, such as CHERI and maybe some
-//! segmented architectures.
-//!
-//! ## Provenance
-//!
-//! **This section is *non-normative* and is part of the [Strict Provenance][] experiment.**
+//! # Provenance
 //!
 //! Pointers are not *simply* an "integer" or "address". For instance, it's uncontroversial
 //! to say that a Use After Free is clearly Undefined Behaviour, even if you "get lucky"
 //! and the freed memory gets reallocated before your read/write (in fact this is the
 //! worst-case scenario, UAFs would be much less concerning if this didn't happen!).
-//! To rationalize this claim, pointers need to somehow be *more* than just their addresses:
-//! they must have provenance.
+//! As another example, consider that [`wrapping_offset`] is documented to "remember"
+//! the allocated object that the original pointer points to, even if it is offset far
+//! outside the memory range occupied by that allocated object.
+//! To rationalize claims like this, pointers need to somehow be *more* than just their addresses:
+//! they must have **provenance**.
 //!
-//! When an allocation is created, that allocation has a unique Original Pointer. For alloc
-//! APIs this is literally the pointer the call returns, and for local variables and statics,
-//! this is the name of the variable/static. This is mildly overloading the term "pointer"
-//! for the sake of brevity/exposition.
+//! A pointer value in Rust semantically contains the following information:
+//!
+//! * The **address** it points to, which can be represented by a `usize`.
+//! * The **provenance** it has, defining the memory it has permission to access. Provenance can be
+//!   absent, in which case the pointer does not have permission to access any memory.
 //!
-//! The Original Pointer for an allocation is guaranteed to have unique access to the entire
-//! allocation and *only* that allocation. In this sense, an allocation can be thought of
-//! as a "sandbox" that cannot be broken into or out of. *Provenance* is the permission
-//! to access an allocation's sandbox and has both a *spatial* and *temporal* component:
+//! The exact structure of provenance is not yet specified, but the permission defined by a
+//! pointer's provenance have a *spatial* component, a *temporal* component, and a *mutability*
+//! component:
 //!
-//! * Spatial: A range of bytes that the pointer is allowed to access.
-//! * Temporal: The lifetime (of the allocation) that access to these bytes is tied to.
+//! * Spatial: The set of memory addresses that the pointer is allowed to access.
+//! * Temporal: The timespan during which the pointer is allowed to access those memory addresses.
+//! * Mutability: Whether the pointer may only access the memory for reads, or also access it for
+//!   writes. Note that this can interact with the other components, e.g. a pointer might permit
+//!   mutation only for a subset of addresses, or only for a subset of its maximal timespan.
 //!
-//! Spatial provenance makes sure you don't go beyond your sandbox, while temporal provenance
-//! makes sure that you can't "get lucky" after your permission to access some memory
-//! has been revoked (either through deallocations or borrows expiring).
+//! When an [allocated object] is created, it has a unique Original Pointer. For alloc
+//! APIs this is literally the pointer the call returns, and for local variables and statics,
+//! this is the name of the variable/static. (This is mildly overloading the term "pointer"
+//! for the sake of brevity/exposition.)
+//!
+//! The Original Pointer for an allocated object has provenance that constrains the *spatial*
+//! permissions of this pointer to the memory range of the allocation, and the *temporal*
+//! permissions to the lifetime of the allocation. Provenance is implicitly inherited by all
+//! pointers transitively derived from the Original Pointer through operations like [`offset`],
+//! borrowing, and pointer casts. Some operations may *shrink* the permissions of the derived
+//! provenance, limiting how much memory it can access or how long it's valid for (i.e. borrowing a
+//! subfield and subslicing can shrink the spatial component of provenance, and all borrowing can
+//! shrink the temporal component of provenance). However, no operation can ever *grow* the
+//! permissions of the derived provenance: even if you "know" there is a larger allocation, you
+//! can't derive a pointer with a larger provenance. Similarly, you cannot "recombine" two
+//! contiguous provenances back into one (i.e. with a `fn merge(&[T], &[T]) -> &[T]`).
+//!
+//! A reference to a place always has provenance over at least the memory that place occupies.
+//! A reference to a slice always has provenance over at least the range that slice describes.
+//! Whether and when exactly the provenance of a reference gets "shrunk" to *exactly* fit
+//! the memory it points to is not yet determined.
+//!
+//! A *shared* reference only ever has provenance that permits reading from memory,
+//! and never permits writes, except inside [`UnsafeCell`].
+//!
+//! Provenance can affect whether a program has undefined behavior:
+//!
+//! * It is undefined behavior to access memory through a pointer that does not have provenance over
+//!   that memory. Note that a pointer "at the end" of its provenance is not actually outside its
+//!   provenance, it just has 0 bytes it can load/store. Zero-sized accesses do not require any
+//!   provenance since they access an empty range of memory.
+//!
+//! * It is undefined behavior to [`offset`] a pointer across a memory range that is not contained
+//!   in the allocated object it is derived from, or to [`offset_from`] two pointers not derived
+//!   from the same allocated object. Provenance is used to say what exactly "derived from" even
+//!   means: the lineage of a pointer is traced back to the Original Pointer it descends from, and
+//!   that identifies the relevant allocated object. In particular, it's always UB to offset a
+//!   pointer derived from something that is now deallocated, except if the offset is 0.
 //!
-//! Provenance is implicitly shared with all pointers transitively derived from
-//! The Original Pointer through operations like [`offset`], borrowing, and pointer casts.
-//! Some operations may *shrink* the derived provenance, limiting how much memory it can
-//! access or how long it's valid for (i.e. borrowing a subfield and subslicing).
+//! But it *is* still sound to:
 //!
-//! Shrinking provenance cannot be undone: even if you "know" there is a larger allocation, you
-//! can't derive a pointer with a larger provenance. Similarly, you cannot "recombine"
-//! two contiguous provenances back into one (i.e. with a `fn merge(&[T], &[T]) -> &[T]`).
+//! * Create a pointer without provenance from just an address (see [`ptr::dangling`]). Such a
+//!   pointer cannot be used for memory accesses (except for zero-sized accesses). This can still be
+//!   useful for sentinel values like `null` *or* to represent a tagged pointer that will never be
+//!   dereferenceable. In general, it is always sound for an integer to pretend to be a pointer "for
+//!   fun" as long as you don't use operations on it which require it to be valid (non-zero-sized
+//!   offset, read, write, etc).
 //!
-//! A reference to a value always has provenance over exactly the memory that field occupies.
-//! A reference to a slice always has provenance over exactly the range that slice describes.
+//! * Forge an allocation of size zero at any sufficiently aligned non-null address.
+//!   i.e. the usual "ZSTs are fake, do what you want" rules apply.
 //!
-//! If an allocation is deallocated, all pointers with provenance to that allocation become
-//! invalidated, and effectively lose their provenance.
+//! * [`wrapping_offset`] a pointer outside its provenance. This includes pointers
+//!   which have "no" provenance. In particular, this makes it sound to do pointer tagging tricks.
 //!
-//! The strict provenance experiment is mostly only interested in exploring stricter *spatial*
-//! provenance. In this sense it can be thought of as a subset of the more ambitious and
-//! formal [Stacked Borrows][] research project, which is what tools like [Miri][] are based on.
-//! In particular, Stacked Borrows is necessary to properly describe what borrows are allowed
-//! to do and when they become invalidated. This necessarily involves much more complex
-//! *temporal* reasoning than simply identifying allocations. Adjusting APIs and code
-//! for the strict provenance experiment will also greatly help Stacked Borrows.
+//! * Compare arbitrary pointers by address. Pointer comparison ignores provenance and addresses
+//!   *are* just integers, so there is always a coherent answer, even if the pointers are dangling
+//!   or from different provenances. Note that if you get "lucky" and notice that a pointer at the
+//!   end of one allocated object is the "same" address as the start of another allocated object,
+//!   anything you do with that fact is *probably* going to be gibberish. The scope of that
+//!   gibberish is kept under control by the fact that the two pointers *still* aren't allowed to
+//!   access the other's allocation (bytes), because they still have different provenance.
 //!
+//! Note that the full definition of provenance in Rust is not decided yet, as this interacts
+//! with the as-yet undecided [aliasing] rules.
 //!
-//! ## Pointer Vs Addresses
+//! ## Pointers Vs Integers
 //!
-//! **This section is *non-normative* and is part of the [Strict Provenance][] experiment.**
+//! From this discussion, it becomes very clear that a `usize` *cannot* accurately represent a pointer,
+//! and converting from a pointer to a `usize` is generally an operation which *only* extracts the
+//! address. Converting this address back into pointer requires somehow answering the question:
+//! which provenance should the resulting pointer have?
 //!
-//! One of the largest historical issues with trying to define provenance is that programmers
-//! freely convert between pointers and integers. Once you allow for this, it generally becomes
-//! impossible to accurately track and preserve provenance information, and you need to appeal
-//! to very complex and unreliable heuristics. But of course, converting between pointers and
-//! integers is very useful, so what can we do?
+//! Rust provides two ways of dealing with this situation: *Strict Provenance* and *Exposed Provenance*.
 //!
-//! Also did you know WASM is actually a "Harvard Architecture"? As in function pointers are
-//! handled completely differently from data pointers? And we kind of just shipped Rust on WASM
-//! without really addressing the fact that we let you freely convert between function pointers
-//! and data pointers, because it mostly Just Works? Let's just put that on the "pointer casts
-//! are dubious" pile.
+//! Note that a pointer *can* represent a `usize` (via [`without_provenance`]), so the right type to
+//! use in situations where a value is "sometimes a pointer and sometimes a bare `usize`" is a
+//! pointer type.
 //!
-//! Strict Provenance attempts to square these circles by decoupling Rust's traditional conflation
-//! of pointers and `usize` (and `isize`), and defining a pointer to semantically contain the
-//! following information:
+//! ## Strict Provenance
 //!
-//! * The **address-space** it is part of (e.g. "data" vs "code" in WASM).
-//! * The **address** it points to, which can be represented by a `usize`.
-//! * The **provenance** it has, defining the memory it has permission to access.
-//!   Provenance can be absent, in which case the pointer does not have permission to access any memory.
+//! "Strict Provenance" refers to a set of APIs designed to make working with provenance more
+//! explicit. They are intended as substitutes for casting a pointer to an integer and back.
 //!
-//! Under Strict Provenance, a `usize` *cannot* accurately represent a pointer, and converting from
-//! a pointer to a `usize` is generally an operation which *only* extracts the address. It is
-//! therefore *impossible* to construct a valid pointer from a `usize` because there is no way
-//! to restore the address-space and provenance. In other words, pointer-integer-pointer
-//! roundtrips are not possible (in the sense that the resulting pointer is not dereferenceable).
+//! Entirely avoiding integer-to-pointer casts successfully side-steps the inherent ambiguity of
+//! that operation. This benefits compiler optimizations, and it is pretty much a requirement for
+//! using tools like [Miri] and architectures like [CHERI] that aim to detect and diagnose pointer
+//! misuse.
 //!
-//! The key insight to making this model *at all* viable is the [`with_addr`][] method:
+//! The key insight to making programming without integer-to-pointer casts *at all* viable is the
+//! [`with_addr`] method:
 //!
 //! ```text
 //!     /// Creates a new pointer with the given address.
 //!     ///
 //!     /// This performs the same operation as an `addr as ptr` cast, but copies
-//!     /// the *address-space* and *provenance* of `self` to the new pointer.
+//!     /// the *provenance* of `self` to the new pointer.
 //!     /// This allows us to dynamically preserve and propagate this important
 //!     /// information in a way that is otherwise impossible with a unary cast.
 //!     ///
@@ -257,23 +265,21 @@
 //!
 //! So you're still able to drop down to the address representation and do whatever
 //! clever bit tricks you want *as long as* you're able to keep around a pointer
-//! into the allocation you care about that can "reconstitute" the other parts of the pointer.
+//! into the allocation you care about that can "reconstitute" the provenance.
 //! Usually this is very easy, because you only are taking a pointer, messing with the address,
 //! and then immediately converting back to a pointer. To make this use case more ergonomic,
-//! we provide the [`map_addr`][] method.
+//! we provide the [`map_addr`] method.
 //!
 //! To help make it clear that code is "following" Strict Provenance semantics, we also provide an
-//! [`addr`][] method which promises that the returned address is not part of a
-//! pointer-usize-pointer roundtrip. In the future we may provide a lint for pointer<->integer
+//! [`addr`] method which promises that the returned address is not part of a
+//! pointer-integer-pointer roundtrip. In the future we may provide a lint for pointer<->integer
 //! casts to help you audit if your code conforms to strict provenance.
 //!
-//!
-//! ## Using Strict Provenance
+//! ### Using Strict Provenance
 //!
 //! Most code needs no changes to conform to strict provenance, as the only really concerning
-//! operation that *wasn't* obviously already Undefined Behaviour is casts from usize to a
-//! pointer. For code which *does* cast a `usize` to a pointer, the scope of the change depends
-//! on exactly what you're doing.
+//! operation is casts from usize to a pointer. For code which *does* cast a `usize` to a pointer,
+//! the scope of the change depends on exactly what you're doing.
 //!
 //! In general, you just need to make sure that if you want to convert a `usize` address to a
 //! pointer and then use that pointer to read/write memory, you need to keep around a pointer
@@ -284,8 +290,6 @@
 //! represent the tagged pointer as an actual pointer and not a `usize`*. For instance:
 //!
 //! ```
-//! #![feature(strict_provenance)]
-//!
 //! unsafe {
 //!     // A flag we want to pack into our pointer
 //!     static HAS_DATA: usize = 0x1;
@@ -314,122 +318,65 @@
 //! be using AtomicPtr instead. If that messes up the way you atomically manipulate pointers,
 //! we would like to know why, and what needs to be done to fix it.)
 //!
-//! Something more complicated and just generally *evil* like an XOR-List requires more significant
-//! changes like allocating all nodes in a pre-allocated Vec or Arena and using a pointer
-//! to the whole allocation to reconstitute the XORed addresses.
-//!
 //! Situations where a valid pointer *must* be created from just an address, such as baremetal code
-//! accessing a memory-mapped interface at a fixed address, are an open question on how to support.
-//! These situations *will* still be allowed, but we might require some kind of "I know what I'm
-//! doing" annotation to explain the situation to the compiler. It's also possible they need no
-//! special attention at all, because they're generally accessing memory outside the scope of
-//! "the abstract machine", or already using "I know what I'm doing" annotations like "volatile".
-//!
-//! Under [Strict Provenance] it is Undefined Behaviour to:
-//!
-//! * Access memory through a pointer that does not have provenance over that memory.
-//!
-//! * [`offset`] a pointer to or from an address it doesn't have provenance over.
-//!   This means it's always UB to offset a pointer derived from something deallocated,
-//!   even if the offset is 0. Note that a pointer "one past the end" of its provenance
-//!   is not actually outside its provenance, it just has 0 bytes it can load/store.
-//!
-//! But it *is* still sound to:
-//!
-//! * Create a pointer without provenance from just an address (see [`ptr::dangling`][]). Such a
-//!   pointer cannot be used for memory accesses (except for zero-sized accesses). This can still be
-//!   useful for sentinel values like `null` *or* to represent a tagged pointer that will never be
-//!   dereferenceable. In general, it is always sound for an integer to pretend to be a pointer "for
-//!   fun" as long as you don't use operations on it which require it to be valid (non-zero-sized
-//!   offset, read, write, etc).
-//!
-//! * Forge an allocation of size zero at any sufficiently aligned non-null address.
-//!   i.e. the usual "ZSTs are fake, do what you want" rules apply *but* this only applies
-//!   for actual forgery (integers cast to pointers). If you borrow some struct's field
-//!   that *happens* to be zero-sized, the resulting pointer will have provenance tied to
-//!   that allocation, and it will still get invalidated if the allocation gets deallocated.
-//!   In the future we may introduce an API to make such a forged allocation explicit.
-//!
-//! * [`wrapping_offset`][] a pointer outside its provenance. This includes pointers
-//!   which have "no" provenance. Unfortunately there may be practical limits on this for a
-//!   particular platform, and it's an open question as to how to specify this (if at all).
-//!   Notably, [CHERI][] relies on a compression scheme that can't handle a
-//!   pointer getting offset "too far" out of bounds. If this happens, the address
-//!   returned by `addr` will be the value you expect, but the provenance will get invalidated
-//!   and using it to read/write will fault. The details of this are architecture-specific
-//!   and based on alignment, but the buffer on either side of the pointer's range is pretty
-//!   generous (think kilobytes, not bytes).
-//!
-//! * Compare arbitrary pointers by address. Addresses *are* just integers and so there is
-//!   always a coherent answer, even if the pointers are dangling or from different
-//!   address-spaces/provenances. Of course, comparing addresses from different address-spaces
-//!   is generally going to be *meaningless*, but so is comparing Kilograms to Meters, and Rust
-//!   doesn't prevent that either. Similarly, if you get "lucky" and notice that a pointer
-//!   one-past-the-end is the "same" address as the start of an unrelated allocation, anything
-//!   you do with that fact is *probably* going to be gibberish. The scope of that gibberish
-//!   is kept under control by the fact that the two pointers *still* aren't allowed to access
-//!   the other's allocation (bytes), because they still have different provenance.
-//!
-//! * Perform pointer tagging tricks. This falls out of [`wrapping_offset`] but is worth
-//!   mentioning in more detail because of the limitations of [CHERI][]. Low-bit tagging
-//!   is very robust, and often doesn't even go out of bounds because types ensure
-//!   size >= align (and over-aligning actually gives CHERI more flexibility). Anything
-//!   more complex than this rapidly enters "extremely platform-specific" territory as
-//!   certain things may or may not be allowed based on specific supported operations.
-//!   For instance, ARM explicitly supports high-bit tagging, and so CHERI on ARM inherits
-//!   that and should support it.
+//! accessing a memory-mapped interface at a fixed address, cannot currently be handled with strict
+//! provenance APIs and should use [exposed provenance](#exposed-provenance).
 //!
 //! ## Exposed Provenance
 //!
-//! **This section is *non-normative* and is an extension to the [Strict Provenance] experiment.**
-//!
-//! As discussed above, pointer-usize-pointer roundtrips are not possible under [Strict Provenance].
+//! As discussed above, integer-to-pointer casts are not possible with Strict Provenance APIs.
 //! This is by design: the goal of Strict Provenance is to provide a clear specification that we are
-//! confident can be formalized unambiguously and can be subject to  precise formal reasoning.
+//! confident can be formalized unambiguously and can be subject to precise formal reasoning.
+//! Integer-to-pointer casts do not (currently) have such a clear specification.
 //!
-//! However, there exist situations where pointer-usize-pointer roundtrips cannot be avoided, or
+//! However, there exist situations where integer-to-pointer casts cannot be avoided, or
 //! where avoiding them would require major refactoring. Legacy platform APIs also regularly assume
-//! that `usize` can capture all the information that makes up a pointer. The goal of Strict
-//! Provenance is not to rule out such code; the goal is to put all the *other* pointer-manipulating
-//! code onto a more solid foundation. Strict Provenance is about improving the situation where
-//! possible (all the code that can be written with Strict Provenance) without making things worse
-//! for situations where Strict Provenance is insufficient.
-//!
-//! For these situations, there is a highly experimental extension to Strict Provenance called
-//! *Exposed Provenance*. This extension permits pointer-usize-pointer roundtrips. However, its
-//! semantics are on much less solid footing than Strict Provenance, and at this point it is not yet
-//! clear where a satisfying unambiguous semantics can be defined for Exposed Provenance.
-//! Furthermore, Exposed Provenance will not work (well) with tools like [Miri] and [CHERI].
+//! that `usize` can capture all the information that makes up a pointer.
+//! Bare-metal platforms can also require the synthesis of a pointer "out of thin air" without
+//! anywhere to obtain proper provenance from.
+//!
+//! Rust's model for dealing with integer-to-pointer casts is called *Exposed Provenance*. However,
+//! the semantics of Exposed Provenance are on much less solid footing than Strict Provenance, and
+//! at this point it is not yet clear whether a satisfying unambiguous semantics can be defined for
+//! Exposed Provenance. (If that sounds bad, be reassured that other popular languages that provide
+//! integer-to-pointer casts are not faring any better.) Furthermore, Exposed Provenance will not
+//! work (well) with tools like [Miri] and [CHERI].
 //!
 //! Exposed Provenance is provided by the [`expose_provenance`] and [`with_exposed_provenance`] methods,
-//! which are meant to replace `as` casts between pointers and integers. [`expose_provenance`] is a lot like
-//! [`addr`], but additionally adds the provenance of the pointer to a global list of 'exposed'
-//! provenances. (This list is purely conceptual, it exists for the purpose of specifying Rust but
-//! is not materialized in actual executions, except in tools like [Miri].) [`with_exposed_provenance`]
-//! can be used to construct a pointer with one of these previously 'exposed' provenances.
-//! [`with_exposed_provenance`] takes only `addr: usize` as arguments, so unlike in [`with_addr`] there is
-//! no indication of what the correct provenance for the returned pointer is -- and that is exactly
-//! what makes pointer-usize-pointer roundtrips so tricky to rigorously specify! There is no
-//! algorithm that decides which provenance will be used. You can think of this as "guessing" the
-//! right provenance, and the guess will be "maximally in your favor", in the sense that if there is
-//! any way to avoid undefined behavior, then that is the guess that will be taken. However, if
-//! there is *no* previously 'exposed' provenance that justifies the way the returned pointer will
-//! be used, the program has undefined behavior.
-//!
-//! Using [`expose_provenance`] or [`with_exposed_provenance`] (or the `as` casts) means that code is
-//! *not* following Strict Provenance rules. The goal of the Strict Provenance experiment is to
-//! determine how far one can get in Rust without the use of [`expose_provenance`] and
-//! [`with_exposed_provenance`], and to encourage code to be written with Strict Provenance APIs only.
-//! Maximizing the amount of such code is a major win for avoiding specification complexity and to
-//! facilitate adoption of tools like [CHERI] and [Miri] that can be a big help in increasing the
-//! confidence in (unsafe) Rust code.
+//! which are equivalent to `as` casts between pointers and integers.
+//! - [`expose_provenance`] is a lot like [`addr`], but additionally adds the provenance of the
+//!   pointer to a global list of 'exposed' provenances. (This list is purely conceptual, it exists
+//!   for the purpose of specifying Rust but is not materialized in actual executions, except in
+//!   tools like [Miri].)
+//!   Memory which is outside the control of the Rust abstract machine (MMIO registers, for example)
+//!   is always considered to be exposed, so long as this memory is disjoint from memory that will
+//!   be used by the abstract machine such as the stack, heap, and statics.
+//! - [`with_exposed_provenance`] can be used to construct a pointer with one of these previously
+//!   'exposed' provenances. [`with_exposed_provenance`] takes only `addr: usize` as arguments, so
+//!   unlike in [`with_addr`] there is no indication of what the correct provenance for the returned
+//!   pointer is -- and that is exactly what makes integer-to-pointer casts so tricky to rigorously
+//!   specify! The compiler will do its best to pick the right provenance for you, but currently we
+//!   cannot provide any guarantees about which provenance the resulting pointer will have. Only one
+//!   thing is clear: if there is *no* previously 'exposed' provenance that justifies the way the
+//!   returned pointer will be used, the program has undefined behavior.
+//!
+//! If at all possible, we encourage code to be ported to [Strict Provenance] APIs, thus avoiding
+//! the need for Exposed Provenance. Maximizing the amount of such code is a major win for avoiding
+//! specification complexity and to facilitate adoption of tools like [CHERI] and [Miri] that can be
+//! a big help in increasing the confidence in (unsafe) Rust code. However, we acknowledge that this
+//! is not always possible, and offer Exposed Provenance as a way to explicit "opt out" of the
+//! well-defined semantics of Strict Provenance, and "opt in" to the unclear semantics of
+//! integer-to-pointer casts.
 //!
 //! [aliasing]: ../../nomicon/aliasing.html
+//! [allocated object]: #allocated-object
+//! [provenance]: #provenance
 //! [book]: ../../book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
 //! [ub]: ../../reference/behavior-considered-undefined.html
 //! [zst]: ../../nomicon/exotic-sizes.html#zero-sized-types-zsts
 //! [atomic operations]: crate::sync::atomic
 //! [`offset`]: pointer::offset
+//! [`offset_from`]: pointer::offset_from
 //! [`wrapping_offset`]: pointer::wrapping_offset
 //! [`with_addr`]: pointer::with_addr
 //! [`map_addr`]: pointer::map_addr
@@ -439,8 +386,8 @@
 //! [`with_exposed_provenance`]: with_exposed_provenance
 //! [Miri]: https://github.com/rust-lang/miri
 //! [CHERI]: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/
-//! [Strict Provenance]: https://github.com/rust-lang/rust/issues/95228
-//! [Stacked Borrows]: https://plv.mpi-sws.org/rustbelt/stacked-borrows/
+//! [Strict Provenance]: #strict-provenance
+//! [`UnsafeCell`]: core::cell::UnsafeCell
 
 #![stable(feature = "rust1", since = "1.0.0")]
 // There are many unsafe functions taking pointers that don't dereference them.
@@ -629,7 +576,7 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
     from_raw_parts_mut(without_provenance_mut::<()>(0), ())
 }
 
-/// Creates a pointer with the given address and no provenance.
+/// Creates a pointer with the given address and no [provenance][crate::ptr#provenance].
 ///
 /// This is equivalent to `ptr::null().with_addr(addr)`.
 ///
@@ -641,16 +588,15 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
 /// This is different from `addr as *const T`, which creates a pointer that picks up a previously
 /// exposed provenance. See [`with_exposed_provenance`] for more details on that operation.
 ///
-/// This API and its claimed semantics are part of the Strict Provenance experiment,
-/// see the [module documentation][crate::ptr] for details.
+/// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
 #[inline(always)]
 #[must_use]
 #[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")]
-#[unstable(feature = "strict_provenance", issue = "95228")]
+#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
 pub const fn without_provenance<T>(addr: usize) -> *const T {
-    // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
-    // We use transmute rather than a cast so tools like Miri can tell that this
-    // is *not* the same as with_exposed_provenance.
+    // An int-to-pointer transmute currently has exactly the intended semantics: it creates a
+    // pointer without provenance. Note that this is *not* a stable guarantee about transmute
+    // semantics, it relies on sysroot crates having special status.
     // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
     // pointer).
     unsafe { mem::transmute(addr) }
@@ -668,12 +614,12 @@ pub const fn without_provenance<T>(addr: usize) -> *const T {
 #[inline(always)]
 #[must_use]
 #[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")]
-#[unstable(feature = "strict_provenance", issue = "95228")]
+#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
 pub const fn dangling<T>() -> *const T {
     without_provenance(mem::align_of::<T>())
 }
 
-/// Creates a pointer with the given address and no provenance.
+/// Creates a pointer with the given address and no [provenance][crate::ptr#provenance].
 ///
 /// This is equivalent to `ptr::null_mut().with_addr(addr)`.
 ///
@@ -685,16 +631,15 @@ pub const fn dangling<T>() -> *const T {
 /// This is different from `addr as *mut T`, which creates a pointer that picks up a previously
 /// exposed provenance. See [`with_exposed_provenance_mut`] for more details on that operation.
 ///
-/// This API and its claimed semantics are part of the Strict Provenance experiment,
-/// see the [module documentation][crate::ptr] for details.
+/// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
 #[inline(always)]
 #[must_use]
 #[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")]
-#[unstable(feature = "strict_provenance", issue = "95228")]
+#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
 pub const fn without_provenance_mut<T>(addr: usize) -> *mut T {
-    // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
-    // We use transmute rather than a cast so tools like Miri can tell that this
-    // is *not* the same as with_exposed_provenance.
+    // An int-to-pointer transmute currently has exactly the intended semantics: it creates a
+    // pointer without provenance. Note that this is *not* a stable guarantee about transmute
+    // semantics, it relies on sysroot crates having special status.
     // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
     // pointer).
     unsafe { mem::transmute(addr) }
@@ -712,96 +657,88 @@ pub const fn without_provenance_mut<T>(addr: usize) -> *mut T {
 #[inline(always)]
 #[must_use]
 #[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")]
-#[unstable(feature = "strict_provenance", issue = "95228")]
+#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
 pub const fn dangling_mut<T>() -> *mut T {
     without_provenance_mut(mem::align_of::<T>())
 }
 
-/// Converts an address back to a pointer, picking up a previously 'exposed' provenance.
+/// Converts an address back to a pointer, picking up some previously 'exposed'
+/// [provenance][crate::ptr#provenance].
 ///
-/// This is a more rigorously specified alternative to `addr as *const T`. The provenance of the
-/// returned pointer is that of *any* pointer that was previously exposed by passing it to
-/// [`expose_provenance`][pointer::expose_provenance], or a `ptr as usize` cast. In addition, memory which is
-/// outside the control of the Rust abstract machine (MMIO registers, for example) is always
-/// considered to be exposed, so long as this memory is disjoint from memory that will be used by
-/// the abstract machine such as the stack, heap, and statics.
+/// This is fully equivalent to `addr as *const T`. The provenance of the returned pointer is that
+/// of *some* pointer that was previously exposed by passing it to
+/// [`expose_provenance`][pointer::expose_provenance], or a `ptr as usize` cast. In addition, memory
+/// which is outside the control of the Rust abstract machine (MMIO registers, for example) is
+/// always considered to be accessible with an exposed provenance, so long as this memory is disjoint
+/// from memory that will be used by the abstract machine such as the stack, heap, and statics.
 ///
-/// If there is no 'exposed' provenance that justifies the way this pointer will be used,
-/// the program has undefined behavior. In particular, the aliasing rules still apply: pointers
-/// and references that have been invalidated due to aliasing accesses cannot be used anymore,
-/// even if they have been exposed!
+/// The exact provenance that gets picked is not specified. The compiler will do its best to pick
+/// the "right" provenance for you (whatever that may be), but currently we cannot provide any
+/// guarantees about which provenance the resulting pointer will have -- and therefore there
+/// is no definite specification for which memory the resulting pointer may access.
 ///
-/// Note that there is no algorithm that decides which provenance will be used. You can think of this
-/// as "guessing" the right provenance, and the guess will be "maximally in your favor", in the sense
-/// that if there is any way to avoid undefined behavior (while upholding all aliasing requirements),
-/// then that is the guess that will be taken.
+/// If there is *no* previously 'exposed' provenance that justifies the way the returned pointer
+/// will be used, the program has undefined behavior. In particular, the aliasing rules still apply:
+/// pointers and references that have been invalidated due to aliasing accesses cannot be used
+/// anymore, even if they have been exposed!
 ///
-/// On platforms with multiple address spaces, it is your responsibility to ensure that the
-/// address makes sense in the address space that this pointer will be used with.
-///
-/// Using this function means that code is *not* following [Strict
-/// Provenance][self#strict-provenance] rules. "Guessing" a
-/// suitable provenance complicates specification and reasoning and may not be supported by
-/// tools that help you to stay conformant with the Rust memory model, so it is recommended to
-/// use [`with_addr`][pointer::with_addr] wherever possible.
+/// Due to its inherent ambiguity, this operation may not be supported by tools that help you to
+/// stay conformant with the Rust memory model. It is recommended to use [Strict
+/// Provenance][self#strict-provenance] APIs such as [`with_addr`][pointer::with_addr] wherever
+/// possible.
 ///
 /// On most platforms this will produce a value with the same bytes as the address. Platforms
 /// which need to store additional information in a pointer may not support this operation,
 /// since it is generally not possible to actually *compute* which provenance the returned
 /// pointer has to pick up.
 ///
-/// It is unclear whether this function can be given a satisfying unambiguous specification. This
-/// API and its claimed semantics are part of [Exposed Provenance][self#exposed-provenance].
+/// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
 #[must_use]
 #[inline(always)]
-#[unstable(feature = "exposed_provenance", issue = "95228")]
+#[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead
-pub fn with_exposed_provenance<T>(addr: usize) -> *const T
-where
-    T: Sized,
-{
-    // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
+pub fn with_exposed_provenance<T>(addr: usize) -> *const T {
     addr as *const T
 }
 
-/// Converts an address back to a mutable pointer, picking up a previously 'exposed' provenance.
+/// Converts an address back to a mutable pointer, picking up some previously 'exposed'
+/// [provenance][crate::ptr#provenance].
+///
+/// This is fully equivalent to `addr as *mut T`. The provenance of the returned pointer is that
+/// of *some* pointer that was previously exposed by passing it to
+/// [`expose_provenance`][pointer::expose_provenance], or a `ptr as usize` cast. In addition, memory
+/// which is outside the control of the Rust abstract machine (MMIO registers, for example) is
+/// always considered to be accessible with an exposed provenance, so long as this memory is disjoint
+/// from memory that will be used by the abstract machine such as the stack, heap, and statics.
 ///
-/// This is a more rigorously specified alternative to `addr as *mut T`. The provenance of the
-/// returned pointer is that of *any* pointer that was previously passed to
-/// [`expose_provenance`][pointer::expose_provenance] or a `ptr as usize` cast. If there is no previously
-/// 'exposed' provenance that justifies the way this pointer will be used, the program has undefined
-/// behavior. Note that there is no algorithm that decides which provenance will be used. You can
-/// think of this as "guessing" the right provenance, and the guess will be "maximally in your
-/// favor", in the sense that if there is any way to avoid undefined behavior, then that is the
-/// guess that will be taken.
+/// The exact provenance that gets picked is not specified. The compiler will do its best to pick
+/// the "right" provenance for you (whatever that may be), but currently we cannot provide any
+/// guarantees about which provenance the resulting pointer will have -- and therefore there
+/// is no definite specification for which memory the resulting pointer may access.
 ///
-/// On platforms with multiple address spaces, it is your responsibility to ensure that the
-/// address makes sense in the address space that this pointer will be used with.
+/// If there is *no* previously 'exposed' provenance that justifies the way the returned pointer
+/// will be used, the program has undefined behavior. In particular, the aliasing rules still apply:
+/// pointers and references that have been invalidated due to aliasing accesses cannot be used
+/// anymore, even if they have been exposed!
 ///
-/// Using this function means that code is *not* following [Strict
-/// Provenance][self#strict-provenance] rules. "Guessing" a
-/// suitable provenance complicates specification and reasoning and may not be supported by
-/// tools that help you to stay conformant with the Rust memory model, so it is recommended to
-/// use [`with_addr`][pointer::with_addr] wherever possible.
+/// Due to its inherent ambiguity, this operation may not be supported by tools that help you to
+/// stay conformant with the Rust memory model. It is recommended to use [Strict
+/// Provenance][self#strict-provenance] APIs such as [`with_addr`][pointer::with_addr] wherever
+/// possible.
 ///
 /// On most platforms this will produce a value with the same bytes as the address. Platforms
 /// which need to store additional information in a pointer may not support this operation,
 /// since it is generally not possible to actually *compute* which provenance the returned
 /// pointer has to pick up.
 ///
-/// It is unclear whether this function can be given a satisfying unambiguous specification. This
-/// API and its claimed semantics are part of [Exposed Provenance][self#exposed-provenance].
+/// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
 #[must_use]
 #[inline(always)]
-#[unstable(feature = "exposed_provenance", issue = "95228")]
+#[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead
-pub fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T
-where
-    T: Sized,
-{
-    // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
+pub fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T {
     addr as *mut T
 }
 
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 613d2c91ac6..782934fc311 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -124,12 +124,12 @@ impl<T: ?Sized> *mut T {
 
     /// Gets the "address" portion of the pointer.
     ///
-    /// This is similar to `self as usize`, which semantically discards *provenance* and
-    /// *address-space* information. However, unlike `self as usize`, casting the returned address
-    /// back to a pointer yields a [pointer without provenance][without_provenance_mut], which is undefined
-    /// behavior to dereference. To properly restore the lost information and obtain a
-    /// dereferenceable pointer, use [`with_addr`][pointer::with_addr] or
-    /// [`map_addr`][pointer::map_addr].
+    /// This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
+    /// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
+    /// casting the returned address back to a pointer yields a [pointer without
+    /// provenance][without_provenance_mut], which is undefined behavior to dereference. To properly
+    /// restore the lost information and obtain a dereferenceable pointer, use
+    /// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
     ///
     /// If using those APIs is not possible because there is no way to preserve a pointer with the
     /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
@@ -143,89 +143,80 @@ impl<T: ?Sized> *mut T {
     /// perform a change of representation to produce a value containing only the address
     /// portion of the pointer. What that means is up to the platform to define.
     ///
-    /// This API and its claimed semantics are part of the Strict Provenance experiment, and as such
-    /// might change in the future (including possibly weakening this so it becomes wholly
-    /// equivalent to `self as usize`). See the [module documentation][crate::ptr] for details.
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline(always)]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn addr(self) -> usize {
-        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
+        // A pointer-to-integer transmute currently has exactly the right semantics: it returns the
+        // address without exposing the provenance. Note that this is *not* a stable guarantee about
+        // transmute semantics, it relies on sysroot crates having special status.
         // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
         // provenance).
         unsafe { mem::transmute(self.cast::<()>()) }
     }
 
-    /// Exposes the "provenance" part of the pointer for future use in
-    /// [`with_exposed_provenance`][] and returns the "address" portion.
+    /// Exposes the ["provenance"][crate::ptr#provenance] part of the pointer for future use in
+    /// [`with_exposed_provenance_mut`] and returns the "address" portion.
     ///
-    /// This is equivalent to `self as usize`, which semantically discards *provenance* and
-    /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
-    /// side-effect of marking the provenance as 'exposed', so on platforms that support it you can
-    /// later call [`with_exposed_provenance_mut`][] to reconstitute the original pointer including its
-    /// provenance. (Reconstructing address space information, if required, is your responsibility.)
+    /// This is equivalent to `self as usize`, which semantically discards provenance information.
+    /// Furthermore, this (like the `as` cast) has the implicit side-effect of marking the
+    /// provenance as 'exposed', so on platforms that support it you can later call
+    /// [`with_exposed_provenance_mut`] to reconstitute the original pointer including its provenance.
     ///
-    /// Using this method means that code is *not* following [Strict
-    /// Provenance][super#strict-provenance] rules. Supporting
-    /// [`with_exposed_provenance_mut`][] complicates specification and reasoning and may not be supported
-    /// by tools that help you to stay conformant with the Rust memory model, so it is recommended
-    /// to use [`addr`][pointer::addr] wherever possible.
+    /// Due to its inherent ambiguity, [`with_exposed_provenance_mut`] may not be supported by tools
+    /// that help you to stay conformant with the Rust memory model. It is recommended to use
+    /// [Strict Provenance][crate::ptr#strict-provenance] APIs such as [`with_addr`][pointer::with_addr]
+    /// wherever possible, in which case [`addr`][pointer::addr] should be used instead of `expose_provenance`.
     ///
     /// On most platforms this will produce a value with the same bytes as the original pointer,
     /// because all the bytes are dedicated to describing the address. Platforms which need to store
     /// additional information in the pointer may not support this operation, since the 'expose'
-    /// side-effect which is required for [`with_exposed_provenance_mut`][] to work is typically not
+    /// side-effect which is required for [`with_exposed_provenance_mut`] to work is typically not
     /// available.
     ///
-    /// It is unclear whether this method can be given a satisfying unambiguous specification. This
-    /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].
+    /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
     ///
     /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut
     #[inline(always)]
-    #[unstable(feature = "exposed_provenance", issue = "95228")]
+    #[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn expose_provenance(self) -> usize {
-        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         self.cast::<()>() as usize
     }
 
-    /// Creates a new pointer with the given address.
+    /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
+    /// `self`.
     ///
-    /// This performs the same operation as an `addr as ptr` cast, but copies
-    /// the *address-space* and *provenance* of `self` to the new pointer.
-    /// This allows us to dynamically preserve and propagate this important
-    /// information in a way that is otherwise impossible with a unary cast.
+    /// This is similar to a `addr as *mut T` cast, but copies
+    /// the *provenance* of `self` to the new pointer.
+    /// This avoids the inherent ambiguity of the unary cast.
     ///
     /// This is equivalent to using [`wrapping_offset`][pointer::wrapping_offset] to offset
     /// `self` to the given address, and therefore has all the same capabilities and restrictions.
     ///
-    /// This API and its claimed semantics are an extension to the Strict Provenance experiment,
-    /// see the [module documentation][crate::ptr] for details.
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn with_addr(self, addr: usize) -> Self {
-        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
-        //
-        // In the mean-time, this operation is defined to be "as if" it was
-        // a wrapping_offset, so we can emulate it as such. This should properly
-        // restore pointer provenance even under today's compiler.
+        // This should probably be an intrinsic to avoid doing any sort of arithmetic, but
+        // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's
+        // provenance.
         let self_addr = self.addr() as isize;
         let dest_addr = addr as isize;
         let offset = dest_addr.wrapping_sub(self_addr);
-
-        // This is the canonical desugaring of this operation
         self.wrapping_byte_offset(offset)
     }
 
-    /// Creates a new pointer by mapping `self`'s address to a new one.
+    /// Creates a new pointer by mapping `self`'s address to a new one, preserving the original
+    /// pointer's [provenance][crate::ptr#provenance].
     ///
     /// This is a convenience for [`with_addr`][pointer::with_addr], see that method for details.
     ///
-    /// This API and its claimed semantics are part of the Strict Provenance experiment,
-    /// see the [module documentation][crate::ptr] for details.
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self {
         self.with_addr(f(self.addr()))
     }
@@ -376,7 +367,7 @@ impl<T: ?Sized> *mut T {
     /// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
     ///   "wrapping around"), must fit in an `isize`.
     ///
-    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
     ///   [allocated object], and the entire memory range between `self` and the result must be in
     ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
     ///   of the address space.
@@ -558,7 +549,7 @@ impl<T: ?Sized> *mut T {
     /// ## Examples
     ///
     /// ```
-    /// #![feature(ptr_mask, strict_provenance)]
+    /// #![feature(ptr_mask)]
     /// let mut v = 17_u32;
     /// let ptr: *mut u32 = &mut v;
     ///
@@ -777,7 +768,7 @@ impl<T: ?Sized> *mut T {
     /// * `self` and `origin` must either
     ///
     ///   * point to the same address, or
-    ///   * both be *derived from* a pointer to the same [allocated object], and the memory range between
+    ///   * both be [derived from][crate::ptr#provenance] a pointer to the same [allocated object], and the memory range between
     ///     the two pointers must be in bounds of that object. (See below for an example.)
     ///
     /// * The distance between the pointers, in bytes, must be an exact multiple
@@ -954,7 +945,7 @@ impl<T: ?Sized> *mut T {
     /// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
     ///   "wrapping around"), must fit in an `isize`.
     ///
-    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
     ///   [allocated object], and the entire memory range between `self` and the result must be in
     ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
     ///   of the address space.
@@ -1061,7 +1052,7 @@ impl<T: ?Sized> *mut T {
     /// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
     ///   "wrapping around"), must fit in an `isize`.
     ///
-    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
     ///   [allocated object], and the entire memory range between `self` and the result must be in
     ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
     ///   of the address space.
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 3e4cae2b3ca..d91bbe1a5a1 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -283,40 +283,39 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// For more details see the equivalent method on a raw pointer, [`pointer::addr`].
     ///
-    /// This API and its claimed semantics are part of the Strict Provenance experiment,
-    /// see the [`ptr` module documentation][crate::ptr].
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn addr(self) -> NonZero<usize> {
         // SAFETY: The pointer is guaranteed by the type to be non-null,
         // meaning that the address will be non-zero.
         unsafe { NonZero::new_unchecked(self.pointer.addr()) }
     }
 
-    /// Creates a new pointer with the given address.
+    /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
+    /// `self`.
     ///
     /// For more details see the equivalent method on a raw pointer, [`pointer::with_addr`].
     ///
-    /// This API and its claimed semantics are part of the Strict Provenance experiment,
-    /// see the [`ptr` module documentation][crate::ptr].
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn with_addr(self, addr: NonZero<usize>) -> Self {
         // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero.
         unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) }
     }
 
-    /// Creates a new pointer by mapping `self`'s address to a new one.
+    /// Creates a new pointer by mapping `self`'s address to a new one, preserving the
+    /// [provenance][crate::ptr#provenance] of `self`.
     ///
     /// For more details see the equivalent method on a raw pointer, [`pointer::map_addr`].
     ///
-    /// This API and its claimed semantics are part of the Strict Provenance experiment,
-    /// see the [`ptr` module documentation][crate::ptr].
+    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[must_use]
     #[inline]
-    #[unstable(feature = "strict_provenance", issue = "95228")]
+    #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn map_addr(self, f: impl FnOnce(NonZero<usize>) -> NonZero<usize>) -> Self {
         self.with_addr(f(self.addr()))
     }
@@ -749,7 +748,6 @@ impl<T: ?Sized> NonNull<T> {
     /// *Incorrect* usage:
     ///
     /// ```rust,no_run
-    /// #![feature(strict_provenance)]
     /// use std::ptr::NonNull;
     ///
     /// let ptr1 = NonNull::new(Box::into_raw(Box::new(0u8))).unwrap();
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 42b68e28273..17ba18c2a66 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -1758,7 +1758,7 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
+    /// #![feature(strict_provenance_atomic_ptr)]
     /// use core::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
@@ -1838,7 +1838,7 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
+    /// #![feature(strict_provenance_atomic_ptr)]
     /// use core::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
@@ -1874,7 +1874,7 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
+    /// #![feature(strict_provenance_atomic_ptr)]
     /// use core::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let atom = AtomicPtr::<i64>::new(core::ptr::without_provenance_mut(1));
@@ -1919,7 +1919,7 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
+    /// #![feature(strict_provenance_atomic_ptr)]
     /// use core::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let pointer = &mut 3i64 as *mut i64;
@@ -1970,7 +1970,7 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
+    /// #![feature(strict_provenance_atomic_ptr)]
     /// use core::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let pointer = &mut 3i64 as *mut i64;
@@ -2020,7 +2020,7 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
+    /// #![feature(strict_provenance_atomic_ptr)]
     /// use core::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let pointer = &mut 3i64 as *mut i64;
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 443090097c0..5d6921845d0 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -1,4 +1,6 @@
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(strict_provenance))]
+#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
 #![cfg_attr(test, feature(cfg_match))]
 #![feature(alloc_layout_extra)]
@@ -85,7 +87,6 @@
 #![feature(std_internals)]
 #![feature(step_trait)]
 #![feature(str_internals)]
-#![feature(strict_provenance)]
 #![feature(strict_provenance_atomic_ptr)]
 #![feature(test)]
 #![feature(trait_upcasting)]
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index 6cd4dffb8aa..1981675f409 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -19,8 +19,6 @@
 #![feature(panic_unwind)]
 #![feature(staged_api)]
 #![feature(std_internals)]
-#![feature(strict_provenance)]
-#![feature(exposed_provenance)]
 #![feature(rustc_attrs)]
 #![panic_runtime]
 #![feature(panic_runtime)]
diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs
index cc6246b4a0d..992a7705e3c 100644
--- a/library/portable-simd/crates/core_simd/src/lib.rs
+++ b/library/portable-simd/crates/core_simd/src/lib.rs
@@ -9,7 +9,6 @@
     repr_simd,
     simd_ffi,
     staged_api,
-    strict_provenance,
     prelude_import,
     ptr_metadata
 )]
diff --git a/library/portable-simd/crates/core_simd/tests/pointers.rs b/library/portable-simd/crates/core_simd/tests/pointers.rs
index 90bfc5d5fd6..d7db4e82b3c 100644
--- a/library/portable-simd/crates/core_simd/tests/pointers.rs
+++ b/library/portable-simd/crates/core_simd/tests/pointers.rs
@@ -1,4 +1,4 @@
-#![feature(portable_simd, strict_provenance, exposed_provenance)]
+#![feature(portable_simd)]
 
 use core_simd::simd::{
     ptr::{SimdConstPtr, SimdMutPtr},
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 72b597a8083..ae47bb7adf4 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -32,7 +32,6 @@
 #![feature(restricted_std)]
 #![feature(rustc_attrs)]
 #![feature(min_specialization)]
-#![feature(strict_provenance)]
 #![recursion_limit = "256"]
 #![allow(internal_features)]
 #![deny(ffi_unwind_calls)]
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 675140ff18f..8a0d2a7f5cf 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2618,7 +2618,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// # Platform-specific behavior
 ///
 /// This function currently corresponds to the `opendir` function on Unix
-/// and the `FindFirstFile` function on Windows. Advancing the iterator
+/// and the `FindFirstFileEx` function on Windows. Advancing the iterator
 /// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows.
 /// Note that, this [may change in the future][changes].
 ///
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 3ab65238368..8c1a3c76829 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -279,6 +279,8 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(strict_provenance))]
+#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 #![feature(alloc_error_handler)]
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
@@ -336,7 +338,6 @@
 #![feature(error_iter)]
 #![feature(exact_size_is_empty)]
 #![feature(exclusive_wrapper)]
-#![feature(exposed_provenance)]
 #![feature(extend_one)]
 #![feature(float_gamma)]
 #![feature(float_minimum_maximum)]
@@ -362,7 +363,6 @@
 #![feature(slice_range)]
 #![feature(std_internals)]
 #![feature(str_internals)]
-#![feature(strict_provenance)]
 #![feature(strict_provenance_atomic_ptr)]
 #![feature(ub_checks)]
 // tidy-alphabetical-end
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index 9c2e4500da0..192c95fd203 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2337,7 +2337,9 @@ Windows.Win32.Storage.FileSystem.FileStandardInfo
 Windows.Win32.Storage.FileSystem.FileStorageInfo
 Windows.Win32.Storage.FileSystem.FileStreamInfo
 Windows.Win32.Storage.FileSystem.FindClose
-Windows.Win32.Storage.FileSystem.FindFirstFileW
+Windows.Win32.Storage.FileSystem.FindExInfoBasic
+Windows.Win32.Storage.FileSystem.FindExSearchNameMatch
+Windows.Win32.Storage.FileSystem.FindFirstFileExW
 Windows.Win32.Storage.FileSystem.FindNextFileW
 Windows.Win32.Storage.FileSystem.FlushFileBuffers
 Windows.Win32.Storage.FileSystem.GetFileAttributesW
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index ab5f8919d7a..52444c2c009 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -26,7 +26,7 @@ windows_targets::link!("kernel32.dll" "system" fn DeviceIoControl(hdevice : HAND
 windows_targets::link!("kernel32.dll" "system" fn DuplicateHandle(hsourceprocesshandle : HANDLE, hsourcehandle : HANDLE, htargetprocesshandle : HANDLE, lptargethandle : *mut HANDLE, dwdesiredaccess : u32, binherithandle : BOOL, dwoptions : DUPLICATE_HANDLE_OPTIONS) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn ExitProcess(uexitcode : u32) -> !);
 windows_targets::link!("kernel32.dll" "system" fn FindClose(hfindfile : HANDLE) -> BOOL);
-windows_targets::link!("kernel32.dll" "system" fn FindFirstFileW(lpfilename : PCWSTR, lpfindfiledata : *mut WIN32_FIND_DATAW) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn FindFirstFileExW(lpfilename : PCWSTR, finfolevelid : FINDEX_INFO_LEVELS, lpfindfiledata : *mut core::ffi::c_void, fsearchop : FINDEX_SEARCH_OPS, lpsearchfilter : *const core::ffi::c_void, dwadditionalflags : FIND_FIRST_EX_FLAGS) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn FindNextFileW(hfindfile : HANDLE, lpfindfiledata : *mut WIN32_FIND_DATAW) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn FlushFileBuffers(hfile : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn FormatMessageW(dwflags : FORMAT_MESSAGE_OPTIONS, lpsource : *const core::ffi::c_void, dwmessageid : u32, dwlanguageid : u32, lpbuffer : PWSTR, nsize : u32, arguments : *const *const i8) -> u32);
@@ -2501,6 +2501,9 @@ pub const FILE_WRITE_ATTRIBUTES: FILE_ACCESS_RIGHTS = 256u32;
 pub const FILE_WRITE_DATA: FILE_ACCESS_RIGHTS = 2u32;
 pub const FILE_WRITE_EA: FILE_ACCESS_RIGHTS = 16u32;
 pub const FILE_WRITE_THROUGH: NTCREATEFILE_CREATE_OPTIONS = 2u32;
+pub type FINDEX_INFO_LEVELS = i32;
+pub type FINDEX_SEARCH_OPS = i32;
+pub type FIND_FIRST_EX_FLAGS = u32;
 pub const FIONBIO: i32 = -2147195266i32;
 #[repr(C)]
 #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
@@ -2565,6 +2568,8 @@ pub const FileRenameInfoEx: FILE_INFO_BY_HANDLE_CLASS = 22i32;
 pub const FileStandardInfo: FILE_INFO_BY_HANDLE_CLASS = 1i32;
 pub const FileStorageInfo: FILE_INFO_BY_HANDLE_CLASS = 16i32;
 pub const FileStreamInfo: FILE_INFO_BY_HANDLE_CLASS = 7i32;
+pub const FindExInfoBasic: FINDEX_INFO_LEVELS = 1i32;
+pub const FindExSearchNameMatch: FINDEX_SEARCH_OPS = 0i32;
 pub type GENERIC_ACCESS_RIGHTS = u32;
 pub const GENERIC_ALL: GENERIC_ACCESS_RIGHTS = 268435456u32;
 pub const GENERIC_EXECUTE: GENERIC_ACCESS_RIGHTS = 536870912u32;
@@ -3307,7 +3312,6 @@ pub struct XSAVE_FORMAT {
     pub XmmRegisters: [M128A; 8],
     pub Reserved4: [u8; 224],
 }
-
 #[cfg(target_arch = "arm")]
 #[repr(C)]
 pub struct WSADATA {
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index aab471e28ea..b237fa481e2 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -114,7 +114,7 @@ impl Iterator for ReadDir {
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         if self.handle.0 == c::INVALID_HANDLE_VALUE {
             // This iterator was initialized with an `INVALID_HANDLE_VALUE` as its handle.
-            // Simply return `None` because this is only the case when `FindFirstFileW` in
+            // Simply return `None` because this is only the case when `FindFirstFileExW` in
             // the construction of this iterator returns `ERROR_FILE_NOT_FOUND` which means
             // no matchhing files can be found.
             return None;
@@ -1047,8 +1047,22 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
     let path = maybe_verbatim(&star)?;
 
     unsafe {
-        let mut wfd = mem::zeroed();
-        let find_handle = c::FindFirstFileW(path.as_ptr(), &mut wfd);
+        let mut wfd: c::WIN32_FIND_DATAW = mem::zeroed();
+        // this is like FindFirstFileW (see https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfileexw),
+        // but with FindExInfoBasic it should skip filling WIN32_FIND_DATAW.cAlternateFileName
+        // (see https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-win32_find_dataw)
+        // (which will be always null string value and currently unused) and should be faster.
+        //
+        // We can pass FIND_FIRST_EX_LARGE_FETCH to dwAdditionalFlags to speed up things more,
+        // but as we don't know user's use profile of this function, lets be conservative.
+        let find_handle = c::FindFirstFileExW(
+            path.as_ptr(),
+            c::FindExInfoBasic,
+            &mut wfd as *mut _ as _,
+            c::FindExSearchNameMatch,
+            ptr::null(),
+            0,
+        );
 
         if find_handle != c::INVALID_HANDLE_VALUE {
             Ok(ReadDir {
@@ -1057,7 +1071,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
                 first: Some(wfd),
             })
         } else {
-            // The status `ERROR_FILE_NOT_FOUND` is returned by the `FindFirstFileW` function
+            // The status `ERROR_FILE_NOT_FOUND` is returned by the `FindFirstFileExW` function
             // if no matching files can be found, but not necessarily that the path to find the
             // files in does not exist.
             //
@@ -1079,7 +1093,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
 
             // Just return the error constructed from the raw OS error if the above is not the case.
             //
-            // Note: `ERROR_PATH_NOT_FOUND` would have been returned by the `FindFirstFileW` function
+            // Note: `ERROR_PATH_NOT_FOUND` would have been returned by the `FindFirstFileExW` function
             // when the path to search in does not exist in the first place.
             Err(Error::from_raw_os_error(last_error.code as i32))
         }
@@ -1220,7 +1234,7 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> {
     opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | reparse.as_flag());
 
     // Attempt to open the file normally.
-    // If that fails with `ERROR_SHARING_VIOLATION` then retry using `FindFirstFileW`.
+    // If that fails with `ERROR_SHARING_VIOLATION` then retry using `FindFirstFileExW`.
     // If the fallback fails for any reason we return the original error.
     match File::open(path, &opts) {
         Ok(file) => file.file_attr(),
@@ -1237,13 +1251,20 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> {
             unsafe {
                 let path = maybe_verbatim(path)?;
 
-                // `FindFirstFileW` accepts wildcard file names.
+                // `FindFirstFileExW` accepts wildcard file names.
                 // Fortunately wildcards are not valid file names and
                 // `ERROR_SHARING_VIOLATION` means the file exists (but is locked)
                 // therefore it's safe to assume the file name given does not
                 // include wildcards.
-                let mut wfd = mem::zeroed();
-                let handle = c::FindFirstFileW(path.as_ptr(), &mut wfd);
+                let mut wfd: c::WIN32_FIND_DATAW = mem::zeroed();
+                let handle = c::FindFirstFileExW(
+                    path.as_ptr(),
+                    c::FindExInfoBasic,
+                    &mut wfd as *mut _ as _,
+                    c::FindExSearchNameMatch,
+                    ptr::null(),
+                    0,
+                );
 
                 if handle == c::INVALID_HANDLE_VALUE {
                     // This can fail if the user does not have read access to the
@@ -1253,7 +1274,7 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> {
                     // We no longer need the find handle.
                     c::FindClose(handle);
 
-                    // `FindFirstFileW` reads the cached file information from the
+                    // `FindFirstFileExW` reads the cached file information from the
                     // directory. The downside is that this metadata may be outdated.
                     let attrs = FileAttr::from(wfd);
                     if reparse == ReparsePoint::Follow && attrs.file_type().is_symlink() {
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 5a476d5843b..79baa5b0b83 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -2,7 +2,6 @@
 #![unstable(feature = "panic_unwind", issue = "32837")]
 #![feature(link_cfg)]
 #![feature(staged_api)]
-#![feature(strict_provenance)]
 #![cfg_attr(not(target_env = "msvc"), feature(libc))]
 #![cfg_attr(
     all(target_family = "wasm", not(target_os = "emscripten")),
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index a555a26367d..15137fbb2b5 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -193,7 +193,8 @@ if '--help' in sys.argv or '-h' in sys.argv:
         if option.value:
             print('\t{:30} {}'.format('--{}=VAL'.format(option.name), option.desc))
         else:
-            print('\t{:30} {}'.format('--enable-{}  OR  --disable-{}'.format(option.name, option.name), option.desc))
+            print('\t--enable-{:25} OR --disable-{}'.format(option.name, option.name))
+            print('\t\t' + option.desc)
     print('')
     print('This configure script is a thin configuration shim over the true')
     print('configuration system, `config.toml`. You can explore the comments')
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 90e6a10d9d6..80ba9f44448 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -1591,9 +1591,15 @@ impl Step for Extended {
             prepare("cargo");
             prepare("rust-std");
             prepare("rust-analysis");
-            prepare("clippy");
-            prepare("rust-analyzer");
-            for tool in &["rust-docs", "miri", "rustc-codegen-cranelift"] {
+
+            for tool in &[
+                "clippy",
+                "rustfmt",
+                "rust-analyzer",
+                "rust-docs",
+                "miri",
+                "rustc-codegen-cranelift",
+            ] {
                 if built_tools.contains(tool) {
                     prepare(tool);
                 }
@@ -1633,6 +1639,8 @@ impl Step for Extended {
                     "rust-analyzer-preview".to_string()
                 } else if name == "clippy" {
                     "clippy-preview".to_string()
+                } else if name == "rustfmt" {
+                    "rustfmt-preview".to_string()
                 } else if name == "miri" {
                     "miri-preview".to_string()
                 } else if name == "rustc-codegen-cranelift" {
@@ -1652,7 +1660,7 @@ impl Step for Extended {
             prepare("cargo");
             prepare("rust-analysis");
             prepare("rust-std");
-            for tool in &["clippy", "rust-analyzer", "rust-docs", "miri"] {
+            for tool in &["clippy", "rustfmt", "rust-analyzer", "rust-docs", "miri"] {
                 if built_tools.contains(tool) {
                     prepare(tool);
                 }
@@ -1770,6 +1778,24 @@ impl Step for Extended {
                     .arg(etc.join("msi/remove-duplicates.xsl"))
                     .run(builder);
             }
+            if built_tools.contains("rustfmt") {
+                command(&heat)
+                    .current_dir(&exe)
+                    .arg("dir")
+                    .arg("rustfmt")
+                    .args(heat_flags)
+                    .arg("-cg")
+                    .arg("RustFmtGroup")
+                    .arg("-dr")
+                    .arg("RustFmt")
+                    .arg("-var")
+                    .arg("var.RustFmtDir")
+                    .arg("-out")
+                    .arg(exe.join("RustFmtGroup.wxs"))
+                    .arg("-t")
+                    .arg(etc.join("msi/remove-duplicates.xsl"))
+                    .run(builder);
+            }
             if built_tools.contains("miri") {
                 command(&heat)
                     .current_dir(&exe)
@@ -1841,6 +1867,9 @@ impl Step for Extended {
                 if built_tools.contains("clippy") {
                     cmd.arg("-dClippyDir=clippy");
                 }
+                if built_tools.contains("rustfmt") {
+                    cmd.arg("-dRustFmtDir=rustfmt");
+                }
                 if built_tools.contains("rust-docs") {
                     cmd.arg("-dDocsDir=rust-docs");
                 }
@@ -1867,6 +1896,9 @@ impl Step for Extended {
             if built_tools.contains("clippy") {
                 candle("ClippyGroup.wxs".as_ref());
             }
+            if built_tools.contains("rustfmt") {
+                candle("RustFmtGroup.wxs".as_ref());
+            }
             if built_tools.contains("miri") {
                 candle("MiriGroup.wxs".as_ref());
             }
@@ -1905,6 +1937,9 @@ impl Step for Extended {
             if built_tools.contains("clippy") {
                 cmd.arg("ClippyGroup.wixobj");
             }
+            if built_tools.contains("rustfmt") {
+                cmd.arg("RustFmtGroup.wixobj");
+            }
             if built_tools.contains("miri") {
                 cmd.arg("MiriGroup.wixobj");
             }
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index c7bcd76cadd..a6dff7fde80 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -283,3 +283,25 @@ impl Step for GenerateCompletions {
         run.builder.ensure(GenerateCompletions);
     }
 }
+
+#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+pub struct UnicodeTableGenerator;
+
+impl Step for UnicodeTableGenerator {
+    type Output = ();
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/unicode-table-generator")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(UnicodeTableGenerator);
+    }
+
+    fn run(self, builder: &Builder<'_>) {
+        let mut cmd = builder.tool_cmd(Tool::UnicodeTableGenerator);
+        cmd.arg(builder.src.join("library/core/src/unicode/unicode_data.rs"));
+        cmd.run(builder);
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index e25b571acba..27acaff8255 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1734,13 +1734,15 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             } else {
                 // We need to properly build cargo using the suitable stage compiler.
 
-                // HACK: currently tool stages are off-by-one compared to compiler stages, i.e. if
-                // you give `tool::Cargo` a stage 1 rustc, it will cause stage 2 rustc to be built
-                // and produce a cargo built with stage 2 rustc. To fix this, we need to chop off
-                // the compiler stage by 1 to align with expected `./x test run-make --stage N`
-                // behavior, i.e. we need to pass `N - 1` compiler stage to cargo. See also Miri
-                // which does a similar hack.
-                let compiler = builder.compiler(builder.top_stage - 1, compiler.host);
+                let compiler = builder.download_rustc().then_some(compiler).unwrap_or_else(||
+                    // HACK: currently tool stages are off-by-one compared to compiler stages, i.e. if
+                    // you give `tool::Cargo` a stage 1 rustc, it will cause stage 2 rustc to be built
+                    // and produce a cargo built with stage 2 rustc. To fix this, we need to chop off
+                    // the compiler stage by 1 to align with expected `./x test run-make --stage N`
+                    // behavior, i.e. we need to pass `N - 1` compiler stage to cargo. See also Miri
+                    // which does a similar hack.
+                    builder.compiler(builder.top_stage - 1, compiler.host));
+
                 builder.ensure(tool::Cargo { compiler, target: compiler.host })
             };
 
@@ -3549,9 +3551,7 @@ impl Step for TestFloatParse {
         let path = self.path.to_str().unwrap();
         let crate_name = self.path.components().last().unwrap().as_os_str().to_str().unwrap();
 
-        if !builder.download_rustc() {
-            builder.ensure(compile::Std::new(compiler, self.host));
-        }
+        builder.ensure(tool::TestFloatParse { host: self.host });
 
         // Run any unit tests in the crate
         let cargo_test = tool::prepare_tool_cargo(
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index f1a10c3296e..50f71e167db 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -360,6 +360,7 @@ bootstrap_tool!(
     CoverageDump, "src/tools/coverage-dump", "coverage-dump";
     RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper";
     WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
+    UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator";
 );
 
 /// These are the submodules that are required for rustbook to work due to
@@ -1096,6 +1097,38 @@ tool_extended!((self, builder),
     Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"];
 );
 
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct TestFloatParse {
+    pub host: TargetSelection,
+}
+
+impl Step for TestFloatParse {
+    type Output = ();
+    const ONLY_HOSTS: bool = true;
+    const DEFAULT: bool = false;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/etc/test-float-parse")
+    }
+
+    fn run(self, builder: &Builder<'_>) {
+        let bootstrap_host = builder.config.build;
+        let compiler = builder.compiler(builder.top_stage, bootstrap_host);
+
+        builder.ensure(ToolBuild {
+            compiler,
+            target: bootstrap_host,
+            tool: "test-float-parse",
+            mode: Mode::ToolStd,
+            path: "src/etc/test-float-parse",
+            source_type: SourceType::InTree,
+            extra_features: Vec::new(),
+            allow_features: "",
+            cargo_args: Vec::new(),
+        });
+    }
+}
+
 impl Builder<'_> {
     /// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for
     /// `host`.
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
new file mode 100644
index 00000000000..c3d0994f164
--- /dev/null
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -0,0 +1,1220 @@
+use std::env;
+use std::ffi::{OsStr, OsString};
+use std::path::{Path, PathBuf};
+
+use super::{Builder, Kind};
+use crate::core::build_steps::tool::SourceType;
+use crate::core::build_steps::{compile, test};
+use crate::core::config::SplitDebuginfo;
+use crate::core::config::flags::Color;
+use crate::utils::helpers::{
+    self, LldThreads, add_link_lib_path, check_cfg_arg, linker_args, linker_flags,
+};
+use crate::{
+    BootstrapCommand, CLang, Compiler, DocTests, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode,
+    TargetSelection, command, prepare_behaviour_dump_dir, t,
+};
+
+/// Represents flag values in `String` form with whitespace delimiter to pass it to the compiler
+/// later.
+///
+/// `-Z crate-attr` flags will be applied recursively on the target code using the
+/// `rustc_parse::parser::Parser`. See `rustc_builtin_macros::cmdline_attrs::inject` for more
+/// information.
+#[derive(Debug, Clone)]
+struct Rustflags(String, TargetSelection);
+
+impl Rustflags {
+    fn new(target: TargetSelection) -> Rustflags {
+        let mut ret = Rustflags(String::new(), target);
+        ret.propagate_cargo_env("RUSTFLAGS");
+        ret
+    }
+
+    /// By default, cargo will pick up on various variables in the environment. However, bootstrap
+    /// reuses those variables to pass additional flags to rustdoc, so by default they get
+    /// overridden. Explicitly add back any previous value in the environment.
+    ///
+    /// `prefix` is usually `RUSTFLAGS` or `RUSTDOCFLAGS`.
+    fn propagate_cargo_env(&mut self, prefix: &str) {
+        // Inherit `RUSTFLAGS` by default ...
+        self.env(prefix);
+
+        // ... and also handle target-specific env RUSTFLAGS if they're configured.
+        let target_specific = format!("CARGO_TARGET_{}_{}", crate::envify(&self.1.triple), prefix);
+        self.env(&target_specific);
+    }
+
+    fn env(&mut self, env: &str) {
+        if let Ok(s) = env::var(env) {
+            for part in s.split(' ') {
+                self.arg(part);
+            }
+        }
+    }
+
+    fn arg(&mut self, arg: &str) -> &mut Self {
+        assert_eq!(arg.split(' ').count(), 1);
+        if !self.0.is_empty() {
+            self.0.push(' ');
+        }
+        self.0.push_str(arg);
+        self
+    }
+}
+
+/// Flags that are passed to the `rustc` shim binary. These flags will only be applied when
+/// compiling host code, i.e. when `--target` is unset.
+#[derive(Debug, Default)]
+struct HostFlags {
+    rustc: Vec<String>,
+}
+
+impl HostFlags {
+    const SEPARATOR: &'static str = " ";
+
+    /// Adds a host rustc flag.
+    fn arg<S: Into<String>>(&mut self, flag: S) {
+        let value = flag.into().trim().to_string();
+        assert!(!value.contains(Self::SEPARATOR));
+        self.rustc.push(value);
+    }
+
+    /// Encodes all the flags into a single string.
+    fn encode(self) -> String {
+        self.rustc.join(Self::SEPARATOR)
+    }
+}
+
+#[derive(Debug)]
+pub struct Cargo {
+    command: BootstrapCommand,
+    compiler: Compiler,
+    target: TargetSelection,
+    rustflags: Rustflags,
+    rustdocflags: Rustflags,
+    hostflags: HostFlags,
+    allow_features: String,
+}
+
+impl Cargo {
+    /// Calls [`Builder::cargo`] and [`Cargo::configure_linker`] to prepare an invocation of `cargo`
+    /// to be run.
+    pub fn new(
+        builder: &Builder<'_>,
+        compiler: Compiler,
+        mode: Mode,
+        source_type: SourceType,
+        target: TargetSelection,
+        cmd_kind: Kind,
+    ) -> Cargo {
+        let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind);
+
+        match cmd_kind {
+            // No need to configure the target linker for these command types,
+            // as they don't invoke rustc at all.
+            Kind::Clean | Kind::Suggest | Kind::Format | Kind::Setup => {}
+            _ => {
+                cargo.configure_linker(builder);
+            }
+        }
+
+        cargo
+    }
+
+    pub fn into_cmd(self) -> BootstrapCommand {
+        self.into()
+    }
+
+    /// Same as [`Cargo::new`] except this one doesn't configure the linker with
+    /// [`Cargo::configure_linker`].
+    pub fn new_for_mir_opt_tests(
+        builder: &Builder<'_>,
+        compiler: Compiler,
+        mode: Mode,
+        source_type: SourceType,
+        target: TargetSelection,
+        cmd_kind: Kind,
+    ) -> Cargo {
+        builder.cargo(compiler, mode, source_type, target, cmd_kind)
+    }
+
+    pub fn rustdocflag(&mut self, arg: &str) -> &mut Cargo {
+        self.rustdocflags.arg(arg);
+        self
+    }
+
+    pub fn rustflag(&mut self, arg: &str) -> &mut Cargo {
+        self.rustflags.arg(arg);
+        self
+    }
+
+    pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Cargo {
+        self.command.arg(arg.as_ref());
+        self
+    }
+
+    pub fn args<I, S>(&mut self, args: I) -> &mut Cargo
+    where
+        I: IntoIterator<Item = S>,
+        S: AsRef<OsStr>,
+    {
+        for arg in args {
+            self.arg(arg.as_ref());
+        }
+        self
+    }
+
+    /// Add an env var to the cargo command instance. Note that `RUSTFLAGS`/`RUSTDOCFLAGS` must go
+    /// through [`Cargo::rustdocflags`] and [`Cargo::rustflags`] because inconsistent `RUSTFLAGS`
+    /// and `RUSTDOCFLAGS` usages will trigger spurious rebuilds.
+    pub fn env(&mut self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Cargo {
+        assert_ne!(key.as_ref(), "RUSTFLAGS");
+        assert_ne!(key.as_ref(), "RUSTDOCFLAGS");
+        self.command.env(key.as_ref(), value.as_ref());
+        self
+    }
+
+    pub fn add_rustc_lib_path(&mut self, builder: &Builder<'_>) {
+        builder.add_rustc_lib_path(self.compiler, &mut self.command);
+    }
+
+    pub fn current_dir(&mut self, dir: &Path) -> &mut Cargo {
+        self.command.current_dir(dir);
+        self
+    }
+
+    /// Adds nightly-only features that this invocation is allowed to use.
+    ///
+    /// By default, all nightly features are allowed. Once this is called, it will be restricted to
+    /// the given set.
+    pub fn allow_features(&mut self, features: &str) -> &mut Cargo {
+        if !self.allow_features.is_empty() {
+            self.allow_features.push(',');
+        }
+        self.allow_features.push_str(features);
+        self
+    }
+
+    fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
+        let target = self.target;
+        let compiler = self.compiler;
+
+        // Dealing with rpath here is a little special, so let's go into some
+        // detail. First off, `-rpath` is a linker option on Unix platforms
+        // which adds to the runtime dynamic loader path when looking for
+        // dynamic libraries. We use this by default on Unix platforms to ensure
+        // that our nightlies behave the same on Windows, that is they work out
+        // of the box. This can be disabled by setting `rpath = false` in `[rust]`
+        // table of `config.toml`
+        //
+        // Ok, so the astute might be wondering "why isn't `-C rpath` used
+        // here?" and that is indeed a good question to ask. This codegen
+        // option is the compiler's current interface to generating an rpath.
+        // Unfortunately it doesn't quite suffice for us. The flag currently
+        // takes no value as an argument, so the compiler calculates what it
+        // should pass to the linker as `-rpath`. This unfortunately is based on
+        // the **compile time** directory structure which when building with
+        // Cargo will be very different than the runtime directory structure.
+        //
+        // All that's a really long winded way of saying that if we use
+        // `-Crpath` then the executables generated have the wrong rpath of
+        // something like `$ORIGIN/deps` when in fact the way we distribute
+        // rustc requires the rpath to be `$ORIGIN/../lib`.
+        //
+        // So, all in all, to set up the correct rpath we pass the linker
+        // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
+        // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
+        // to change a flag in a binary?
+        if builder.config.rpath_enabled(target) && helpers::use_host_linker(target) {
+            let libdir = builder.sysroot_libdir_relative(compiler).to_str().unwrap();
+            let rpath = if target.contains("apple") {
+                // Note that we need to take one extra step on macOS to also pass
+                // `-Wl,-instal_name,@rpath/...` to get things to work right. To
+                // do that we pass a weird flag to the compiler to get it to do
+                // so. Note that this is definitely a hack, and we should likely
+                // flesh out rpath support more fully in the future.
+                self.rustflags.arg("-Zosx-rpath-install-name");
+                Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
+            } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
+                self.rustflags.arg("-Clink-args=-Wl,-z,origin");
+                Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
+            } else {
+                None
+            };
+            if let Some(rpath) = rpath {
+                self.rustflags.arg(&format!("-Clink-args={rpath}"));
+            }
+        }
+
+        for arg in linker_args(builder, compiler.host, LldThreads::Yes) {
+            self.hostflags.arg(&arg);
+        }
+
+        if let Some(target_linker) = builder.linker(target) {
+            let target = crate::envify(&target.triple);
+            self.command.env(format!("CARGO_TARGET_{target}_LINKER"), target_linker);
+        }
+        // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
+        // `linker_args` here.
+        for flag in linker_flags(builder, target, LldThreads::Yes) {
+            self.rustflags.arg(&flag);
+        }
+        for arg in linker_args(builder, target, LldThreads::Yes) {
+            self.rustdocflags.arg(&arg);
+        }
+
+        if !builder.config.dry_run()
+            && builder.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
+        {
+            self.rustflags.arg("-Clink-arg=-gz");
+        }
+
+        // Throughout the build Cargo can execute a number of build scripts
+        // compiling C/C++ code and we need to pass compilers, archivers, flags, etc
+        // obtained previously to those build scripts.
+        // Build scripts use either the `cc` crate or `configure/make` so we pass
+        // the options through environment variables that are fetched and understood by both.
+        //
+        // FIXME: the guard against msvc shouldn't need to be here
+        if target.is_msvc() {
+            if let Some(ref cl) = builder.config.llvm_clang_cl {
+                // FIXME: There is a bug in Clang 18 when building for ARM64:
+                // https://github.com/llvm/llvm-project/pull/81849. This is
+                // fixed in LLVM 19, but can't be backported.
+                if !target.starts_with("aarch64") && !target.starts_with("arm64ec") {
+                    self.command.env("CC", cl).env("CXX", cl);
+                }
+            }
+        } else {
+            let ccache = builder.config.ccache.as_ref();
+            let ccacheify = |s: &Path| {
+                let ccache = match ccache {
+                    Some(ref s) => s,
+                    None => return s.display().to_string(),
+                };
+                // FIXME: the cc-rs crate only recognizes the literal strings
+                // `ccache` and `sccache` when doing caching compilations, so we
+                // mirror that here. It should probably be fixed upstream to
+                // accept a new env var or otherwise work with custom ccache
+                // vars.
+                match &ccache[..] {
+                    "ccache" | "sccache" => format!("{} {}", ccache, s.display()),
+                    _ => s.display().to_string(),
+                }
+            };
+            let triple_underscored = target.triple.replace('-', "_");
+            let cc = ccacheify(&builder.cc(target));
+            self.command.env(format!("CC_{triple_underscored}"), &cc);
+
+            let cflags = builder.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
+            self.command.env(format!("CFLAGS_{triple_underscored}"), &cflags);
+
+            if let Some(ar) = builder.ar(target) {
+                let ranlib = format!("{} s", ar.display());
+                self.command
+                    .env(format!("AR_{triple_underscored}"), ar)
+                    .env(format!("RANLIB_{triple_underscored}"), ranlib);
+            }
+
+            if let Ok(cxx) = builder.cxx(target) {
+                let cxx = ccacheify(&cxx);
+                let cxxflags = builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
+                self.command
+                    .env(format!("CXX_{triple_underscored}"), &cxx)
+                    .env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
+            }
+        }
+
+        self
+    }
+}
+
+impl From<Cargo> for BootstrapCommand {
+    fn from(mut cargo: Cargo) -> BootstrapCommand {
+        let rustflags = &cargo.rustflags.0;
+        if !rustflags.is_empty() {
+            cargo.command.env("RUSTFLAGS", rustflags);
+        }
+
+        let rustdocflags = &cargo.rustdocflags.0;
+        if !rustdocflags.is_empty() {
+            cargo.command.env("RUSTDOCFLAGS", rustdocflags);
+        }
+
+        let encoded_hostflags = cargo.hostflags.encode();
+        if !encoded_hostflags.is_empty() {
+            cargo.command.env("RUSTC_HOST_FLAGS", encoded_hostflags);
+        }
+
+        if !cargo.allow_features.is_empty() {
+            cargo.command.env("RUSTC_ALLOW_FEATURES", cargo.allow_features);
+        }
+        cargo.command
+    }
+}
+
+impl Builder<'_> {
+    /// Like [`Builder::cargo`], but only passes flags that are valid for all commands.
+    pub fn bare_cargo(
+        &self,
+        compiler: Compiler,
+        mode: Mode,
+        target: TargetSelection,
+        cmd_kind: Kind,
+    ) -> BootstrapCommand {
+        let mut cargo = match cmd_kind {
+            Kind::Clippy => {
+                let mut cargo = self.cargo_clippy_cmd(compiler);
+                cargo.arg(cmd_kind.as_str());
+                cargo
+            }
+            Kind::MiriSetup => {
+                let mut cargo = self.cargo_miri_cmd(compiler);
+                cargo.arg("miri").arg("setup");
+                cargo
+            }
+            Kind::MiriTest => {
+                let mut cargo = self.cargo_miri_cmd(compiler);
+                cargo.arg("miri").arg("test");
+                cargo
+            }
+            _ => {
+                let mut cargo = command(&self.initial_cargo);
+                cargo.arg(cmd_kind.as_str());
+                cargo
+            }
+        };
+
+        // Run cargo from the source root so it can find .cargo/config.
+        // This matters when using vendoring and the working directory is outside the repository.
+        cargo.current_dir(&self.src);
+
+        let out_dir = self.stage_out(compiler, mode);
+        cargo.env("CARGO_TARGET_DIR", &out_dir);
+
+        // Found with `rg "init_env_logger\("`. If anyone uses `init_env_logger`
+        // from out of tree it shouldn't matter, since x.py is only used for
+        // building in-tree.
+        let color_logs = ["RUSTDOC_LOG_COLOR", "RUSTC_LOG_COLOR", "RUST_LOG_COLOR"];
+        match self.build.config.color {
+            Color::Always => {
+                cargo.arg("--color=always");
+                for log in &color_logs {
+                    cargo.env(log, "always");
+                }
+            }
+            Color::Never => {
+                cargo.arg("--color=never");
+                for log in &color_logs {
+                    cargo.env(log, "never");
+                }
+            }
+            Color::Auto => {} // nothing to do
+        }
+
+        if cmd_kind != Kind::Install {
+            cargo.arg("--target").arg(target.rustc_target_arg());
+        } else {
+            assert_eq!(target, compiler.host);
+        }
+
+        if self.config.rust_optimize.is_release() &&
+        // cargo bench/install do not accept `--release` and miri doesn't want it
+        !matches!(cmd_kind, Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest)
+        {
+            cargo.arg("--release");
+        }
+
+        // Remove make-related flags to ensure Cargo can correctly set things up
+        cargo.env_remove("MAKEFLAGS");
+        cargo.env_remove("MFLAGS");
+
+        cargo
+    }
+
+    /// This will create a [`BootstrapCommand`] that represents a pending execution of cargo. This
+    /// cargo will be configured to use `compiler` as the actual rustc compiler, its output will be
+    /// scoped by `mode`'s output directory, it will pass the `--target` flag for the specified
+    /// `target`, and will be executing the Cargo command `cmd`. `cmd` can be `miri-cmd` for
+    /// commands to be run with Miri.
+    fn cargo(
+        &self,
+        compiler: Compiler,
+        mode: Mode,
+        source_type: SourceType,
+        target: TargetSelection,
+        cmd_kind: Kind,
+    ) -> Cargo {
+        let mut cargo = self.bare_cargo(compiler, mode, target, cmd_kind);
+        let out_dir = self.stage_out(compiler, mode);
+
+        let mut hostflags = HostFlags::default();
+
+        // Codegen backends are not yet tracked by -Zbinary-dep-depinfo,
+        // so we need to explicitly clear out if they've been updated.
+        for backend in self.codegen_backends(compiler) {
+            self.clear_if_dirty(&out_dir, &backend);
+        }
+
+        if cmd_kind == Kind::Doc {
+            let my_out = match mode {
+                // This is the intended out directory for compiler documentation.
+                Mode::Rustc | Mode::ToolRustc => self.compiler_doc_out(target),
+                Mode::Std => {
+                    if self.config.cmd.json() {
+                        out_dir.join(target).join("json-doc")
+                    } else {
+                        out_dir.join(target).join("doc")
+                    }
+                }
+                _ => panic!("doc mode {mode:?} not expected"),
+            };
+            let rustdoc = self.rustdoc(compiler);
+            self.clear_if_dirty(&my_out, &rustdoc);
+        }
+
+        let profile_var = |name: &str| {
+            let profile = if self.config.rust_optimize.is_release() { "RELEASE" } else { "DEV" };
+            format!("CARGO_PROFILE_{}_{}", profile, name)
+        };
+
+        // See comment in rustc_llvm/build.rs for why this is necessary, largely llvm-config
+        // needs to not accidentally link to libLLVM in stage0/lib.
+        cargo.env("REAL_LIBRARY_PATH_VAR", helpers::dylib_path_var());
+        if let Some(e) = env::var_os(helpers::dylib_path_var()) {
+            cargo.env("REAL_LIBRARY_PATH", e);
+        }
+
+        // Set a flag for `check`/`clippy`/`fix`, so that certain build
+        // scripts can do less work (i.e. not building/requiring LLVM).
+        if matches!(cmd_kind, Kind::Check | Kind::Clippy | Kind::Fix) {
+            // If we've not yet built LLVM, or it's stale, then bust
+            // the rustc_llvm cache. That will always work, even though it
+            // may mean that on the next non-check build we'll need to rebuild
+            // rustc_llvm. But if LLVM is stale, that'll be a tiny amount
+            // of work comparatively, and we'd likely need to rebuild it anyway,
+            // so that's okay.
+            if crate::core::build_steps::llvm::prebuilt_llvm_config(self, target, false)
+                .should_build()
+            {
+                cargo.env("RUST_CHECK", "1");
+            }
+        }
+
+        let stage = if compiler.stage == 0 && self.local_rebuild {
+            // Assume the local-rebuild rustc already has stage1 features.
+            1
+        } else {
+            compiler.stage
+        };
+
+        // We synthetically interpret a stage0 compiler used to build tools as a
+        // "raw" compiler in that it's the exact snapshot we download. Normally
+        // the stage0 build means it uses libraries build by the stage0
+        // compiler, but for tools we just use the precompiled libraries that
+        // we've downloaded
+        let use_snapshot = mode == Mode::ToolBootstrap;
+        assert!(!use_snapshot || stage == 0 || self.local_rebuild);
+
+        let maybe_sysroot = self.sysroot(compiler);
+        let sysroot = if use_snapshot { self.rustc_snapshot_sysroot() } else { &maybe_sysroot };
+        let libdir = self.rustc_libdir(compiler);
+
+        let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8");
+        if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) {
+            println!("using sysroot {sysroot_str}");
+        }
+
+        let mut rustflags = Rustflags::new(target);
+        if stage != 0 {
+            if let Ok(s) = env::var("CARGOFLAGS_NOT_BOOTSTRAP") {
+                cargo.args(s.split_whitespace());
+            }
+            rustflags.env("RUSTFLAGS_NOT_BOOTSTRAP");
+        } else {
+            if let Ok(s) = env::var("CARGOFLAGS_BOOTSTRAP") {
+                cargo.args(s.split_whitespace());
+            }
+            rustflags.env("RUSTFLAGS_BOOTSTRAP");
+            rustflags.arg("--cfg=bootstrap");
+        }
+
+        if cmd_kind == Kind::Clippy {
+            // clippy overwrites sysroot if we pass it to cargo.
+            // Pass it directly to clippy instead.
+            // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
+            // so it has no way of knowing the sysroot.
+            rustflags.arg("--sysroot");
+            rustflags.arg(sysroot_str);
+        }
+
+        let use_new_symbol_mangling = match self.config.rust_new_symbol_mangling {
+            Some(setting) => {
+                // If an explicit setting is given, use that
+                setting
+            }
+            None => {
+                if mode == Mode::Std {
+                    // The standard library defaults to the legacy scheme
+                    false
+                } else {
+                    // The compiler and tools default to the new scheme
+                    true
+                }
+            }
+        };
+
+        // By default, windows-rs depends on a native library that doesn't get copied into the
+        // sysroot. Passing this cfg enables raw-dylib support instead, which makes the native
+        // library unnecessary. This can be removed when windows-rs enables raw-dylib
+        // unconditionally.
+        if let Mode::Rustc | Mode::ToolRustc = mode {
+            rustflags.arg("--cfg=windows_raw_dylib");
+        }
+
+        if use_new_symbol_mangling {
+            rustflags.arg("-Csymbol-mangling-version=v0");
+        } else {
+            rustflags.arg("-Csymbol-mangling-version=legacy");
+        }
+
+        // FIXME: the following components don't build with `-Zrandomize-layout` yet:
+        // - wasm-component-ld, due to the `wast`crate
+        // - rust-analyzer, due to the rowan crate
+        // so we exclude entire categories of steps here due to lack of fine-grained control over
+        // rustflags.
+        if self.config.rust_randomize_layout && mode != Mode::ToolStd && mode != Mode::ToolRustc {
+            rustflags.arg("-Zrandomize-layout");
+        }
+
+        // Enable compile-time checking of `cfg` names, values and Cargo `features`.
+        //
+        // Note: `std`, `alloc` and `core` imports some dependencies by #[path] (like
+        // backtrace, core_simd, std_float, ...), those dependencies have their own
+        // features but cargo isn't involved in the #[path] process and so cannot pass the
+        // complete list of features, so for that reason we don't enable checking of
+        // features for std crates.
+        if mode == Mode::Std {
+            rustflags.arg("--check-cfg=cfg(feature,values(any()))");
+        }
+
+        // Add extra cfg not defined in/by rustc
+        //
+        // Note: Although it would seems that "-Zunstable-options" to `rustflags` is useless as
+        // cargo would implicitly add it, it was discover that sometimes bootstrap only use
+        // `rustflags` without `cargo` making it required.
+        rustflags.arg("-Zunstable-options");
+        for (restricted_mode, name, values) in EXTRA_CHECK_CFGS {
+            if restricted_mode.is_none() || *restricted_mode == Some(mode) {
+                rustflags.arg(&check_cfg_arg(name, *values));
+            }
+        }
+
+        // FIXME(rust-lang/cargo#5754) we shouldn't be using special command arguments
+        // to the host invocation here, but rather Cargo should know what flags to pass rustc
+        // itself.
+        if stage == 0 {
+            hostflags.arg("--cfg=bootstrap");
+        }
+        // Cargo doesn't pass RUSTFLAGS to proc_macros:
+        // https://github.com/rust-lang/cargo/issues/4423
+        // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`.
+        // We also declare that the flag is expected, which we need to do to not
+        // get warnings about it being unexpected.
+        hostflags.arg("-Zunstable-options");
+        hostflags.arg("--check-cfg=cfg(bootstrap)");
+
+        // FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`,
+        // but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See
+        // #71458.
+        let mut rustdocflags = rustflags.clone();
+        rustdocflags.propagate_cargo_env("RUSTDOCFLAGS");
+        if stage == 0 {
+            rustdocflags.env("RUSTDOCFLAGS_BOOTSTRAP");
+        } else {
+            rustdocflags.env("RUSTDOCFLAGS_NOT_BOOTSTRAP");
+        }
+
+        if let Ok(s) = env::var("CARGOFLAGS") {
+            cargo.args(s.split_whitespace());
+        }
+
+        match mode {
+            Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
+            Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
+                // Build proc macros both for the host and the target unless proc-macros are not
+                // supported by the target.
+                if target != compiler.host && cmd_kind != Kind::Check {
+                    let error = command(self.rustc(compiler))
+                        .arg("--target")
+                        .arg(target.rustc_target_arg())
+                        .arg("--print=file-names")
+                        .arg("--crate-type=proc-macro")
+                        .arg("-")
+                        .run_capture(self)
+                        .stderr();
+                    let not_supported = error
+                        .lines()
+                        .any(|line| line.contains("unsupported crate type `proc-macro`"));
+                    if !not_supported {
+                        cargo.arg("-Zdual-proc-macros");
+                        rustflags.arg("-Zdual-proc-macros");
+                    }
+                }
+            }
+        }
+
+        // This tells Cargo (and in turn, rustc) to output more complete
+        // dependency information.  Most importantly for bootstrap, this
+        // includes sysroot artifacts, like libstd, which means that we don't
+        // need to track those in bootstrap (an error prone process!). This
+        // feature is currently unstable as there may be some bugs and such, but
+        // it represents a big improvement in bootstrap's reliability on
+        // rebuilds, so we're using it here.
+        //
+        // For some additional context, see #63470 (the PR originally adding
+        // this), as well as #63012 which is the tracking issue for this
+        // feature on the rustc side.
+        cargo.arg("-Zbinary-dep-depinfo");
+        let allow_features = match mode {
+            Mode::ToolBootstrap | Mode::ToolStd => {
+                // Restrict the allowed features so we don't depend on nightly
+                // accidentally.
+                //
+                // binary-dep-depinfo is used by bootstrap itself for all
+                // compilations.
+                //
+                // Lots of tools depend on proc_macro2 and proc-macro-error.
+                // Those have build scripts which assume nightly features are
+                // available if the `rustc` version is "nighty" or "dev". See
+                // bin/rustc.rs for why that is a problem. Instead of labeling
+                // those features for each individual tool that needs them,
+                // just blanket allow them here.
+                //
+                // If this is ever removed, be sure to add something else in
+                // its place to keep the restrictions in place (or make a way
+                // to unset RUSTC_BOOTSTRAP).
+                "binary-dep-depinfo,proc_macro_span,proc_macro_span_shrink,proc_macro_diagnostic"
+                    .to_string()
+            }
+            Mode::Std | Mode::Rustc | Mode::Codegen | Mode::ToolRustc => String::new(),
+        };
+
+        cargo.arg("-j").arg(self.jobs().to_string());
+
+        // FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005
+        // Force cargo to output binaries with disambiguating hashes in the name
+        let mut metadata = if compiler.stage == 0 {
+            // Treat stage0 like a special channel, whether it's a normal prior-
+            // release rustc or a local rebuild with the same version, so we
+            // never mix these libraries by accident.
+            "bootstrap".to_string()
+        } else {
+            self.config.channel.to_string()
+        };
+        // We want to make sure that none of the dependencies between
+        // std/test/rustc unify with one another. This is done for weird linkage
+        // reasons but the gist of the problem is that if librustc, libtest, and
+        // libstd all depend on libc from crates.io (which they actually do) we
+        // want to make sure they all get distinct versions. Things get really
+        // weird if we try to unify all these dependencies right now, namely
+        // around how many times the library is linked in dynamic libraries and
+        // such. If rustc were a static executable or if we didn't ship dylibs
+        // this wouldn't be a problem, but we do, so it is. This is in general
+        // just here to make sure things build right. If you can remove this and
+        // things still build right, please do!
+        match mode {
+            Mode::Std => metadata.push_str("std"),
+            // When we're building rustc tools, they're built with a search path
+            // that contains things built during the rustc build. For example,
+            // bitflags is built during the rustc build, and is a dependency of
+            // rustdoc as well. We're building rustdoc in a different target
+            // directory, though, which means that Cargo will rebuild the
+            // dependency. When we go on to build rustdoc, we'll look for
+            // bitflags, and find two different copies: one built during the
+            // rustc step and one that we just built. This isn't always a
+            // problem, somehow -- not really clear why -- but we know that this
+            // fixes things.
+            Mode::ToolRustc => metadata.push_str("tool-rustc"),
+            // Same for codegen backends.
+            Mode::Codegen => metadata.push_str("codegen"),
+            _ => {}
+        }
+        cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
+
+        if cmd_kind == Kind::Clippy {
+            rustflags.arg("-Zforce-unstable-if-unmarked");
+        }
+
+        rustflags.arg("-Zmacro-backtrace");
+
+        let want_rustdoc = self.doc_tests != DocTests::No;
+
+        // Clear the output directory if the real rustc we're using has changed;
+        // Cargo cannot detect this as it thinks rustc is bootstrap/debug/rustc.
+        //
+        // Avoid doing this during dry run as that usually means the relevant
+        // compiler is not yet linked/copied properly.
+        //
+        // Only clear out the directory if we're compiling std; otherwise, we
+        // should let Cargo take care of things for us (via depdep info)
+        if !self.config.dry_run() && mode == Mode::Std && cmd_kind == Kind::Build {
+            self.clear_if_dirty(&out_dir, &self.rustc(compiler));
+        }
+
+        let rustdoc_path = match cmd_kind {
+            Kind::Doc | Kind::Test | Kind::MiriTest => self.rustdoc(compiler),
+            _ => PathBuf::from("/path/to/nowhere/rustdoc/not/required"),
+        };
+
+        // Customize the compiler we're running. Specify the compiler to cargo
+        // as our shim and then pass it some various options used to configure
+        // how the actual compiler itself is called.
+        //
+        // These variables are primarily all read by
+        // src/bootstrap/bin/{rustc.rs,rustdoc.rs}
+        cargo
+            .env("RUSTBUILD_NATIVE_DIR", self.native_dir(target))
+            .env("RUSTC_REAL", self.rustc(compiler))
+            .env("RUSTC_STAGE", stage.to_string())
+            .env("RUSTC_SYSROOT", sysroot)
+            .env("RUSTC_LIBDIR", libdir)
+            .env("RUSTDOC", self.bootstrap_out.join("rustdoc"))
+            .env("RUSTDOC_REAL", rustdoc_path)
+            .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir())
+            .env("RUSTC_BREAK_ON_ICE", "1");
+
+        // Set RUSTC_WRAPPER to the bootstrap shim, which switches between beta and in-tree
+        // sysroot depending on whether we're building build scripts.
+        // NOTE: we intentionally use RUSTC_WRAPPER so that we can support clippy - RUSTC is not
+        // respected by clippy-driver; RUSTC_WRAPPER happens earlier, before clippy runs.
+        cargo.env("RUSTC_WRAPPER", self.bootstrap_out.join("rustc"));
+        // NOTE: we also need to set RUSTC so cargo can run `rustc -vV`; apparently that ignores RUSTC_WRAPPER >:(
+        cargo.env("RUSTC", self.bootstrap_out.join("rustc"));
+
+        // Someone might have set some previous rustc wrapper (e.g.
+        // sccache) before bootstrap overrode it. Respect that variable.
+        if let Some(existing_wrapper) = env::var_os("RUSTC_WRAPPER") {
+            cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper);
+        }
+
+        // If this is for `miri-test`, prepare the sysroots.
+        if cmd_kind == Kind::MiriTest {
+            self.ensure(compile::Std::new(compiler, compiler.host));
+            let host_sysroot = self.sysroot(compiler);
+            let miri_sysroot = test::Miri::build_miri_sysroot(self, compiler, target);
+            cargo.env("MIRI_SYSROOT", &miri_sysroot);
+            cargo.env("MIRI_HOST_SYSROOT", &host_sysroot);
+        }
+
+        cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string());
+
+        if let Some(stack_protector) = &self.config.rust_stack_protector {
+            rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
+        }
+
+        if !matches!(cmd_kind, Kind::Build | Kind::Check | Kind::Clippy | Kind::Fix) && want_rustdoc
+        {
+            cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
+        }
+
+        let debuginfo_level = match mode {
+            Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
+            Mode::Std => self.config.rust_debuginfo_level_std,
+            Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => {
+                self.config.rust_debuginfo_level_tools
+            }
+        };
+        cargo.env(profile_var("DEBUG"), debuginfo_level.to_string());
+        if let Some(opt_level) = &self.config.rust_optimize.get_opt_level() {
+            cargo.env(profile_var("OPT_LEVEL"), opt_level);
+        }
+        cargo.env(
+            profile_var("DEBUG_ASSERTIONS"),
+            if mode == Mode::Std {
+                self.config.rust_debug_assertions_std.to_string()
+            } else {
+                self.config.rust_debug_assertions.to_string()
+            },
+        );
+        cargo.env(
+            profile_var("OVERFLOW_CHECKS"),
+            if mode == Mode::Std {
+                self.config.rust_overflow_checks_std.to_string()
+            } else {
+                self.config.rust_overflow_checks.to_string()
+            },
+        );
+
+        match self.config.split_debuginfo(target) {
+            SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"),
+            SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"),
+            SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"),
+        };
+
+        if self.config.cmd.bless() {
+            // Bless `expect!` tests.
+            cargo.env("UPDATE_EXPECT", "1");
+        }
+
+        if !mode.is_tool() {
+            cargo.env("RUSTC_FORCE_UNSTABLE", "1");
+        }
+
+        if let Some(x) = self.crt_static(target) {
+            if x {
+                rustflags.arg("-Ctarget-feature=+crt-static");
+            } else {
+                rustflags.arg("-Ctarget-feature=-crt-static");
+            }
+        }
+
+        if let Some(x) = self.crt_static(compiler.host) {
+            let sign = if x { "+" } else { "-" };
+            hostflags.arg(format!("-Ctarget-feature={sign}crt-static"));
+        }
+
+        if let Some(map_to) = self.build.debuginfo_map_to(GitRepo::Rustc) {
+            let map = format!("{}={}", self.build.src.display(), map_to);
+            cargo.env("RUSTC_DEBUGINFO_MAP", map);
+
+            // `rustc` needs to know the virtual `/rustc/$hash` we're mapping to,
+            // in order to opportunistically reverse it later.
+            cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to);
+        }
+
+        if self.config.rust_remap_debuginfo {
+            let mut env_var = OsString::new();
+            if self.config.vendor {
+                let vendor = self.build.src.join("vendor");
+                env_var.push(vendor);
+                env_var.push("=/rust/deps");
+            } else {
+                let registry_src = t!(home::cargo_home()).join("registry").join("src");
+                for entry in t!(std::fs::read_dir(registry_src)) {
+                    if !env_var.is_empty() {
+                        env_var.push("\t");
+                    }
+                    env_var.push(t!(entry).path());
+                    env_var.push("=/rust/deps");
+                }
+            }
+            cargo.env("RUSTC_CARGO_REGISTRY_SRC_TO_REMAP", env_var);
+        }
+
+        // Enable usage of unstable features
+        cargo.env("RUSTC_BOOTSTRAP", "1");
+
+        if self.config.dump_bootstrap_shims {
+            prepare_behaviour_dump_dir(self.build);
+
+            cargo
+                .env("DUMP_BOOTSTRAP_SHIMS", self.build.out.join("bootstrap-shims-dump"))
+                .env("BUILD_OUT", &self.build.out)
+                .env("CARGO_HOME", t!(home::cargo_home()));
+        };
+
+        self.add_rust_test_threads(&mut cargo);
+
+        // Almost all of the crates that we compile as part of the bootstrap may
+        // have a build script, including the standard library. To compile a
+        // build script, however, it itself needs a standard library! This
+        // introduces a bit of a pickle when we're compiling the standard
+        // library itself.
+        //
+        // To work around this we actually end up using the snapshot compiler
+        // (stage0) for compiling build scripts of the standard library itself.
+        // The stage0 compiler is guaranteed to have a libstd available for use.
+        //
+        // For other crates, however, we know that we've already got a standard
+        // library up and running, so we can use the normal compiler to compile
+        // build scripts in that situation.
+        if mode == Mode::Std {
+            cargo
+                .env("RUSTC_SNAPSHOT", &self.initial_rustc)
+                .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
+        } else {
+            cargo
+                .env("RUSTC_SNAPSHOT", self.rustc(compiler))
+                .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler));
+        }
+
+        // Tools that use compiler libraries may inherit the `-lLLVM` link
+        // requirement, but the `-L` library path is not propagated across
+        // separate Cargo projects. We can add LLVM's library path to the
+        // platform-specific environment variable as a workaround.
+        if mode == Mode::ToolRustc || mode == Mode::Codegen {
+            if let Some(llvm_config) = self.llvm_config(target) {
+                let llvm_libdir =
+                    command(llvm_config).arg("--libdir").run_capture_stdout(self).stdout();
+                add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo);
+            }
+        }
+
+        // Compile everything except libraries and proc macros with the more
+        // efficient initial-exec TLS model. This doesn't work with `dlopen`,
+        // so we can't use it by default in general, but we can use it for tools
+        // and our own internal libraries.
+        if !mode.must_support_dlopen() && !target.triple.starts_with("powerpc-") {
+            cargo.env("RUSTC_TLS_MODEL_INITIAL_EXEC", "1");
+        }
+
+        // Ignore incremental modes except for stage0, since we're
+        // not guaranteeing correctness across builds if the compiler
+        // is changing under your feet.
+        if self.config.incremental && compiler.stage == 0 {
+            cargo.env("CARGO_INCREMENTAL", "1");
+        } else {
+            // Don't rely on any default setting for incr. comp. in Cargo
+            cargo.env("CARGO_INCREMENTAL", "0");
+        }
+
+        if let Some(ref on_fail) = self.config.on_fail {
+            cargo.env("RUSTC_ON_FAIL", on_fail);
+        }
+
+        if self.config.print_step_timings {
+            cargo.env("RUSTC_PRINT_STEP_TIMINGS", "1");
+        }
+
+        if self.config.print_step_rusage {
+            cargo.env("RUSTC_PRINT_STEP_RUSAGE", "1");
+        }
+
+        if self.config.backtrace_on_ice {
+            cargo.env("RUSTC_BACKTRACE_ON_ICE", "1");
+        }
+
+        if self.is_verbose() {
+            // This provides very useful logs especially when debugging build cache-related stuff.
+            cargo.env("CARGO_LOG", "cargo::core::compiler::fingerprint=info");
+        }
+
+        cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());
+
+        // Downstream forks of the Rust compiler might want to use a custom libc to add support for
+        // targets that are not yet available upstream. Adding a patch to replace libc with a
+        // custom one would cause compilation errors though, because Cargo would interpret the
+        // custom libc as part of the workspace, and apply the check-cfg lints on it.
+        //
+        // The libc build script emits check-cfg flags only when this environment variable is set,
+        // so this line allows the use of custom libcs.
+        cargo.env("LIBC_CHECK_CFG", "1");
+
+        if source_type == SourceType::InTree {
+            let mut lint_flags = Vec::new();
+            // When extending this list, add the new lints to the RUSTFLAGS of the
+            // build_bootstrap function of src/bootstrap/bootstrap.py as well as
+            // some code doesn't go through this `rustc` wrapper.
+            lint_flags.push("-Wrust_2018_idioms");
+            lint_flags.push("-Wunused_lifetimes");
+
+            if self.config.deny_warnings {
+                lint_flags.push("-Dwarnings");
+                rustdocflags.arg("-Dwarnings");
+            }
+
+            // This does not use RUSTFLAGS due to caching issues with Cargo.
+            // Clippy is treated as an "in tree" tool, but shares the same
+            // cache as other "submodule" tools. With these options set in
+            // RUSTFLAGS, that causes *every* shared dependency to be rebuilt.
+            // By injecting this into the rustc wrapper, this circumvents
+            // Cargo's fingerprint detection. This is fine because lint flags
+            // are always ignored in dependencies. Eventually this should be
+            // fixed via better support from Cargo.
+            cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" "));
+
+            rustdocflags.arg("-Wrustdoc::invalid_codeblock_attributes");
+        }
+
+        if mode == Mode::Rustc {
+            rustflags.arg("-Wrustc::internal");
+            // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
+            // of the individual lints are satisfied.
+            rustflags.arg("-Wkeyword_idents_2024");
+            rustflags.arg("-Wunsafe_op_in_unsafe_fn");
+        }
+
+        if self.config.rust_frame_pointers {
+            rustflags.arg("-Cforce-frame-pointers=true");
+        }
+
+        // If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc
+        // when compiling the standard library, since this might be linked into the final outputs
+        // produced by rustc. Since this mitigation is only available on Windows, only enable it
+        // for the standard library in case the compiler is run on a non-Windows platform.
+        // This is not needed for stage 0 artifacts because these will only be used for building
+        // the stage 1 compiler.
+        if cfg!(windows)
+            && mode == Mode::Std
+            && self.config.control_flow_guard
+            && compiler.stage >= 1
+        {
+            rustflags.arg("-Ccontrol-flow-guard");
+        }
+
+        // If EHCont Guard is enabled, pass the `-Zehcont-guard` flag to rustc when compiling the
+        // standard library, since this might be linked into the final outputs produced by rustc.
+        // Since this mitigation is only available on Windows, only enable it for the standard
+        // library in case the compiler is run on a non-Windows platform.
+        // This is not needed for stage 0 artifacts because these will only be used for building
+        // the stage 1 compiler.
+        if cfg!(windows) && mode == Mode::Std && self.config.ehcont_guard && compiler.stage >= 1 {
+            rustflags.arg("-Zehcont-guard");
+        }
+
+        // For `cargo doc` invocations, make rustdoc print the Rust version into the docs
+        // This replaces spaces with tabs because RUSTDOCFLAGS does not
+        // support arguments with regular spaces. Hopefully someday Cargo will
+        // have space support.
+        let rust_version = self.rust_version().replace(' ', "\t");
+        rustdocflags.arg("--crate-version").arg(&rust_version);
+
+        // Environment variables *required* throughout the build
+        //
+        // FIXME: should update code to not require this env var
+
+        // The host this new compiler will *run* on.
+        cargo.env("CFG_COMPILER_HOST_TRIPLE", target.triple);
+        // The host this new compiler is being *built* on.
+        cargo.env("CFG_COMPILER_BUILD_TRIPLE", compiler.host.triple);
+
+        // Set this for all builds to make sure doc builds also get it.
+        cargo.env("CFG_RELEASE_CHANNEL", &self.config.channel);
+
+        // This one's a bit tricky. As of the time of this writing the compiler
+        // links to the `winapi` crate on crates.io. This crate provides raw
+        // bindings to Windows system functions, sort of like libc does for
+        // Unix. This crate also, however, provides "import libraries" for the
+        // MinGW targets. There's an import library per dll in the windows
+        // distribution which is what's linked to. These custom import libraries
+        // are used because the winapi crate can reference Windows functions not
+        // present in the MinGW import libraries.
+        //
+        // For example MinGW may ship libdbghelp.a, but it may not have
+        // references to all the functions in the dbghelp dll. Instead the
+        // custom import library for dbghelp in the winapi crates has all this
+        // information.
+        //
+        // Unfortunately for us though the import libraries are linked by
+        // default via `-ldylib=winapi_foo`. That is, they're linked with the
+        // `dylib` type with a `winapi_` prefix (so the winapi ones don't
+        // conflict with the system MinGW ones). This consequently means that
+        // the binaries we ship of things like rustc_codegen_llvm (aka the rustc_codegen_llvm
+        // DLL) when linked against *again*, for example with procedural macros
+        // or plugins, will trigger the propagation logic of `-ldylib`, passing
+        // `-lwinapi_foo` to the linker again. This isn't actually available in
+        // our distribution, however, so the link fails.
+        //
+        // To solve this problem we tell winapi to not use its bundled import
+        // libraries. This means that it will link to the system MinGW import
+        // libraries by default, and the `-ldylib=foo` directives will still get
+        // passed to the final linker, but they'll look like `-lfoo` which can
+        // be resolved because MinGW has the import library. The downside is we
+        // don't get newer functions from Windows, but we don't use any of them
+        // anyway.
+        if !mode.is_tool() {
+            cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1");
+        }
+
+        for _ in 0..self.verbosity {
+            cargo.arg("-v");
+        }
+
+        match (mode, self.config.rust_codegen_units_std, self.config.rust_codegen_units) {
+            (Mode::Std, Some(n), _) | (_, _, Some(n)) => {
+                cargo.env(profile_var("CODEGEN_UNITS"), n.to_string());
+            }
+            _ => {
+                // Don't set anything
+            }
+        }
+
+        if self.config.locked_deps {
+            cargo.arg("--locked");
+        }
+        if self.config.vendor || self.is_sudo {
+            cargo.arg("--frozen");
+        }
+
+        // Try to use a sysroot-relative bindir, in case it was configured absolutely.
+        cargo.env("RUSTC_INSTALL_BINDIR", self.config.bindir_relative());
+
+        cargo.force_coloring_in_ci();
+
+        // When we build Rust dylibs they're all intended for intermediate
+        // usage, so make sure we pass the -Cprefer-dynamic flag instead of
+        // linking all deps statically into the dylib.
+        if matches!(mode, Mode::Std) {
+            rustflags.arg("-Cprefer-dynamic");
+        }
+        if matches!(mode, Mode::Rustc) && !self.link_std_into_rustc_driver(target) {
+            rustflags.arg("-Cprefer-dynamic");
+        }
+
+        cargo.env(
+            "RUSTC_LINK_STD_INTO_RUSTC_DRIVER",
+            if self.link_std_into_rustc_driver(target) { "1" } else { "0" },
+        );
+
+        // When building incrementally we default to a lower ThinLTO import limit
+        // (unless explicitly specified otherwise). This will produce a somewhat
+        // slower code but give way better compile times.
+        {
+            let limit = match self.config.rust_thin_lto_import_instr_limit {
+                Some(limit) => Some(limit),
+                None if self.config.incremental => Some(10),
+                _ => None,
+            };
+
+            if let Some(limit) = limit {
+                if stage == 0
+                    || self.config.default_codegen_backend(target).unwrap_or_default() == "llvm"
+                {
+                    rustflags.arg(&format!("-Cllvm-args=-import-instr-limit={limit}"));
+                }
+            }
+        }
+
+        if matches!(mode, Mode::Std) {
+            if let Some(mir_opt_level) = self.config.rust_validate_mir_opts {
+                rustflags.arg("-Zvalidate-mir");
+                rustflags.arg(&format!("-Zmir-opt-level={mir_opt_level}"));
+            }
+            if self.config.rust_randomize_layout {
+                rustflags.arg("--cfg=randomized_layouts");
+            }
+            // Always enable inlining MIR when building the standard library.
+            // Without this flag, MIR inlining is disabled when incremental compilation is enabled.
+            // That causes some mir-opt tests which inline functions from the standard library to
+            // break when incremental compilation is enabled. So this overrides the "no inlining
+            // during incremental builds" heuristic for the standard library.
+            rustflags.arg("-Zinline-mir");
+
+            // Similarly, we need to keep debug info for functions inlined into other std functions,
+            // even if we're not going to output debuginfo for the crate we're currently building,
+            // so that it'll be available when downstream consumers of std try to use it.
+            rustflags.arg("-Zinline-mir-preserve-debug");
+        }
+
+        if self.config.rustc_parallel
+            && matches!(mode, Mode::ToolRustc | Mode::Rustc | Mode::Codegen)
+        {
+            // keep in sync with `bootstrap/lib.rs:Build::rustc_features`
+            // `cfg` option for rustc, `features` option for cargo, for conditional compilation
+            rustflags.arg("--cfg=parallel_compiler");
+            rustdocflags.arg("--cfg=parallel_compiler");
+        }
+
+        Cargo {
+            command: cargo,
+            compiler,
+            target,
+            rustflags,
+            rustdocflags,
+            hostflags,
+            allow_features,
+        }
+    }
+}
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder/mod.rs
index 15c6f303f94..8f8ab112857 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -1,7 +1,8 @@
+mod cargo;
+
 use std::any::{Any, type_name};
 use std::cell::{Cell, RefCell};
 use std::collections::BTreeSet;
-use std::ffi::{OsStr, OsString};
 use std::fmt::{Debug, Write};
 use std::hash::Hash;
 use std::ops::Deref;
@@ -12,22 +13,17 @@ use std::{env, fs};
 
 use clap::ValueEnum;
 
+pub use self::cargo::Cargo;
 pub use crate::Compiler;
-use crate::core::build_steps::tool::{self, SourceType};
 use crate::core::build_steps::{
-    check, clean, clippy, compile, dist, doc, gcc, install, llvm, run, setup, test, vendor,
+    check, clean, clippy, compile, dist, doc, gcc, install, llvm, run, setup, test, tool, vendor,
 };
-use crate::core::config::flags::{Color, Subcommand};
-use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection};
+use crate::core::config::flags::Subcommand;
+use crate::core::config::{DryRun, TargetSelection};
 use crate::utils::cache::Cache;
 use crate::utils::exec::{BootstrapCommand, command};
-use crate::utils::helpers::{
-    self, LldThreads, add_dylib_path, add_link_lib_path, check_cfg_arg, exe, libdir, linker_args,
-    linker_flags, t,
-};
-use crate::{
-    Build, CLang, Crate, DocTests, EXTRA_CHECK_CFGS, GitRepo, Mode, prepare_behaviour_dump_dir,
-};
+use crate::utils::helpers::{self, LldThreads, add_dylib_path, exe, libdir, linker_args, t};
+use crate::{Build, Crate};
 
 #[cfg(test)]
 mod tests;
@@ -1010,6 +1006,7 @@ impl<'a> Builder<'a> {
                 run::GenerateCopyright,
                 run::GenerateWindowsSys,
                 run::GenerateCompletions,
+                run::UnicodeTableGenerator,
             ),
             Kind::Setup => {
                 describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor)
@@ -1409,870 +1406,6 @@ impl<'a> Builder<'a> {
         None
     }
 
-    /// Like `cargo`, but only passes flags that are valid for all commands.
-    pub fn bare_cargo(
-        &self,
-        compiler: Compiler,
-        mode: Mode,
-        target: TargetSelection,
-        cmd_kind: Kind,
-    ) -> BootstrapCommand {
-        let mut cargo = match cmd_kind {
-            Kind::Clippy => {
-                let mut cargo = self.cargo_clippy_cmd(compiler);
-                cargo.arg(cmd_kind.as_str());
-                cargo
-            }
-            Kind::MiriSetup => {
-                let mut cargo = self.cargo_miri_cmd(compiler);
-                cargo.arg("miri").arg("setup");
-                cargo
-            }
-            Kind::MiriTest => {
-                let mut cargo = self.cargo_miri_cmd(compiler);
-                cargo.arg("miri").arg("test");
-                cargo
-            }
-            _ => {
-                let mut cargo = command(&self.initial_cargo);
-                cargo.arg(cmd_kind.as_str());
-                cargo
-            }
-        };
-
-        // Run cargo from the source root so it can find .cargo/config.
-        // This matters when using vendoring and the working directory is outside the repository.
-        cargo.current_dir(&self.src);
-
-        let out_dir = self.stage_out(compiler, mode);
-        cargo.env("CARGO_TARGET_DIR", &out_dir);
-
-        // Found with `rg "init_env_logger\("`. If anyone uses `init_env_logger`
-        // from out of tree it shouldn't matter, since x.py is only used for
-        // building in-tree.
-        let color_logs = ["RUSTDOC_LOG_COLOR", "RUSTC_LOG_COLOR", "RUST_LOG_COLOR"];
-        match self.build.config.color {
-            Color::Always => {
-                cargo.arg("--color=always");
-                for log in &color_logs {
-                    cargo.env(log, "always");
-                }
-            }
-            Color::Never => {
-                cargo.arg("--color=never");
-                for log in &color_logs {
-                    cargo.env(log, "never");
-                }
-            }
-            Color::Auto => {} // nothing to do
-        }
-
-        if cmd_kind != Kind::Install {
-            cargo.arg("--target").arg(target.rustc_target_arg());
-        } else {
-            assert_eq!(target, compiler.host);
-        }
-
-        if self.config.rust_optimize.is_release() &&
-        // cargo bench/install do not accept `--release` and miri doesn't want it
-        !matches!(cmd_kind, Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest)
-        {
-            cargo.arg("--release");
-        }
-
-        // Remove make-related flags to ensure Cargo can correctly set things up
-        cargo.env_remove("MAKEFLAGS");
-        cargo.env_remove("MFLAGS");
-
-        cargo
-    }
-
-    /// This will create a `Command` that represents a pending execution of
-    /// Cargo. This cargo will be configured to use `compiler` as the actual
-    /// rustc compiler, its output will be scoped by `mode`'s output directory,
-    /// it will pass the `--target` flag for the specified `target`, and will be
-    /// executing the Cargo command `cmd`. `cmd` can be `miri-cmd` for commands
-    /// to be run with Miri.
-    fn cargo(
-        &self,
-        compiler: Compiler,
-        mode: Mode,
-        source_type: SourceType,
-        target: TargetSelection,
-        cmd_kind: Kind,
-    ) -> Cargo {
-        let mut cargo = self.bare_cargo(compiler, mode, target, cmd_kind);
-        let out_dir = self.stage_out(compiler, mode);
-
-        let mut hostflags = HostFlags::default();
-
-        // Codegen backends are not yet tracked by -Zbinary-dep-depinfo,
-        // so we need to explicitly clear out if they've been updated.
-        for backend in self.codegen_backends(compiler) {
-            self.clear_if_dirty(&out_dir, &backend);
-        }
-
-        if cmd_kind == Kind::Doc {
-            let my_out = match mode {
-                // This is the intended out directory for compiler documentation.
-                Mode::Rustc | Mode::ToolRustc => self.compiler_doc_out(target),
-                Mode::Std => {
-                    if self.config.cmd.json() {
-                        out_dir.join(target).join("json-doc")
-                    } else {
-                        out_dir.join(target).join("doc")
-                    }
-                }
-                _ => panic!("doc mode {mode:?} not expected"),
-            };
-            let rustdoc = self.rustdoc(compiler);
-            self.clear_if_dirty(&my_out, &rustdoc);
-        }
-
-        let profile_var = |name: &str| {
-            let profile = if self.config.rust_optimize.is_release() { "RELEASE" } else { "DEV" };
-            format!("CARGO_PROFILE_{}_{}", profile, name)
-        };
-
-        // See comment in rustc_llvm/build.rs for why this is necessary, largely llvm-config
-        // needs to not accidentally link to libLLVM in stage0/lib.
-        cargo.env("REAL_LIBRARY_PATH_VAR", helpers::dylib_path_var());
-        if let Some(e) = env::var_os(helpers::dylib_path_var()) {
-            cargo.env("REAL_LIBRARY_PATH", e);
-        }
-
-        // Set a flag for `check`/`clippy`/`fix`, so that certain build
-        // scripts can do less work (i.e. not building/requiring LLVM).
-        if matches!(cmd_kind, Kind::Check | Kind::Clippy | Kind::Fix) {
-            // If we've not yet built LLVM, or it's stale, then bust
-            // the rustc_llvm cache. That will always work, even though it
-            // may mean that on the next non-check build we'll need to rebuild
-            // rustc_llvm. But if LLVM is stale, that'll be a tiny amount
-            // of work comparatively, and we'd likely need to rebuild it anyway,
-            // so that's okay.
-            if crate::core::build_steps::llvm::prebuilt_llvm_config(self, target, false)
-                .should_build()
-            {
-                cargo.env("RUST_CHECK", "1");
-            }
-        }
-
-        let stage = if compiler.stage == 0 && self.local_rebuild {
-            // Assume the local-rebuild rustc already has stage1 features.
-            1
-        } else {
-            compiler.stage
-        };
-
-        // We synthetically interpret a stage0 compiler used to build tools as a
-        // "raw" compiler in that it's the exact snapshot we download. Normally
-        // the stage0 build means it uses libraries build by the stage0
-        // compiler, but for tools we just use the precompiled libraries that
-        // we've downloaded
-        let use_snapshot = mode == Mode::ToolBootstrap;
-        assert!(!use_snapshot || stage == 0 || self.local_rebuild);
-
-        let maybe_sysroot = self.sysroot(compiler);
-        let sysroot = if use_snapshot { self.rustc_snapshot_sysroot() } else { &maybe_sysroot };
-        let libdir = self.rustc_libdir(compiler);
-
-        let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8");
-        if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) {
-            println!("using sysroot {sysroot_str}");
-        }
-
-        let mut rustflags = Rustflags::new(target);
-        if stage != 0 {
-            if let Ok(s) = env::var("CARGOFLAGS_NOT_BOOTSTRAP") {
-                cargo.args(s.split_whitespace());
-            }
-            rustflags.env("RUSTFLAGS_NOT_BOOTSTRAP");
-        } else {
-            if let Ok(s) = env::var("CARGOFLAGS_BOOTSTRAP") {
-                cargo.args(s.split_whitespace());
-            }
-            rustflags.env("RUSTFLAGS_BOOTSTRAP");
-            rustflags.arg("--cfg=bootstrap");
-        }
-
-        if cmd_kind == Kind::Clippy {
-            // clippy overwrites sysroot if we pass it to cargo.
-            // Pass it directly to clippy instead.
-            // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
-            // so it has no way of knowing the sysroot.
-            rustflags.arg("--sysroot");
-            rustflags.arg(sysroot_str);
-        }
-
-        let use_new_symbol_mangling = match self.config.rust_new_symbol_mangling {
-            Some(setting) => {
-                // If an explicit setting is given, use that
-                setting
-            }
-            None => {
-                if mode == Mode::Std {
-                    // The standard library defaults to the legacy scheme
-                    false
-                } else {
-                    // The compiler and tools default to the new scheme
-                    true
-                }
-            }
-        };
-
-        // By default, windows-rs depends on a native library that doesn't get copied into the
-        // sysroot. Passing this cfg enables raw-dylib support instead, which makes the native
-        // library unnecessary. This can be removed when windows-rs enables raw-dylib
-        // unconditionally.
-        if let Mode::Rustc | Mode::ToolRustc = mode {
-            rustflags.arg("--cfg=windows_raw_dylib");
-        }
-
-        if use_new_symbol_mangling {
-            rustflags.arg("-Csymbol-mangling-version=v0");
-        } else {
-            rustflags.arg("-Csymbol-mangling-version=legacy");
-        }
-
-        // FIXME: the following components don't build with `-Zrandomize-layout` yet:
-        // - wasm-component-ld, due to the `wast`crate
-        // - rust-analyzer, due to the rowan crate
-        // so we exclude entire categories of steps here due to lack of fine-grained control over
-        // rustflags.
-        if self.config.rust_randomize_layout && mode != Mode::ToolStd && mode != Mode::ToolRustc {
-            rustflags.arg("-Zrandomize-layout");
-        }
-
-        // Enable compile-time checking of `cfg` names, values and Cargo `features`.
-        //
-        // Note: `std`, `alloc` and `core` imports some dependencies by #[path] (like
-        // backtrace, core_simd, std_float, ...), those dependencies have their own
-        // features but cargo isn't involved in the #[path] process and so cannot pass the
-        // complete list of features, so for that reason we don't enable checking of
-        // features for std crates.
-        if mode == Mode::Std {
-            rustflags.arg("--check-cfg=cfg(feature,values(any()))");
-        }
-
-        // Add extra cfg not defined in/by rustc
-        //
-        // Note: Although it would seems that "-Zunstable-options" to `rustflags` is useless as
-        // cargo would implicitly add it, it was discover that sometimes bootstrap only use
-        // `rustflags` without `cargo` making it required.
-        rustflags.arg("-Zunstable-options");
-        for (restricted_mode, name, values) in EXTRA_CHECK_CFGS {
-            if restricted_mode.is_none() || *restricted_mode == Some(mode) {
-                rustflags.arg(&check_cfg_arg(name, *values));
-            }
-        }
-
-        // FIXME(rust-lang/cargo#5754) we shouldn't be using special command arguments
-        // to the host invocation here, but rather Cargo should know what flags to pass rustc
-        // itself.
-        if stage == 0 {
-            hostflags.arg("--cfg=bootstrap");
-        }
-        // Cargo doesn't pass RUSTFLAGS to proc_macros:
-        // https://github.com/rust-lang/cargo/issues/4423
-        // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`.
-        // We also declare that the flag is expected, which we need to do to not
-        // get warnings about it being unexpected.
-        hostflags.arg("-Zunstable-options");
-        hostflags.arg("--check-cfg=cfg(bootstrap)");
-
-        // FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`,
-        // but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See
-        // #71458.
-        let mut rustdocflags = rustflags.clone();
-        rustdocflags.propagate_cargo_env("RUSTDOCFLAGS");
-        if stage == 0 {
-            rustdocflags.env("RUSTDOCFLAGS_BOOTSTRAP");
-        } else {
-            rustdocflags.env("RUSTDOCFLAGS_NOT_BOOTSTRAP");
-        }
-
-        if let Ok(s) = env::var("CARGOFLAGS") {
-            cargo.args(s.split_whitespace());
-        }
-
-        match mode {
-            Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
-            Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
-                // Build proc macros both for the host and the target unless proc-macros are not
-                // supported by the target.
-                if target != compiler.host && cmd_kind != Kind::Check {
-                    let error = command(self.rustc(compiler))
-                        .arg("--target")
-                        .arg(target.rustc_target_arg())
-                        .arg("--print=file-names")
-                        .arg("--crate-type=proc-macro")
-                        .arg("-")
-                        .run_capture(self)
-                        .stderr();
-                    let not_supported = error
-                        .lines()
-                        .any(|line| line.contains("unsupported crate type `proc-macro`"));
-                    if !not_supported {
-                        cargo.arg("-Zdual-proc-macros");
-                        rustflags.arg("-Zdual-proc-macros");
-                    }
-                }
-            }
-        }
-
-        // This tells Cargo (and in turn, rustc) to output more complete
-        // dependency information.  Most importantly for bootstrap, this
-        // includes sysroot artifacts, like libstd, which means that we don't
-        // need to track those in bootstrap (an error prone process!). This
-        // feature is currently unstable as there may be some bugs and such, but
-        // it represents a big improvement in bootstrap's reliability on
-        // rebuilds, so we're using it here.
-        //
-        // For some additional context, see #63470 (the PR originally adding
-        // this), as well as #63012 which is the tracking issue for this
-        // feature on the rustc side.
-        cargo.arg("-Zbinary-dep-depinfo");
-        let allow_features = match mode {
-            Mode::ToolBootstrap | Mode::ToolStd => {
-                // Restrict the allowed features so we don't depend on nightly
-                // accidentally.
-                //
-                // binary-dep-depinfo is used by bootstrap itself for all
-                // compilations.
-                //
-                // Lots of tools depend on proc_macro2 and proc-macro-error.
-                // Those have build scripts which assume nightly features are
-                // available if the `rustc` version is "nighty" or "dev". See
-                // bin/rustc.rs for why that is a problem. Instead of labeling
-                // those features for each individual tool that needs them,
-                // just blanket allow them here.
-                //
-                // If this is ever removed, be sure to add something else in
-                // its place to keep the restrictions in place (or make a way
-                // to unset RUSTC_BOOTSTRAP).
-                "binary-dep-depinfo,proc_macro_span,proc_macro_span_shrink,proc_macro_diagnostic"
-                    .to_string()
-            }
-            Mode::Std | Mode::Rustc | Mode::Codegen | Mode::ToolRustc => String::new(),
-        };
-
-        cargo.arg("-j").arg(self.jobs().to_string());
-
-        // FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005
-        // Force cargo to output binaries with disambiguating hashes in the name
-        let mut metadata = if compiler.stage == 0 {
-            // Treat stage0 like a special channel, whether it's a normal prior-
-            // release rustc or a local rebuild with the same version, so we
-            // never mix these libraries by accident.
-            "bootstrap".to_string()
-        } else {
-            self.config.channel.to_string()
-        };
-        // We want to make sure that none of the dependencies between
-        // std/test/rustc unify with one another. This is done for weird linkage
-        // reasons but the gist of the problem is that if librustc, libtest, and
-        // libstd all depend on libc from crates.io (which they actually do) we
-        // want to make sure they all get distinct versions. Things get really
-        // weird if we try to unify all these dependencies right now, namely
-        // around how many times the library is linked in dynamic libraries and
-        // such. If rustc were a static executable or if we didn't ship dylibs
-        // this wouldn't be a problem, but we do, so it is. This is in general
-        // just here to make sure things build right. If you can remove this and
-        // things still build right, please do!
-        match mode {
-            Mode::Std => metadata.push_str("std"),
-            // When we're building rustc tools, they're built with a search path
-            // that contains things built during the rustc build. For example,
-            // bitflags is built during the rustc build, and is a dependency of
-            // rustdoc as well. We're building rustdoc in a different target
-            // directory, though, which means that Cargo will rebuild the
-            // dependency. When we go on to build rustdoc, we'll look for
-            // bitflags, and find two different copies: one built during the
-            // rustc step and one that we just built. This isn't always a
-            // problem, somehow -- not really clear why -- but we know that this
-            // fixes things.
-            Mode::ToolRustc => metadata.push_str("tool-rustc"),
-            // Same for codegen backends.
-            Mode::Codegen => metadata.push_str("codegen"),
-            _ => {}
-        }
-        cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
-
-        if cmd_kind == Kind::Clippy {
-            rustflags.arg("-Zforce-unstable-if-unmarked");
-        }
-
-        rustflags.arg("-Zmacro-backtrace");
-
-        let want_rustdoc = self.doc_tests != DocTests::No;
-
-        // Clear the output directory if the real rustc we're using has changed;
-        // Cargo cannot detect this as it thinks rustc is bootstrap/debug/rustc.
-        //
-        // Avoid doing this during dry run as that usually means the relevant
-        // compiler is not yet linked/copied properly.
-        //
-        // Only clear out the directory if we're compiling std; otherwise, we
-        // should let Cargo take care of things for us (via depdep info)
-        if !self.config.dry_run() && mode == Mode::Std && cmd_kind == Kind::Build {
-            self.clear_if_dirty(&out_dir, &self.rustc(compiler));
-        }
-
-        let rustdoc_path = match cmd_kind {
-            Kind::Doc | Kind::Test | Kind::MiriTest => self.rustdoc(compiler),
-            _ => PathBuf::from("/path/to/nowhere/rustdoc/not/required"),
-        };
-
-        // Customize the compiler we're running. Specify the compiler to cargo
-        // as our shim and then pass it some various options used to configure
-        // how the actual compiler itself is called.
-        //
-        // These variables are primarily all read by
-        // src/bootstrap/bin/{rustc.rs,rustdoc.rs}
-        cargo
-            .env("RUSTBUILD_NATIVE_DIR", self.native_dir(target))
-            .env("RUSTC_REAL", self.rustc(compiler))
-            .env("RUSTC_STAGE", stage.to_string())
-            .env("RUSTC_SYSROOT", sysroot)
-            .env("RUSTC_LIBDIR", libdir)
-            .env("RUSTDOC", self.bootstrap_out.join("rustdoc"))
-            .env("RUSTDOC_REAL", rustdoc_path)
-            .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir())
-            .env("RUSTC_BREAK_ON_ICE", "1");
-
-        // Set RUSTC_WRAPPER to the bootstrap shim, which switches between beta and in-tree
-        // sysroot depending on whether we're building build scripts.
-        // NOTE: we intentionally use RUSTC_WRAPPER so that we can support clippy - RUSTC is not
-        // respected by clippy-driver; RUSTC_WRAPPER happens earlier, before clippy runs.
-        cargo.env("RUSTC_WRAPPER", self.bootstrap_out.join("rustc"));
-        // NOTE: we also need to set RUSTC so cargo can run `rustc -vV`; apparently that ignores RUSTC_WRAPPER >:(
-        cargo.env("RUSTC", self.bootstrap_out.join("rustc"));
-
-        // Someone might have set some previous rustc wrapper (e.g.
-        // sccache) before bootstrap overrode it. Respect that variable.
-        if let Some(existing_wrapper) = env::var_os("RUSTC_WRAPPER") {
-            cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper);
-        }
-
-        // If this is for `miri-test`, prepare the sysroots.
-        if cmd_kind == Kind::MiriTest {
-            self.ensure(compile::Std::new(compiler, compiler.host));
-            let host_sysroot = self.sysroot(compiler);
-            let miri_sysroot = test::Miri::build_miri_sysroot(self, compiler, target);
-            cargo.env("MIRI_SYSROOT", &miri_sysroot);
-            cargo.env("MIRI_HOST_SYSROOT", &host_sysroot);
-        }
-
-        cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string());
-
-        if let Some(stack_protector) = &self.config.rust_stack_protector {
-            rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
-        }
-
-        if !matches!(cmd_kind, Kind::Build | Kind::Check | Kind::Clippy | Kind::Fix) && want_rustdoc
-        {
-            cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
-        }
-
-        let debuginfo_level = match mode {
-            Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
-            Mode::Std => self.config.rust_debuginfo_level_std,
-            Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => {
-                self.config.rust_debuginfo_level_tools
-            }
-        };
-        cargo.env(profile_var("DEBUG"), debuginfo_level.to_string());
-        if let Some(opt_level) = &self.config.rust_optimize.get_opt_level() {
-            cargo.env(profile_var("OPT_LEVEL"), opt_level);
-        }
-        cargo.env(
-            profile_var("DEBUG_ASSERTIONS"),
-            if mode == Mode::Std {
-                self.config.rust_debug_assertions_std.to_string()
-            } else {
-                self.config.rust_debug_assertions.to_string()
-            },
-        );
-        cargo.env(
-            profile_var("OVERFLOW_CHECKS"),
-            if mode == Mode::Std {
-                self.config.rust_overflow_checks_std.to_string()
-            } else {
-                self.config.rust_overflow_checks.to_string()
-            },
-        );
-
-        match self.config.split_debuginfo(target) {
-            SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"),
-            SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"),
-            SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"),
-        };
-
-        if self.config.cmd.bless() {
-            // Bless `expect!` tests.
-            cargo.env("UPDATE_EXPECT", "1");
-        }
-
-        if !mode.is_tool() {
-            cargo.env("RUSTC_FORCE_UNSTABLE", "1");
-        }
-
-        if let Some(x) = self.crt_static(target) {
-            if x {
-                rustflags.arg("-Ctarget-feature=+crt-static");
-            } else {
-                rustflags.arg("-Ctarget-feature=-crt-static");
-            }
-        }
-
-        if let Some(x) = self.crt_static(compiler.host) {
-            let sign = if x { "+" } else { "-" };
-            hostflags.arg(format!("-Ctarget-feature={sign}crt-static"));
-        }
-
-        if let Some(map_to) = self.build.debuginfo_map_to(GitRepo::Rustc) {
-            let map = format!("{}={}", self.build.src.display(), map_to);
-            cargo.env("RUSTC_DEBUGINFO_MAP", map);
-
-            // `rustc` needs to know the virtual `/rustc/$hash` we're mapping to,
-            // in order to opportunistically reverse it later.
-            cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to);
-        }
-
-        if self.config.rust_remap_debuginfo {
-            let mut env_var = OsString::new();
-            if self.config.vendor {
-                let vendor = self.build.src.join("vendor");
-                env_var.push(vendor);
-                env_var.push("=/rust/deps");
-            } else {
-                let registry_src = t!(home::cargo_home()).join("registry").join("src");
-                for entry in t!(std::fs::read_dir(registry_src)) {
-                    if !env_var.is_empty() {
-                        env_var.push("\t");
-                    }
-                    env_var.push(t!(entry).path());
-                    env_var.push("=/rust/deps");
-                }
-            }
-            cargo.env("RUSTC_CARGO_REGISTRY_SRC_TO_REMAP", env_var);
-        }
-
-        // Enable usage of unstable features
-        cargo.env("RUSTC_BOOTSTRAP", "1");
-
-        if self.config.dump_bootstrap_shims {
-            prepare_behaviour_dump_dir(self.build);
-
-            cargo
-                .env("DUMP_BOOTSTRAP_SHIMS", self.build.out.join("bootstrap-shims-dump"))
-                .env("BUILD_OUT", &self.build.out)
-                .env("CARGO_HOME", t!(home::cargo_home()));
-        };
-
-        self.add_rust_test_threads(&mut cargo);
-
-        // Almost all of the crates that we compile as part of the bootstrap may
-        // have a build script, including the standard library. To compile a
-        // build script, however, it itself needs a standard library! This
-        // introduces a bit of a pickle when we're compiling the standard
-        // library itself.
-        //
-        // To work around this we actually end up using the snapshot compiler
-        // (stage0) for compiling build scripts of the standard library itself.
-        // The stage0 compiler is guaranteed to have a libstd available for use.
-        //
-        // For other crates, however, we know that we've already got a standard
-        // library up and running, so we can use the normal compiler to compile
-        // build scripts in that situation.
-        if mode == Mode::Std {
-            cargo
-                .env("RUSTC_SNAPSHOT", &self.initial_rustc)
-                .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
-        } else {
-            cargo
-                .env("RUSTC_SNAPSHOT", self.rustc(compiler))
-                .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler));
-        }
-
-        // Tools that use compiler libraries may inherit the `-lLLVM` link
-        // requirement, but the `-L` library path is not propagated across
-        // separate Cargo projects. We can add LLVM's library path to the
-        // platform-specific environment variable as a workaround.
-        if mode == Mode::ToolRustc || mode == Mode::Codegen {
-            if let Some(llvm_config) = self.llvm_config(target) {
-                let llvm_libdir =
-                    command(llvm_config).arg("--libdir").run_capture_stdout(self).stdout();
-                add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo);
-            }
-        }
-
-        // Compile everything except libraries and proc macros with the more
-        // efficient initial-exec TLS model. This doesn't work with `dlopen`,
-        // so we can't use it by default in general, but we can use it for tools
-        // and our own internal libraries.
-        if !mode.must_support_dlopen() && !target.triple.starts_with("powerpc-") {
-            cargo.env("RUSTC_TLS_MODEL_INITIAL_EXEC", "1");
-        }
-
-        // Ignore incremental modes except for stage0, since we're
-        // not guaranteeing correctness across builds if the compiler
-        // is changing under your feet.
-        if self.config.incremental && compiler.stage == 0 {
-            cargo.env("CARGO_INCREMENTAL", "1");
-        } else {
-            // Don't rely on any default setting for incr. comp. in Cargo
-            cargo.env("CARGO_INCREMENTAL", "0");
-        }
-
-        if let Some(ref on_fail) = self.config.on_fail {
-            cargo.env("RUSTC_ON_FAIL", on_fail);
-        }
-
-        if self.config.print_step_timings {
-            cargo.env("RUSTC_PRINT_STEP_TIMINGS", "1");
-        }
-
-        if self.config.print_step_rusage {
-            cargo.env("RUSTC_PRINT_STEP_RUSAGE", "1");
-        }
-
-        if self.config.backtrace_on_ice {
-            cargo.env("RUSTC_BACKTRACE_ON_ICE", "1");
-        }
-
-        if self.is_verbose() {
-            // This provides very useful logs especially when debugging build cache-related stuff.
-            cargo.env("CARGO_LOG", "cargo::core::compiler::fingerprint=info");
-        }
-
-        cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());
-
-        // Downstream forks of the Rust compiler might want to use a custom libc to add support for
-        // targets that are not yet available upstream. Adding a patch to replace libc with a
-        // custom one would cause compilation errors though, because Cargo would interpret the
-        // custom libc as part of the workspace, and apply the check-cfg lints on it.
-        //
-        // The libc build script emits check-cfg flags only when this environment variable is set,
-        // so this line allows the use of custom libcs.
-        cargo.env("LIBC_CHECK_CFG", "1");
-
-        if source_type == SourceType::InTree {
-            let mut lint_flags = Vec::new();
-            // When extending this list, add the new lints to the RUSTFLAGS of the
-            // build_bootstrap function of src/bootstrap/bootstrap.py as well as
-            // some code doesn't go through this `rustc` wrapper.
-            lint_flags.push("-Wrust_2018_idioms");
-            lint_flags.push("-Wunused_lifetimes");
-
-            if self.config.deny_warnings {
-                lint_flags.push("-Dwarnings");
-                rustdocflags.arg("-Dwarnings");
-            }
-
-            // This does not use RUSTFLAGS due to caching issues with Cargo.
-            // Clippy is treated as an "in tree" tool, but shares the same
-            // cache as other "submodule" tools. With these options set in
-            // RUSTFLAGS, that causes *every* shared dependency to be rebuilt.
-            // By injecting this into the rustc wrapper, this circumvents
-            // Cargo's fingerprint detection. This is fine because lint flags
-            // are always ignored in dependencies. Eventually this should be
-            // fixed via better support from Cargo.
-            cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" "));
-
-            rustdocflags.arg("-Wrustdoc::invalid_codeblock_attributes");
-        }
-
-        if mode == Mode::Rustc {
-            rustflags.arg("-Wrustc::internal");
-            // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
-            // of the individual lints are satisfied.
-            rustflags.arg("-Wkeyword_idents_2024");
-            rustflags.arg("-Wunsafe_op_in_unsafe_fn");
-        }
-
-        if self.config.rust_frame_pointers {
-            rustflags.arg("-Cforce-frame-pointers=true");
-        }
-
-        // If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc
-        // when compiling the standard library, since this might be linked into the final outputs
-        // produced by rustc. Since this mitigation is only available on Windows, only enable it
-        // for the standard library in case the compiler is run on a non-Windows platform.
-        // This is not needed for stage 0 artifacts because these will only be used for building
-        // the stage 1 compiler.
-        if cfg!(windows)
-            && mode == Mode::Std
-            && self.config.control_flow_guard
-            && compiler.stage >= 1
-        {
-            rustflags.arg("-Ccontrol-flow-guard");
-        }
-
-        // If EHCont Guard is enabled, pass the `-Zehcont-guard` flag to rustc when compiling the
-        // standard library, since this might be linked into the final outputs produced by rustc.
-        // Since this mitigation is only available on Windows, only enable it for the standard
-        // library in case the compiler is run on a non-Windows platform.
-        // This is not needed for stage 0 artifacts because these will only be used for building
-        // the stage 1 compiler.
-        if cfg!(windows) && mode == Mode::Std && self.config.ehcont_guard && compiler.stage >= 1 {
-            rustflags.arg("-Zehcont-guard");
-        }
-
-        // For `cargo doc` invocations, make rustdoc print the Rust version into the docs
-        // This replaces spaces with tabs because RUSTDOCFLAGS does not
-        // support arguments with regular spaces. Hopefully someday Cargo will
-        // have space support.
-        let rust_version = self.rust_version().replace(' ', "\t");
-        rustdocflags.arg("--crate-version").arg(&rust_version);
-
-        // Environment variables *required* throughout the build
-        //
-        // FIXME: should update code to not require this env var
-
-        // The host this new compiler will *run* on.
-        cargo.env("CFG_COMPILER_HOST_TRIPLE", target.triple);
-        // The host this new compiler is being *built* on.
-        cargo.env("CFG_COMPILER_BUILD_TRIPLE", compiler.host.triple);
-
-        // Set this for all builds to make sure doc builds also get it.
-        cargo.env("CFG_RELEASE_CHANNEL", &self.config.channel);
-
-        // This one's a bit tricky. As of the time of this writing the compiler
-        // links to the `winapi` crate on crates.io. This crate provides raw
-        // bindings to Windows system functions, sort of like libc does for
-        // Unix. This crate also, however, provides "import libraries" for the
-        // MinGW targets. There's an import library per dll in the windows
-        // distribution which is what's linked to. These custom import libraries
-        // are used because the winapi crate can reference Windows functions not
-        // present in the MinGW import libraries.
-        //
-        // For example MinGW may ship libdbghelp.a, but it may not have
-        // references to all the functions in the dbghelp dll. Instead the
-        // custom import library for dbghelp in the winapi crates has all this
-        // information.
-        //
-        // Unfortunately for us though the import libraries are linked by
-        // default via `-ldylib=winapi_foo`. That is, they're linked with the
-        // `dylib` type with a `winapi_` prefix (so the winapi ones don't
-        // conflict with the system MinGW ones). This consequently means that
-        // the binaries we ship of things like rustc_codegen_llvm (aka the rustc_codegen_llvm
-        // DLL) when linked against *again*, for example with procedural macros
-        // or plugins, will trigger the propagation logic of `-ldylib`, passing
-        // `-lwinapi_foo` to the linker again. This isn't actually available in
-        // our distribution, however, so the link fails.
-        //
-        // To solve this problem we tell winapi to not use its bundled import
-        // libraries. This means that it will link to the system MinGW import
-        // libraries by default, and the `-ldylib=foo` directives will still get
-        // passed to the final linker, but they'll look like `-lfoo` which can
-        // be resolved because MinGW has the import library. The downside is we
-        // don't get newer functions from Windows, but we don't use any of them
-        // anyway.
-        if !mode.is_tool() {
-            cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1");
-        }
-
-        for _ in 0..self.verbosity {
-            cargo.arg("-v");
-        }
-
-        match (mode, self.config.rust_codegen_units_std, self.config.rust_codegen_units) {
-            (Mode::Std, Some(n), _) | (_, _, Some(n)) => {
-                cargo.env(profile_var("CODEGEN_UNITS"), n.to_string());
-            }
-            _ => {
-                // Don't set anything
-            }
-        }
-
-        if self.config.locked_deps {
-            cargo.arg("--locked");
-        }
-        if self.config.vendor || self.is_sudo {
-            cargo.arg("--frozen");
-        }
-
-        // Try to use a sysroot-relative bindir, in case it was configured absolutely.
-        cargo.env("RUSTC_INSTALL_BINDIR", self.config.bindir_relative());
-
-        cargo.force_coloring_in_ci();
-
-        // When we build Rust dylibs they're all intended for intermediate
-        // usage, so make sure we pass the -Cprefer-dynamic flag instead of
-        // linking all deps statically into the dylib.
-        if matches!(mode, Mode::Std) {
-            rustflags.arg("-Cprefer-dynamic");
-        }
-        if matches!(mode, Mode::Rustc) && !self.link_std_into_rustc_driver(target) {
-            rustflags.arg("-Cprefer-dynamic");
-        }
-
-        cargo.env(
-            "RUSTC_LINK_STD_INTO_RUSTC_DRIVER",
-            if self.link_std_into_rustc_driver(target) { "1" } else { "0" },
-        );
-
-        // When building incrementally we default to a lower ThinLTO import limit
-        // (unless explicitly specified otherwise). This will produce a somewhat
-        // slower code but give way better compile times.
-        {
-            let limit = match self.config.rust_thin_lto_import_instr_limit {
-                Some(limit) => Some(limit),
-                None if self.config.incremental => Some(10),
-                _ => None,
-            };
-
-            if let Some(limit) = limit {
-                if stage == 0
-                    || self.config.default_codegen_backend(target).unwrap_or_default() == "llvm"
-                {
-                    rustflags.arg(&format!("-Cllvm-args=-import-instr-limit={limit}"));
-                }
-            }
-        }
-
-        if matches!(mode, Mode::Std) {
-            if let Some(mir_opt_level) = self.config.rust_validate_mir_opts {
-                rustflags.arg("-Zvalidate-mir");
-                rustflags.arg(&format!("-Zmir-opt-level={mir_opt_level}"));
-            }
-            if self.config.rust_randomize_layout {
-                rustflags.arg("--cfg=randomized_layouts");
-            }
-            // Always enable inlining MIR when building the standard library.
-            // Without this flag, MIR inlining is disabled when incremental compilation is enabled.
-            // That causes some mir-opt tests which inline functions from the standard library to
-            // break when incremental compilation is enabled. So this overrides the "no inlining
-            // during incremental builds" heuristic for the standard library.
-            rustflags.arg("-Zinline-mir");
-
-            // Similarly, we need to keep debug info for functions inlined into other std functions,
-            // even if we're not going to output debuginfo for the crate we're currently building,
-            // so that it'll be available when downstream consumers of std try to use it.
-            rustflags.arg("-Zinline-mir-preserve-debug");
-        }
-
-        if self.config.rustc_parallel
-            && matches!(mode, Mode::ToolRustc | Mode::Rustc | Mode::Codegen)
-        {
-            // keep in sync with `bootstrap/lib.rs:Build::rustc_features`
-            // `cfg` option for rustc, `features` option for cargo, for conditional compilation
-            rustflags.arg("--cfg=parallel_compiler");
-            rustdocflags.arg("--cfg=parallel_compiler");
-        }
-
-        Cargo {
-            command: cargo,
-            compiler,
-            target,
-            rustflags,
-            rustdocflags,
-            hostflags,
-            allow_features,
-        }
-    }
-
     /// Ensure that a given step is built, returning its output. This will
     /// cache the step, so it is safe (and good!) to call this as often as
     /// needed to ensure that all dependencies are built.
@@ -2398,337 +1531,3 @@ impl<'a> Builder<'a> {
         }
     }
 }
-
-/// Represents flag values in `String` form with whitespace delimiter to pass it to the compiler later.
-///
-/// `-Z crate-attr` flags will be applied recursively on the target code using the `rustc_parse::parser::Parser`.
-/// See `rustc_builtin_macros::cmdline_attrs::inject` for more information.
-#[derive(Debug, Clone)]
-struct Rustflags(String, TargetSelection);
-
-impl Rustflags {
-    fn new(target: TargetSelection) -> Rustflags {
-        let mut ret = Rustflags(String::new(), target);
-        ret.propagate_cargo_env("RUSTFLAGS");
-        ret
-    }
-
-    /// By default, cargo will pick up on various variables in the environment. However, bootstrap
-    /// reuses those variables to pass additional flags to rustdoc, so by default they get overridden.
-    /// Explicitly add back any previous value in the environment.
-    ///
-    /// `prefix` is usually `RUSTFLAGS` or `RUSTDOCFLAGS`.
-    fn propagate_cargo_env(&mut self, prefix: &str) {
-        // Inherit `RUSTFLAGS` by default ...
-        self.env(prefix);
-
-        // ... and also handle target-specific env RUSTFLAGS if they're configured.
-        let target_specific = format!("CARGO_TARGET_{}_{}", crate::envify(&self.1.triple), prefix);
-        self.env(&target_specific);
-    }
-
-    fn env(&mut self, env: &str) {
-        if let Ok(s) = env::var(env) {
-            for part in s.split(' ') {
-                self.arg(part);
-            }
-        }
-    }
-
-    fn arg(&mut self, arg: &str) -> &mut Self {
-        assert_eq!(arg.split(' ').count(), 1);
-        if !self.0.is_empty() {
-            self.0.push(' ');
-        }
-        self.0.push_str(arg);
-        self
-    }
-}
-
-/// Flags that are passed to the `rustc` shim binary.
-/// These flags will only be applied when compiling host code, i.e. when
-/// `--target` is unset.
-#[derive(Debug, Default)]
-pub struct HostFlags {
-    rustc: Vec<String>,
-}
-
-impl HostFlags {
-    const SEPARATOR: &'static str = " ";
-
-    /// Adds a host rustc flag.
-    fn arg<S: Into<String>>(&mut self, flag: S) {
-        let value = flag.into().trim().to_string();
-        assert!(!value.contains(Self::SEPARATOR));
-        self.rustc.push(value);
-    }
-
-    /// Encodes all the flags into a single string.
-    fn encode(self) -> String {
-        self.rustc.join(Self::SEPARATOR)
-    }
-}
-
-#[derive(Debug)]
-pub struct Cargo {
-    command: BootstrapCommand,
-    compiler: Compiler,
-    target: TargetSelection,
-    rustflags: Rustflags,
-    rustdocflags: Rustflags,
-    hostflags: HostFlags,
-    allow_features: String,
-}
-
-impl Cargo {
-    /// Calls `Builder::cargo` and `Cargo::configure_linker` to prepare an invocation of `cargo` to be run.
-    pub fn new(
-        builder: &Builder<'_>,
-        compiler: Compiler,
-        mode: Mode,
-        source_type: SourceType,
-        target: TargetSelection,
-        cmd_kind: Kind,
-    ) -> Cargo {
-        let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind);
-
-        match cmd_kind {
-            // No need to configure the target linker for these command types,
-            // as they don't invoke rustc at all.
-            Kind::Clean | Kind::Suggest | Kind::Format | Kind::Setup => {}
-            _ => {
-                cargo.configure_linker(builder);
-            }
-        }
-
-        cargo
-    }
-
-    pub fn into_cmd(self) -> BootstrapCommand {
-        self.into()
-    }
-
-    /// Same as `Cargo::new` except this one doesn't configure the linker with `Cargo::configure_linker`
-    pub fn new_for_mir_opt_tests(
-        builder: &Builder<'_>,
-        compiler: Compiler,
-        mode: Mode,
-        source_type: SourceType,
-        target: TargetSelection,
-        cmd_kind: Kind,
-    ) -> Cargo {
-        builder.cargo(compiler, mode, source_type, target, cmd_kind)
-    }
-
-    pub fn rustdocflag(&mut self, arg: &str) -> &mut Cargo {
-        self.rustdocflags.arg(arg);
-        self
-    }
-
-    pub fn rustflag(&mut self, arg: &str) -> &mut Cargo {
-        self.rustflags.arg(arg);
-        self
-    }
-
-    pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Cargo {
-        self.command.arg(arg.as_ref());
-        self
-    }
-
-    pub fn args<I, S>(&mut self, args: I) -> &mut Cargo
-    where
-        I: IntoIterator<Item = S>,
-        S: AsRef<OsStr>,
-    {
-        for arg in args {
-            self.arg(arg.as_ref());
-        }
-        self
-    }
-
-    pub fn env(&mut self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Cargo {
-        // These are managed through rustflag/rustdocflag interfaces.
-        assert_ne!(key.as_ref(), "RUSTFLAGS");
-        assert_ne!(key.as_ref(), "RUSTDOCFLAGS");
-        self.command.env(key.as_ref(), value.as_ref());
-        self
-    }
-
-    pub fn add_rustc_lib_path(&mut self, builder: &Builder<'_>) {
-        builder.add_rustc_lib_path(self.compiler, &mut self.command);
-    }
-
-    pub fn current_dir(&mut self, dir: &Path) -> &mut Cargo {
-        self.command.current_dir(dir);
-        self
-    }
-
-    /// Adds nightly-only features that this invocation is allowed to use.
-    ///
-    /// By default, all nightly features are allowed. Once this is called, it
-    /// will be restricted to the given set.
-    pub fn allow_features(&mut self, features: &str) -> &mut Cargo {
-        if !self.allow_features.is_empty() {
-            self.allow_features.push(',');
-        }
-        self.allow_features.push_str(features);
-        self
-    }
-
-    fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
-        let target = self.target;
-        let compiler = self.compiler;
-
-        // Dealing with rpath here is a little special, so let's go into some
-        // detail. First off, `-rpath` is a linker option on Unix platforms
-        // which adds to the runtime dynamic loader path when looking for
-        // dynamic libraries. We use this by default on Unix platforms to ensure
-        // that our nightlies behave the same on Windows, that is they work out
-        // of the box. This can be disabled by setting `rpath = false` in `[rust]`
-        // table of `config.toml`
-        //
-        // Ok, so the astute might be wondering "why isn't `-C rpath` used
-        // here?" and that is indeed a good question to ask. This codegen
-        // option is the compiler's current interface to generating an rpath.
-        // Unfortunately it doesn't quite suffice for us. The flag currently
-        // takes no value as an argument, so the compiler calculates what it
-        // should pass to the linker as `-rpath`. This unfortunately is based on
-        // the **compile time** directory structure which when building with
-        // Cargo will be very different than the runtime directory structure.
-        //
-        // All that's a really long winded way of saying that if we use
-        // `-Crpath` then the executables generated have the wrong rpath of
-        // something like `$ORIGIN/deps` when in fact the way we distribute
-        // rustc requires the rpath to be `$ORIGIN/../lib`.
-        //
-        // So, all in all, to set up the correct rpath we pass the linker
-        // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
-        // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
-        // to change a flag in a binary?
-        if builder.config.rpath_enabled(target) && helpers::use_host_linker(target) {
-            let libdir = builder.sysroot_libdir_relative(compiler).to_str().unwrap();
-            let rpath = if target.contains("apple") {
-                // Note that we need to take one extra step on macOS to also pass
-                // `-Wl,-instal_name,@rpath/...` to get things to work right. To
-                // do that we pass a weird flag to the compiler to get it to do
-                // so. Note that this is definitely a hack, and we should likely
-                // flesh out rpath support more fully in the future.
-                self.rustflags.arg("-Zosx-rpath-install-name");
-                Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
-            } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
-                self.rustflags.arg("-Clink-args=-Wl,-z,origin");
-                Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
-            } else {
-                None
-            };
-            if let Some(rpath) = rpath {
-                self.rustflags.arg(&format!("-Clink-args={rpath}"));
-            }
-        }
-
-        for arg in linker_args(builder, compiler.host, LldThreads::Yes) {
-            self.hostflags.arg(&arg);
-        }
-
-        if let Some(target_linker) = builder.linker(target) {
-            let target = crate::envify(&target.triple);
-            self.command.env(format!("CARGO_TARGET_{target}_LINKER"), target_linker);
-        }
-        // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
-        // `linker_args` here.
-        for flag in linker_flags(builder, target, LldThreads::Yes) {
-            self.rustflags.arg(&flag);
-        }
-        for arg in linker_args(builder, target, LldThreads::Yes) {
-            self.rustdocflags.arg(&arg);
-        }
-
-        if !builder.config.dry_run()
-            && builder.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
-        {
-            self.rustflags.arg("-Clink-arg=-gz");
-        }
-
-        // Throughout the build Cargo can execute a number of build scripts
-        // compiling C/C++ code and we need to pass compilers, archivers, flags, etc
-        // obtained previously to those build scripts.
-        // Build scripts use either the `cc` crate or `configure/make` so we pass
-        // the options through environment variables that are fetched and understood by both.
-        //
-        // FIXME: the guard against msvc shouldn't need to be here
-        if target.is_msvc() {
-            if let Some(ref cl) = builder.config.llvm_clang_cl {
-                // FIXME: There is a bug in Clang 18 when building for ARM64:
-                // https://github.com/llvm/llvm-project/pull/81849. This is
-                // fixed in LLVM 19, but can't be backported.
-                if !target.starts_with("aarch64") && !target.starts_with("arm64ec") {
-                    self.command.env("CC", cl).env("CXX", cl);
-                }
-            }
-        } else {
-            let ccache = builder.config.ccache.as_ref();
-            let ccacheify = |s: &Path| {
-                let ccache = match ccache {
-                    Some(ref s) => s,
-                    None => return s.display().to_string(),
-                };
-                // FIXME: the cc-rs crate only recognizes the literal strings
-                // `ccache` and `sccache` when doing caching compilations, so we
-                // mirror that here. It should probably be fixed upstream to
-                // accept a new env var or otherwise work with custom ccache
-                // vars.
-                match &ccache[..] {
-                    "ccache" | "sccache" => format!("{} {}", ccache, s.display()),
-                    _ => s.display().to_string(),
-                }
-            };
-            let triple_underscored = target.triple.replace('-', "_");
-            let cc = ccacheify(&builder.cc(target));
-            self.command.env(format!("CC_{triple_underscored}"), &cc);
-
-            let cflags = builder.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
-            self.command.env(format!("CFLAGS_{triple_underscored}"), &cflags);
-
-            if let Some(ar) = builder.ar(target) {
-                let ranlib = format!("{} s", ar.display());
-                self.command
-                    .env(format!("AR_{triple_underscored}"), ar)
-                    .env(format!("RANLIB_{triple_underscored}"), ranlib);
-            }
-
-            if let Ok(cxx) = builder.cxx(target) {
-                let cxx = ccacheify(&cxx);
-                let cxxflags = builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
-                self.command
-                    .env(format!("CXX_{triple_underscored}"), &cxx)
-                    .env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
-            }
-        }
-
-        self
-    }
-}
-
-impl From<Cargo> for BootstrapCommand {
-    fn from(mut cargo: Cargo) -> BootstrapCommand {
-        let rustflags = &cargo.rustflags.0;
-        if !rustflags.is_empty() {
-            cargo.command.env("RUSTFLAGS", rustflags);
-        }
-
-        let rustdocflags = &cargo.rustdocflags.0;
-        if !rustdocflags.is_empty() {
-            cargo.command.env("RUSTDOCFLAGS", rustdocflags);
-        }
-
-        let encoded_hostflags = cargo.hostflags.encode();
-        if !encoded_hostflags.is_empty() {
-            cargo.command.env("RUSTC_HOST_FLAGS", encoded_hostflags);
-        }
-
-        if !cargo.allow_features.is_empty() {
-            cargo.command.env("RUSTC_ALLOW_FEATURES", cargo.allow_features);
-        }
-        cargo.command
-    }
-}
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 695a66834d4..21c5f7232a1 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -637,7 +637,7 @@ mod dist {
         assert_eq!(first(builder.cache.all::<test::Crate>()), &[test::Crate {
             compiler: Compiler { host, stage: 0 },
             target: host,
-            mode: Mode::Std,
+            mode: crate::Mode::Std,
             crates: vec!["std".to_owned()],
         },]);
     }
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 3924a6d714e..a9db0377a50 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -545,23 +545,28 @@ impl Build {
             .args(["--get-regexp", "path"])
             .run_capture(self)
             .stdout();
-        for line in output.lines() {
+        std::thread::scope(|s| {
             // Look for `submodule.$name.path = $path`
             // Sample output: `submodule.src/rust-installer.path src/tools/rust-installer`
-            let submodule = line.split_once(' ').unwrap().1;
-            self.update_existing_submodule(submodule);
-        }
+            for line in output.lines() {
+                let submodule = line.split_once(' ').unwrap().1;
+                let config = self.config.clone();
+                s.spawn(move || {
+                    Self::update_existing_submodule(&config, submodule);
+                });
+            }
+        });
     }
 
     /// Updates the given submodule only if it's initialized already; nothing happens otherwise.
-    pub fn update_existing_submodule(&self, submodule: &str) {
+    pub fn update_existing_submodule(config: &Config, submodule: &str) {
         // Avoid running git when there isn't a git checkout.
-        if !self.config.submodules() {
+        if !config.submodules() {
             return;
         }
 
         if GitInfo::new(false, Path::new(submodule)).is_managed_git_subrepository() {
-            self.config.update_submodule(submodule);
+            config.update_submodule(submodule);
         }
     }
 
diff --git a/src/bootstrap/src/utils/channel.rs b/src/bootstrap/src/utils/channel.rs
index c361abb9c9e..4a9ecc7a4f8 100644
--- a/src/bootstrap/src/utils/channel.rs
+++ b/src/bootstrap/src/utils/channel.rs
@@ -10,7 +10,7 @@ use std::path::Path;
 
 use super::helpers;
 use crate::Build;
-use crate::utils::helpers::{output, t};
+use crate::utils::helpers::{start_process, t};
 
 #[derive(Clone, Default)]
 pub enum GitInfo {
@@ -56,7 +56,7 @@ impl GitInfo {
         }
 
         // Ok, let's scrape some info
-        let ver_date = output(
+        let ver_date = start_process(
             helpers::git(Some(dir))
                 .arg("log")
                 .arg("-1")
@@ -65,14 +65,14 @@ impl GitInfo {
                 .as_command_mut(),
         );
         let ver_hash =
-            output(helpers::git(Some(dir)).arg("rev-parse").arg("HEAD").as_command_mut());
-        let short_ver_hash = output(
+            start_process(helpers::git(Some(dir)).arg("rev-parse").arg("HEAD").as_command_mut());
+        let short_ver_hash = start_process(
             helpers::git(Some(dir)).arg("rev-parse").arg("--short=9").arg("HEAD").as_command_mut(),
         );
         GitInfo::Present(Some(Info {
-            commit_date: ver_date.trim().to_string(),
-            sha: ver_hash.trim().to_string(),
-            short_sha: short_ver_hash.trim().to_string(),
+            commit_date: ver_date().trim().to_string(),
+            sha: ver_hash().trim().to_string(),
+            short_sha: short_ver_hash().trim().to_string(),
         }))
     }
 
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 2519ace92b9..7162007e9f0 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -288,6 +288,33 @@ pub fn output(cmd: &mut Command) -> String {
     String::from_utf8(output.stdout).unwrap()
 }
 
+/// Spawn a process and return a closure that will wait for the process
+/// to finish and then return its output. This allows the spawned process
+/// to do work without immediately blocking bootstrap.
+#[track_caller]
+pub fn start_process(cmd: &mut Command) -> impl FnOnce() -> String {
+    let child = match cmd.stderr(Stdio::inherit()).stdout(Stdio::piped()).spawn() {
+        Ok(child) => child,
+        Err(e) => fail(&format!("failed to execute command: {cmd:?}\nERROR: {e}")),
+    };
+
+    let command = format!("{:?}", cmd);
+
+    move || {
+        let output = child.wait_with_output().unwrap();
+
+        if !output.status.success() {
+            panic!(
+                "command did not execute successfully: {}\n\
+                 expected success, got: {}",
+                command, output.status
+            );
+        }
+
+        String::from_utf8(output.stdout).unwrap()
+    }
+}
+
 /// Returns the last-modified time for `path`, or zero if it doesn't exist.
 pub fn mtime(path: &Path) -> SystemTime {
     fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH)
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index 1b98d541693..410f0f92e60 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -56,9 +56,9 @@ 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" \
     CXX_x86_64_fortanix_unknown_sgx=clang++-11 \
     CXXFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
-    AR_i686_unknown_freebsd=i686-unknown-freebsd12-ar \
-    CC_i686_unknown_freebsd=i686-unknown-freebsd12-clang \
-    CXX_i686_unknown_freebsd=i686-unknown-freebsd12-clang++ \
+    AR_i686_unknown_freebsd=i686-unknown-freebsd13-ar \
+    CC_i686_unknown_freebsd=i686-unknown-freebsd13-clang \
+    CXX_i686_unknown_freebsd=i686-unknown-freebsd13-clang++ \
     CC_aarch64_unknown_uefi=clang-11 \
     CXX_aarch64_unknown_uefi=clang++-11 \
     CC_i686_unknown_uefi=clang-11 \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
index b3c5f41bdd7..fd0f5da8c49 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:22.04
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
   clang \
@@ -29,9 +29,9 @@ COPY scripts/cmake.sh /scripts/
 RUN /scripts/cmake.sh
 
 ENV \
-    AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-ar \
-    CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang \
-    CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang++
+    AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-ar \
+    CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-clang \
+    CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-clang++
 
 ENV HOSTS=x86_64-unknown-freebsd
 
diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh
index 0d02636db91..4826b81d56c 100755
--- a/src/ci/docker/scripts/freebsd-toolchain.sh
+++ b/src/ci/docker/scripts/freebsd-toolchain.sh
@@ -5,8 +5,8 @@ set -eux
 
 arch=$1
 binutils_version=2.40
-freebsd_version=12.3
-triple=$arch-unknown-freebsd12
+freebsd_version=13.2
+triple=$arch-unknown-freebsd13
 sysroot=/usr/local/$triple
 
 hide_output() {
@@ -59,7 +59,7 @@ done
 
 # Originally downloaded from:
 # URL=https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz
-URL=https://ci-mirrors.rust-lang.org/rustc/2022-05-06-freebsd-${freebsd_version}-${freebsd_arch}-base.txz
+URL=https://ci-mirrors.rust-lang.org/rustc/2024-02-18-freebsd-${freebsd_version}-${freebsd_arch}-base.txz
 curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}"
 
 # Clang can do cross-builds out of the box, if we give it the right
@@ -68,7 +68,7 @@ curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}"
 # there might be other problems.)
 #
 # The --target option is last because the cross-build of LLVM uses
-# --target without an OS version ("-freebsd" vs. "-freebsd12").  This
+# --target without an OS version ("-freebsd" vs. "-freebsd13").  This
 # makes Clang default to libstdc++ (which no longer exists), and also
 # controls other features, like GNU-style symbol table hashing and
 # anything predicated on the version number in the __FreeBSD__
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index d84b904442c..2b636604049 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -51,7 +51,7 @@ envs:
     RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
     MACOSX_DEPLOYMENT_TARGET: 10.12
     MACOSX_STD_DEPLOYMENT_TARGET: 10.12
-    SELECT_XCODE: /Applications/Xcode_14.3.1.app
+    SELECT_XCODE: /Applications/Xcode_15.2.app
     NO_LLVM_ASSERTIONS: 1
     NO_DEBUG_ASSERTIONS: 1
     NO_OVERFLOW_CHECKS: 1
@@ -287,7 +287,7 @@ auto:
       RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1
       RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
       MACOSX_DEPLOYMENT_TARGET: 10.12
-      SELECT_XCODE: /Applications/Xcode_14.3.1.app
+      SELECT_XCODE: /Applications/Xcode_15.2.app
       NO_LLVM_ASSERTIONS: 1
       NO_DEBUG_ASSERTIONS: 1
       NO_OVERFLOW_CHECKS: 1
@@ -303,7 +303,7 @@ auto:
       RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc --set target.aarch64-apple-ios-macabi.sanitizers=false --set target.x86_64-apple-ios-macabi.sanitizers=false
       RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
       MACOSX_DEPLOYMENT_TARGET: 10.12
-      SELECT_XCODE: /Applications/Xcode_14.3.1.app
+      SELECT_XCODE: /Applications/Xcode_15.2.app
       NO_LLVM_ASSERTIONS: 1
       NO_DEBUG_ASSERTIONS: 1
       NO_OVERFLOW_CHECKS: 1
@@ -332,7 +332,7 @@ auto:
         --set llvm.ninja=false
         --set rust.lto=thin
       RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-      SELECT_XCODE: /Applications/Xcode_14.3.1.app
+      SELECT_XCODE: /Applications/Xcode_15.4.app
       USE_XCODE_CLANG: 1
       MACOSX_DEPLOYMENT_TARGET: 11.0
       MACOSX_STD_DEPLOYMENT_TARGET: 11.0
@@ -352,7 +352,7 @@ auto:
         --enable-profiler
         --set rust.jemalloc
       RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-      SELECT_XCODE: /Applications/Xcode_14.3.1.app
+      SELECT_XCODE: /Applications/Xcode_15.4.app
       USE_XCODE_CLANG: 1
       MACOSX_DEPLOYMENT_TARGET: 11.0
       MACOSX_STD_DEPLOYMENT_TARGET: 11.0
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 022fc9da7e0..e9c73ef1c2d 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -100,7 +100,7 @@ target | notes
 [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29)
 [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3)
 `s390x-unknown-linux-gnu` | S390x Linux (kernel 3.2, glibc 2.17)
-`x86_64-unknown-freebsd` | 64-bit FreeBSD
+`x86_64-unknown-freebsd` | 64-bit FreeBSD (version 13.2)
 `x86_64-unknown-illumos` | illumos
 `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3
 [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64
@@ -166,7 +166,7 @@ target | std | notes
 `i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, musl 1.2.3 [^x86_32-floats-x87]
 [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android [^x86_32-floats-return-ABI]
 [`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+), LLVM ABI [^x86_32-floats-return-ABI]
-`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI]
+`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD (version 13.2) [^x86_32-floats-return-ABI]
 `i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI]
 [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI
 [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI)
@@ -257,7 +257,7 @@ target | std | host | notes
 [`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? |  | ARM64 TEEOS |
 [`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? |  | ARM64 QNX Neutrino 7.0 RTOS |
 [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ |  | ARM64 QNX Neutrino 7.1 RTOS |
-`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
+`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD (version 13.2)
 [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ |  | ARM64 Hermit
 `aarch64-unknown-illumos` | ✓ | ✓ | ARM64 illumos
 `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
@@ -276,14 +276,14 @@ target | std | host | notes
 `armv4t-unknown-linux-gnueabi` | ? |  | Armv4T Linux
 [`armv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * |  | Bare Armv5TE
 `armv5te-unknown-linux-uclibceabi` | ? |  | Armv5TE Linux with uClibc
-`armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD
+`armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD (version 13.2)
 [`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float
 [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? |  | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain)
 [`armv7-rtems-eabihf`](platform-support/armv7-rtems-eabihf.md) | ? |  | RTEMS OS for ARM BSPs
 [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ |  | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
 [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat
 [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
-`armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD
+`armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD (version 13.2)
 [`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float
 [`armv7-unknown-trusty`](platform-support/trusty.md) | ? |  |
 [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ |  | Armv7-A for VxWorks
@@ -342,9 +342,9 @@ target | std | host | notes
 [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * |  |
 [`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ |  |
 [`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
-`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2)
-`powerpc64le-unknown-freebsd` |   |   | PPC64LE FreeBSD
-`powerpc-unknown-freebsd` |   |   | PowerPC FreeBSD
+`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2, version 13.2)
+`powerpc64le-unknown-freebsd` |   |   | PPC64LE FreeBSD (version 13.2)
+`powerpc-unknown-freebsd` |   |   | PowerPC FreeBSD (version 13.2)
 `powerpc64-unknown-linux-musl` | ? |  | 64-bit PowerPC Linux with musl 1.2.3
 [`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
 `powerpc64le-unknown-linux-musl` | ? |  | 64-bit PowerPC Linux with musl 1.2.3, Little Endian
@@ -360,7 +360,7 @@ target | std | host | notes
 [`riscv32imafc-esp-espidf`](platform-support/esp-idf.md) | ✓ |  | RISC-V ESP-IDF
 [`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
 [`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ |   | RISC-V Hermit
-`riscv64gc-unknown-freebsd` |   |   | RISC-V FreeBSD
+`riscv64gc-unknown-freebsd` |   |   | RISC-V FreeBSD (version 13.2)
 `riscv64gc-unknown-fuchsia` |   |   | RISC-V Fuchsia
 [`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD
 [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md
index de0ef322fa6..9732df4be7f 100644
--- a/src/doc/rustc/src/platform-support/arm-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md
@@ -42,16 +42,15 @@ their own document.
 There are two 32-bit instruction set architectures (ISAs) defined by Arm:
 
 - The [*A32 ISA*][a32-isa], with fixed-width 32-bit instructions. Previously
-  known as the *Arm* ISA, this originated with the original Arm1 of 1985 and has
+  known as the *Arm* ISA, this originated with the original ARM1 of 1985 and has
   been updated by various revisions to the architecture specifications ever
   since.
 - The [*T32 ISA*][t32-isa], with a mix of 16-bit and 32-bit width instructions.
   Note that this term includes both the original 16-bit width *Thumb* ISA
   introduced with the Armv4T architecture in 1994, and the later 16/32-bit sized
-  *Thumb-2* ISA introduced with the Armv6T2 architecture in 2003.
-
-Again, these ISAs have been revised by subsequent revisions to the relevant Arm
-architecture specifications.
+  *Thumb-2* ISA introduced with the Armv6T2 architecture in 2003. Again, these
+  ISAs have been revised by subsequent revisions to the relevant Arm
+  architecture specifications.
 
 There is also a 64-bit ISA with fixed-width 32-bit instructions called the *A64
 ISA*, but targets which implement that instruction set generally start with
@@ -106,10 +105,14 @@ features you do not have available, leaving you with the optimized instruction
 scheduling and support for the features you do have. More details are available
 in the detailed target-specific documentation.
 
-**Note:** Many target-features are currently unstable and subject to change, and
+<div class="warning">
+
+Many target-features are currently unstable and subject to change, and
 if you use them you should disassemble the compiler output and manually inspect
 it to ensure only appropriate instructions for your CPU have been generated.
 
+</div>
+
 If you wish to use the *target-cpu* and *target-feature* options, you can add
 them to your `.cargo/config.toml` file alongside any other flags your project
 uses (likely linker related ones):
diff --git a/src/doc/rustc/src/platform-support/nuttx.md b/src/doc/rustc/src/platform-support/nuttx.md
index cbbede45f52..433a092aab2 100644
--- a/src/doc/rustc/src/platform-support/nuttx.md
+++ b/src/doc/rustc/src/platform-support/nuttx.md
@@ -35,7 +35,7 @@ The following target names are defined:
 
 ## Building the target
 
-The target can be built by enabled in the `rustc` build:
+The target can be built by enabling it in the `rustc` build:
 
 ```toml
 [build]
diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
index f25ef0383b1..11c9486cb76 100644
--- a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
@@ -35,9 +35,9 @@ to use these flags.
 | CPU        | FPU | DSP | Target CPU  | Target Features |
 | ---------- | --- | --- | ----------- | --------------- |
 | Any        | No  | Yes | None        | None            |
-| Cortex-M4  | No  | Yes | `cortex-m4` | `+soft-float`   |
+| Cortex-M4  | No  | Yes | `cortex-m4` | `-fpregs`       |
 | Cortex-M4F | SP  | Yes | `cortex-m4` | None            |
-| Cortex-M7  | No  | Yes | `cortex-m7` | `+soft-float`   |
+| Cortex-M7  | No  | Yes | `cortex-m7` | `-fpregs`       |
 | Cortex-M7F | SP  | Yes | `cortex-m7` | `-fp64`         |
 | Cortex-M7F | DP  | Yes | `cortex-m7` | None            |
 
@@ -50,6 +50,13 @@ to use these flags.
 | Cortex-M7F | SP  | Yes | `cortex-m7` | `-fp64`         |
 | Cortex-M7F | DP  | Yes | `cortex-m7` | None            |
 
+<div class="warning">
+
+Never use the `-fpregs` *target-feature* with the `thumbv7em-none-eabihf` target
+as it will cause compilation units to have different ABIs, which is unsound.
+
+</div>
+
 ### Arm Cortex-M4 and Arm Cortex-M4F
 
 The target CPU is `cortex-m4`.
@@ -59,7 +66,7 @@ The target CPU is `cortex-m4`.
   * enabled by default with this *target*
 * Cortex-M4F has a single precision FPU
   * support is enabled by default with this *target-cpu*
-  * disable support using the `+soft-float` feature (`eabi` only)
+  * disable support using the `-fpregs` *target-feature* (`eabi` only)
 
 ### Arm Cortex-M7 and Arm Cortex-M7F
 
@@ -71,4 +78,4 @@ The target CPU is `cortex-m7`.
 * Cortex-M7F have either a single-precision or double-precision FPU
   * double-precision support is enabled by default with this *target-cpu*
     * opt-out by using the `-f64` *target-feature*
-  * disable support entirely using the `+soft-float` feature (`eabi` only)
+  * disable support entirely using the `-fpregs` *target-feature* (`eabi` only)
diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
index 4e696f9c304..82fdc5b21cf 100644
--- a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
@@ -39,22 +39,22 @@ to use these flags.
 | CPU         | FPU | DSP | MVE       | Target CPU    | Target Features       |
 | ----------- | --- | --- | --------- | ------------- | --------------------- |
 | Unspecified | No  | No  | No        | None          | None                  |
-| Cortex-M33  | No  | No  | No        | `cortex-m33`  | `+soft-float,-dsp`    |
-| Cortex-M33  | No  | Yes | No        | `cortex-m33`  | `+soft-float`         |
+| Cortex-M33  | No  | No  | No        | `cortex-m33`  | `-fpregs,-dsp`        |
+| Cortex-M33  | No  | Yes | No        | `cortex-m33`  | `-fpregs`             |
 | Cortex-M33  | SP  | No  | No        | `cortex-m33`  | `-dsp`                |
 | Cortex-M33  | SP  | Yes | No        | `cortex-m33`  | None                  |
-| Cortex-M35P | No  | No  | No        | `cortex-m35p` | `+soft-float,-dsp`    |
-| Cortex-M35P | No  | Yes | No        | `cortex-m35p` | `+soft-float`         |
+| Cortex-M35P | No  | No  | No        | `cortex-m35p` | `-fpregs,-dsp`        |
+| Cortex-M35P | No  | Yes | No        | `cortex-m35p` | `-fpregs`             |
 | Cortex-M35P | SP  | No  | No        | `cortex-m35p` | `-dsp`                |
 | Cortex-M35P | SP  | Yes | No        | `cortex-m35p` | None                  |
-| Cortex-M55  | No  | Yes | No        | `cortex-m55`  | `+soft-float,-mve`    |
+| Cortex-M55  | No  | Yes | No        | `cortex-m55`  | `-fpregs,-mve`        |
 | Cortex-M55  | DP  | Yes | No        | `cortex-m55`  | `-mve`                |
-| Cortex-M55  | No  | Yes | Int       | `cortex-m55`  | `+soft-float,-mve.fp` |
+| Cortex-M55  | No  | Yes | Int       | `cortex-m55`  | `-fpregs,-mve.fp,+mve`|
 | Cortex-M55  | DP  | Yes | Int       | `cortex-m55`  | `-mve.fp`             |
 | Cortex-M55  | DP  | Yes | Int+Float | `cortex-m55`  | None                  |
-| Cortex-M85  | No  | Yes | No        | `cortex-m85`  | `+soft-float,-mve`    |
+| Cortex-M85  | No  | Yes | No        | `cortex-m85`  | `-fpregs,-mve`        |
 | Cortex-M85  | DP  | Yes | No        | `cortex-m85`  | `-mve`                |
-| Cortex-M85  | No  | Yes | Int       | `cortex-m85`  | `+soft-float,-mve.fp` |
+| Cortex-M85  | No  | Yes | Int       | `cortex-m85`  | `-fpregs,-mve.fp,+mve`|
 | Cortex-M85  | DP  | Yes | Int       | `cortex-m85`  | `-mve.fp`             |
 | Cortex-M85  | DP  | Yes | Int+Float | `cortex-m85`  | None                  |
 
@@ -74,6 +74,19 @@ to use these flags.
 | Cortex-M85  | DP  | Yes | Int       | `cortex-m85`  | `-mve.fp`             |
 | Cortex-M85  | DP  | Yes | Int+Float | `cortex-m85`  | None                  |
 
+*Technically* you can use this hard-float ABI on a CPU which has no FPU but does
+have Integer MVE, because MVE provides the same set of registers as the FPU
+(including `s0` and `d0`). The particular set of flags that might enable this
+unusual scenario are currently not recorded here.
+
+<div class="warning">
+
+Never use the `-fpregs` *target-feature* with the `thumbv8m.main-none-eabihf`
+target as it will cause compilation units to have different ABIs, which is
+unsound.
+
+</div>
+
 ### Arm Cortex-M33
 
 The target CPU is `cortex-m33`.
@@ -83,7 +96,7 @@ The target CPU is `cortex-m33`.
   * enabled by default with this *target-cpu*
 * Has an optional single precision FPU
   * support is enabled by default with this *target-cpu*
-  * disable support using the `+soft-float` feature (`eabi` only)
+  * disable support using the `-fpregs` *target-feature* (`eabi` only)
 
 ### Arm Cortex-M35P
 
@@ -94,7 +107,7 @@ The target CPU is `cortex-m35p`.
   * enabled by default with this *target-cpu*
 * Has an optional single precision FPU
   * support is enabled by default with this *target-cpu*
-  * disable support using the `+soft-float` feature (`eabi` only)
+  * disable support using the `-fpregs` *target-feature* (`eabi` only)
 
 ### Arm Cortex-M55
 
@@ -106,7 +119,7 @@ The target CPU is `cortex-m55`.
 * Has an optional double-precision FPU that also supports half-precision FP16
   values
   * support is enabled by default with this *target-cpu*
-  * disable support using the `+soft-float` feature (`eabi` only)
+  * disable support using the `-fpregs` *target-feature* (`eabi` only)
 * Has optional support for M-Profile Vector Extensions
   * Also known as *Helium Technology*
   * Available with only integer support, or both integer/float support
@@ -125,7 +138,7 @@ The target CPU is `cortex-m85`.
 * Has an optional double-precision FPU that also supports half-precision FP16
   values
   * support is enabled by default with this *target-cpu*
-  * disable support using the `+soft-float` feature (`eabi` only)
+  * disable support using the `-fpregs` *target-feature* (`eabi` only)
 * Has optional support for M-Profile Vector Extensions
   * Also known as *Helium Technology*
   * Available with only integer support, or both integer/float support
diff --git a/src/doc/unstable-book/src/compiler-flags/regparm.md b/src/doc/unstable-book/src/compiler-flags/regparm.md
new file mode 100644
index 00000000000..8f311f091c0
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/regparm.md
@@ -0,0 +1,20 @@
+# `regparm`
+
+The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/131749.
+
+------------------------
+
+Option -Zregparm=N causes the compiler to pass N arguments
+in registers EAX, EDX, and ECX instead of on the stack for "C", "cdecl", and "stdcall" fn.
+It is UNSOUND to link together crates that use different values for this flag.
+It is only supported on `x86`.
+
+It is equivalent to [Clang]'s and [GCC]'s `-mregparm`.
+
+Supported values for this option are 0-3.
+
+[Clang]: https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mregparm
+[GCC]: https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#index-regparm-function-attribute_002c-x86
+
+Implementation details:
+For eligible arguments, llvm `inreg` attribute is set.
diff --git a/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md b/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md
deleted file mode 100644
index dc9c196524e..00000000000
--- a/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# `result_ffi_guarantees`
-
-The tracking issue for this feature is: [#110503]
-
-[#110503]: https://github.com/rust-lang/rust/issues/110503
-
-------------------------
-
-This feature adds the possibility of using `Result<T, E>` in FFI if T's niche
-value can be used to describe E or vise-versa.
-
-See [RFC 3391] for more information.
-
-[RFC 3391]: https://github.com/rust-lang/rfcs/blob/master/text/3391-result_ffi_guarantees.md
diff --git a/src/doc/unstable-book/src/language-features/strict-provenance.md b/src/doc/unstable-book/src/language-features/strict-provenance-lints.md
index dc60f3f375d..81bdf07a86a 100644
--- a/src/doc/unstable-book/src/language-features/strict-provenance.md
+++ b/src/doc/unstable-book/src/language-features/strict-provenance-lints.md
@@ -1,18 +1,17 @@
-# `strict_provenance`
+# `strict_provenance_lints`
 
 The tracking issue for this feature is: [#95228]
 
 [#95228]: https://github.com/rust-lang/rust/issues/95228
 -----
 
-The `strict_provenance` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints.
+The `strict_provenance_lints` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints.
 These lint on casts between integers and pointers, that are recommended against or invalid in the strict provenance model.
-The same feature gate is also used for the experimental strict provenance API in `std` (actually `core`).
 
 ## Example
 
 ```rust
-#![feature(strict_provenance)]
+#![feature(strict_provenance_lints)]
 #![warn(fuzzy_provenance_casts)]
 
 fn main() {
diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs
index f29e1e4d27a..2d155bf0b10 100644
--- a/src/etc/installer/msi/rust.wxs
+++ b/src/etc/installer/msi/rust.wxs
@@ -172,6 +172,11 @@
                     <!-- tool-rust-docs-end -->
                     <Directory Id="Cargo" Name="." />
                     <Directory Id="Std" Name="." />
+                    <Directory Id="RustFmt" Name="." />
+                    <Directory Id="RustAnalyzer" Name="." />
+                    <Directory Id="Miri" Name="." />
+                    <Directory Id="Analysis" Name="." />
+                    <Directory Id="Clippy" Name="." />
                 </Directory>
             </Directory>
 
@@ -279,7 +284,41 @@
                  <ComponentRef Id="PathEnvPerMachine" />
                  <ComponentRef Id="PathEnvPerUser" />
         </Feature>
-
+        <Feature Id="RustFmt"
+                 Title="Formatter for rust"
+                 Display="7"
+                 Level="1"
+                 AllowAdvertise="no">
+                 <ComponentGroupRef Id="RustFmtGroup" />
+        </Feature>
+        <Feature Id="Clippy"
+                 Title="Formatter and checker for rust"
+                 Display="8"
+                 Level="1"
+                 AllowAdvertise="no">
+                 <ComponentGroupRef Id="ClippyGroup" />
+        </Feature>
+        <Feature Id="Miri"
+                 Title="Soundness checker for rust"
+                 Display="9"
+                 Level="1"
+                 AllowAdvertise="no">
+                 <ComponentGroupRef Id="MiriGroup" />
+        </Feature>
+        <Feature Id="RustAnalyzer"
+                 Title="Analyzer for rust"
+                 Display="10"
+                 Level="1"
+                 AllowAdvertise="no">
+                 <ComponentGroupRef Id="RustAnalyzerGroup" />
+        </Feature>
+        <Feature Id="Analysis"
+                 Title="Analysis for rust"
+                 Display="11"
+                 Level="1"
+                 AllowAdvertise="no">
+                 <ComponentGroupRef Id="AnalysisGroup" />
+        </Feature>
         <UIRef Id="RustUI" />
     </Product>
 </Wix>
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 1ddad917b78..7d4d8d8941d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1817,7 +1817,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
                         // Only anon consts can implicitly capture params.
                         // FIXME: is this correct behavior?
                         let param_env = cx.tcx.param_env(*def_id);
-                        ct.normalize(cx.tcx, param_env)
+                        cx.tcx.normalize_erasing_regions(param_env, ct)
                     } else {
                         ct
                     };
@@ -2033,8 +2033,8 @@ pub(crate) fn clean_middle_ty<'tcx>(
             Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None)),
             format!("{pat:?}").into_boxed_str(),
         ),
-        ty::Array(ty, mut n) => {
-            n = n.normalize(cx.tcx, ty::ParamEnv::reveal_all());
+        ty::Array(ty, n) => {
+            let n = cx.tcx.normalize_erasing_regions(cx.param_env, n);
             let n = print_const(cx, n);
             Array(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None)), n.into())
         }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 9bebe1fb4c1..0f7d4d3e8f3 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::unord::UnordSet;
 use rustc_errors::codes::*;
 use rustc_errors::emitter::{DynEmitter, HumanEmitter, stderr_destination};
 use rustc_errors::json::JsonEmitter;
-use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, TerminalUrl};
+use rustc_errors::{ErrorGuaranteed, TerminalUrl};
 use rustc_feature::UnstableFeatures;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
@@ -21,8 +21,8 @@ use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
 use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks};
 pub(crate) use rustc_session::config::{Options, UnstableOptions};
 use rustc_session::{Session, lint};
+use rustc_span::source_map;
 use rustc_span::symbol::sym;
-use rustc_span::{Span, source_map};
 use tracing::{debug, info};
 
 use crate::clean::inline::build_external_trait;
@@ -381,45 +381,10 @@ pub(crate) fn run_global_ctxt(
         );
     }
 
-    fn report_deprecated_attr(name: &str, dcx: DiagCtxtHandle<'_>, sp: Span) {
-        let mut msg =
-            dcx.struct_span_warn(sp, format!("the `#![doc({name})]` attribute is deprecated"));
-        msg.note(
-            "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
-            for more information",
-        );
-
-        if name == "no_default_passes" {
-            msg.help("`#![doc(no_default_passes)]` no longer functions; you may want to use `#![doc(document_private_items)]`");
-        } else if name.starts_with("passes") {
-            msg.help("`#![doc(passes = \"...\")]` no longer functions; you may want to use `#![doc(document_private_items)]`");
-        } else if name.starts_with("plugins") {
-            msg.warn("`#![doc(plugins = \"...\")]` no longer functions; see CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622>");
-        }
-
-        msg.emit();
-    }
-
     // Process all of the crate attributes, extracting plugin metadata along
     // with the passes which we are supposed to run.
     for attr in krate.module.attrs.lists(sym::doc) {
-        let dcx = ctxt.sess().dcx();
-
         let name = attr.name_or_empty();
-        // `plugins = "..."`, `no_default_passes`, and `passes = "..."` have no effect
-        if attr.is_word() && name == sym::no_default_passes {
-            report_deprecated_attr("no_default_passes", dcx, attr.span());
-        } else if attr.value_str().is_some() {
-            match name {
-                sym::passes => {
-                    report_deprecated_attr("passes = \"...\"", dcx, attr.span());
-                }
-                sym::plugins => {
-                    report_deprecated_attr("plugins = \"...\"", dcx, attr.span());
-                }
-                _ => (),
-            }
-        }
 
         if attr.is_word() && name == sym::document_private_items {
             ctxt.render_options.document_private = true;
diff --git a/src/rustdoc-json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml
index 7f7cd3672b7..14ff1d08816 100644
--- a/src/rustdoc-json-types/Cargo.toml
+++ b/src/rustdoc-json-types/Cargo.toml
@@ -11,7 +11,7 @@ default = ["rustc-hash"]
 
 [dependencies]
 serde = { version = "1.0", features = ["derive"] }
-rustc-hash = { version = "1.1.0", optional = true }
+rustc-hash = { version = "2.0", optional = true }
 
 [dev-dependencies]
 serde_json = "1.0"
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index c4e142342a8..f553a78d766 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -2,6 +2,18 @@
 //!
 //! These types are the public API exposed through the `--output-format json` flag. The [`Crate`]
 //! struct is the root of the JSON blob and all other items are contained within.
+//!
+//! We expose a `rustc-hash` feature that is disabled by default. This feature switches the
+//! [`std::collections::HashMap`] for [`rustc_hash::FxHashMap`] to improve the performance of said
+//! `HashMap` in specific situations.
+//!
+//! `cargo-semver-checks` for example, saw a [-3% improvement][1] when benchmarking using the
+//! `aws_sdk_ec2` JSON output (~500MB of JSON). As always, we recommend measuring the impact before
+//! turning this feature on, as [`FxHashMap`][2] only concerns itself with hash speed, and may
+//! increase the number of collisions.
+//!
+//! [1]: https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/rustc-hash.20and.20performance.20of.20rustdoc-types/near/474855731
+//! [2]: https://crates.io/crates/rustc-hash
 
 #[cfg(not(feature = "rustc-hash"))]
 use std::collections::HashMap;
@@ -305,10 +317,10 @@ pub enum AssocItemConstraintKind {
 // FIXME(aDotInTheVoid): Consider making this non-public in rustdoc-types.
 pub struct Id(pub u32);
 
-/// The fundamental kind of an item. Unlike [`ItemEnum`], this does not carry any aditional info.
+/// The fundamental kind of an item. Unlike [`ItemEnum`], this does not carry any additional info.
 ///
 /// Part of [`ItemSummary`].
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 #[serde(rename_all = "snake_case")]
 pub enum ItemKind {
     /// A module declaration, e.g. `mod foo;` or `mod foo {}`
@@ -698,7 +710,7 @@ pub enum Abi {
     Aapcs { unwind: bool },
     /// Can be specified as `extern "win64"`.
     Win64 { unwind: bool },
-    /// Can be specifed as `extern "sysv64"`.
+    /// Can be specified as `extern "sysv64"`.
     SysV64 { unwind: bool },
     /// Can be specified as `extern "system"`.
     System { unwind: bool },
@@ -892,7 +904,7 @@ pub enum GenericBound {
 }
 
 /// A set of modifiers applied to a trait.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 #[serde(rename_all = "snake_case")]
 pub enum TraitBoundModifier {
     /// Marks the absence of a modifier.
@@ -996,7 +1008,7 @@ pub enum Type {
     QualifiedPath {
         /// The name of the associated type in the parent type.
         ///
-        /// ```ignore (incomplete expresssion)
+        /// ```ignore (incomplete expression)
         /// <core::array::IntoIter<u32, 42> as Iterator>::Item
         /// //                                            ^^^^
         /// ```
@@ -1083,7 +1095,7 @@ pub struct FunctionSignature {
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub struct Trait {
     /// Whether the trait is marked `auto` and is thus implemented automatically
-    /// for all aplicable types.
+    /// for all applicable types.
     pub is_auto: bool,
     /// Whether the trait is marked as `unsafe`.
     pub is_unsafe: bool,
@@ -1193,7 +1205,7 @@ pub struct ProcMacro {
 }
 
 /// The way a [`ProcMacro`] is declared to be used.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 #[serde(rename_all = "snake_case")]
 pub enum MacroKind {
     /// A bang macro `foo!()`.
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index f4c00d8287d..00f83237224 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -190,15 +190,6 @@ fn is_same_generics<'tcx>(
         .enumerate()
         .skip(1) // skip `Self` implicit arg
         .all(|(arg_index, arg)| {
-            if [
-                implied_by_generics.host_effect_index,
-                implied_generics.host_effect_index,
-            ]
-            .contains(&Some(arg_index))
-            {
-                // skip host effect params in determining whether generics are same
-                return true;
-            }
             if let Some(ty) = arg.as_type() {
                 if let &ty::Param(ty::ParamTy { index, .. }) = ty.kind()
                     // `index == 0` means that it's referring to `Self`,
diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
index 22e9674714f..ae2c3e0491f 100644
--- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
@@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
             if let Some(range) = higher::Range::hir(index) {
                 // Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]
                 if let ty::Array(_, s) = ty.kind() {
-                    let size: u128 = if let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env) {
+                    let size: u128 = if let Some(size) = s.try_to_target_usize(cx.tcx) {
                         size.into()
                     } else {
                         return;
@@ -183,7 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
                             && let ty::Uint(utype) = cx.typeck_results().expr_ty(index).kind()
                             && *utype == ty::UintTy::Usize
                             && let ty::Array(_, s) = ty.kind()
-                            && let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env)
+                            && let Some(size) = s.try_to_target_usize(cx.tcx)
                         {
                             // get constant offset and check whether it is in bounds
                             let off = usize::try_from(off).unwrap();
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
index b134af500f5..022c6bcc70b 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
@@ -30,7 +30,7 @@ pub(super) fn check(
                 return;
             }
         } else if count
-            .try_eval_target_usize(cx.tcx, cx.param_env)
+            .try_to_target_usize(cx.tcx)
             .map_or(true, |x| x > 32)
             && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN)
         {
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index 68d063ad5e5..af089451759 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -472,7 +472,7 @@ fn is_array_length_equal_to_range(cx: &LateContext<'_>, start: &Expr<'_>, end: &
     let arr_ty = cx.typeck_results().expr_ty(arr).peel_refs();
 
     if let ty::Array(_, s) = arr_ty.kind() {
-        let size: u128 = if let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env) {
+        let size: u128 = if let Some(size) = s.try_to_target_usize(cx.tcx) {
             size.into()
         } else {
             return false;
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 214b8b0f379..2e6442156ef 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -207,7 +207,7 @@ fn is_end_eq_array_len<'tcx>(
     if let ExprKind::Lit(lit) = end.kind
         && let ast::LitKind::Int(end_int, _) = lit.node
         && let ty::Array(_, arr_len_const) = indexed_ty.kind()
-        && let Some(arr_len) = arr_len_const.try_eval_target_usize(cx.tcx, cx.param_env)
+        && let Some(arr_len) = arr_len_const.try_to_target_usize(cx.tcx)
     {
         return match limits {
             ast::RangeLimits::Closed => end_int.get() + 1 >= arr_len.into(),
diff --git a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
index 00e02e2a336..4c171e6d890 100644
--- a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
@@ -111,11 +111,7 @@ fn check_int_ty_and_feature(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     let expr_ty = cx.typeck_results().expr_ty(expr);
     match expr_ty.peel_refs().kind() {
         ty::Uint(_) => true,
-        ty::Int(_) => cx
-            .tcx
-            .features()
-            .declared_features
-            .contains(&Symbol::intern("int_roundings")),
+        ty::Int(_) => cx.tcx.features().enabled(Symbol::intern("int_roundings")),
 
         _ => false,
     }
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 2eda238ae8c..047d070a131 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -11,7 +11,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{Visitor, walk_pat};
 use rustc_hir::{Arm, Expr, ExprKind, HirId, Node, Pat, PatKind, QPath, StmtKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, AdtDef, ParamEnv, TyCtxt, TypeckResults, VariantDef};
+use rustc_middle::ty::{self, AdtDef, TyCtxt, TypeckResults, VariantDef};
 use rustc_span::{Span, sym};
 
 use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE};
@@ -67,7 +67,6 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tc
             if v.has_enum {
                 let cx = PatCtxt {
                     tcx: cx.tcx,
-                    param_env: cx.param_env,
                     typeck,
                     arena: DroplessArena::default(),
                 };
@@ -185,7 +184,6 @@ impl<'tcx> Visitor<'tcx> for PatVisitor<'tcx> {
 /// The context needed to manipulate a `PatState`.
 struct PatCtxt<'tcx> {
     tcx: TyCtxt<'tcx>,
-    param_env: ParamEnv<'tcx>,
     typeck: &'tcx TypeckResults<'tcx>,
     arena: DroplessArena,
 }
@@ -334,7 +332,7 @@ impl<'a> PatState<'a> {
                 if match *cx.typeck.pat_ty(pat).peel_refs().kind() {
                     ty::Adt(adt, _) => adt.is_enum() || (adt.is_struct() && !adt.non_enum_variant().fields.is_empty()),
                     ty::Tuple(tys) => !tys.is_empty(),
-                    ty::Array(_, len) => len.try_eval_target_usize(cx.tcx, cx.param_env) != Some(1),
+                    ty::Array(_, len) => len.try_to_target_usize(cx.tcx) != Some(1),
                     ty::Slice(..) => true,
                     _ => false,
                 } =>
@@ -353,7 +351,7 @@ impl<'a> PatState<'a> {
             },
             PatKind::Slice([sub_pat], _, []) | PatKind::Slice([], _, [sub_pat])
                 if let ty::Array(_, len) = *cx.typeck.pat_ty(pat).kind()
-                    && len.try_eval_target_usize(cx.tcx, cx.param_env) == Some(1) =>
+                    && len.try_to_target_usize(cx.tcx) == Some(1) =>
             {
                 self.add_pat(cx, sub_pat)
             },
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
index f198849c5c0..9d462bd1845 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
@@ -31,14 +31,14 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) ->
         // parameter.
         substs
             .const_at(1)
-            .try_eval_target_usize(cx.tcx, cx.param_env)
+            .try_to_target_usize(cx.tcx)
             .map(u128::from)
     } else if cx.tcx.is_diagnostic_item(sym::SliceIter, did)
         && let ExprKind::MethodCall(_, recv, ..) = iter.kind
     {
         if let ty::Array(_, len) = cx.typeck_results().expr_ty(recv).peel_refs().kind() {
             // For slice::Iter<'_, T>, the receiver might be an array literal: [1,2,3].iter().skip(..)
-            len.try_eval_target_usize(cx.tcx, cx.param_env).map(u128::from)
+            len.try_to_target_usize(cx.tcx).map(u128::from)
         } else if let Some(args) = VecArgs::hir(cx, expr_or_init(cx, recv)) {
             match args {
                 VecArgs::Vec(vec) => vec.len().try_into().ok(),
diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs
index cf0ee569f13..6e39e7be2c4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs
@@ -18,7 +18,7 @@ pub(super) fn derefs_to_slice<'tcx>(
             ty::Slice(_) => true,
             ty::Adt(..) if let Some(boxed) = ty.boxed_ty() => may_slice(cx, boxed),
             ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::Vec),
-            ty::Array(_, size) => size.try_eval_target_usize(cx.tcx, cx.param_env).is_some(),
+            ty::Array(_, size) => size.try_to_target_usize(cx.tcx).is_some(),
             ty::Ref(_, inner, _) => may_slice(cx, *inner),
             _ => false,
         }
diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
index db8c63892b8..52bb7c4bd68 100644
--- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
+++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::has_repr_attr;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{Const, FeedConstTy};
+use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -55,16 +55,14 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
 
 fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
     if let ItemKind::Struct(data, _) = &item.kind
-        // First check if last field is an array
         && let Some(last_field) = data.fields().last()
-        && let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind
-
-        // Then check if that array is zero-sized
-        && let length = Const::from_const_arg(cx.tcx, length, FeedConstTy::No)
-        && let length = length.try_eval_target_usize(cx.tcx, cx.param_env)
-        && let Some(length) = length
+        && let field_ty = cx
+            .tcx
+            .normalize_erasing_regions(cx.param_env, cx.tcx.type_of(last_field.def_id).instantiate_identity())
+        && let ty::Array(_, array_len) = *field_ty.kind()
+        && let Some(0) = array_len.try_to_target_usize(cx.tcx)
     {
-        length == 0
+        true
     } else {
         false
     }
diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
index 3da8a449a7c..07d0f59b91c 100644
--- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
@@ -190,7 +190,7 @@ fn all_bindings_are_for_conv<'tcx>(
                     tys.len() == elements.len() && tys.iter().chain(final_tys.iter().copied()).all_equal()
                 },
                 (ToType::Tuple, ty::Array(ty, len)) => {
-                    let Some(len) = len.try_eval_target_usize(cx.tcx, cx.param_env) else { return false };
+                    let Some(len) = len.try_to_target_usize(cx.tcx) else { return false };
                     len as usize == elements.len() && final_tys.iter().chain(once(ty)).all_equal()
                 },
                 _ => false,
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index a1cfb7be647..67c31abbdda 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -472,7 +472,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
             ExprKind::Tup(tup) => self.multi(tup).map(Constant::Tuple),
             ExprKind::Repeat(value, _) => {
                 let n = match self.typeck.expr_ty(e).kind() {
-                    ty::Array(_, n) => n.try_eval_target_usize(self.tcx, self.param_env)?,
+                    ty::Array(_, n) => n.try_to_target_usize(self.tcx)?,
                     _ => span_bug!(e.span, "typeck error"),
                 };
                 self.expr(value).map(|v| Constant::Repeat(Box::new(v), n))
@@ -553,7 +553,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
             ExprKind::Array(vec) => self.multi(vec).map(|v| v.is_empty()),
             ExprKind::Repeat(..) => {
                 if let ty::Array(_, n) = self.typeck.expr_ty(e).kind() {
-                    Some(n.try_eval_target_usize(self.tcx, self.param_env)? == 0)
+                    Some(n.try_to_target_usize(self.tcx)? == 0)
                 } else {
                     span_bug!(e.span, "typeck error");
                 }
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index b7a3569ccf0..07c3d0eada0 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -274,23 +274,10 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
         .map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into()))
         .collect::<Vec<_>>();
 
-    // If an effect arg was not specified, we need to specify it.
-    let effect_arg = if tcx
-        .generics_of(trait_id)
-        .host_effect_index
-        .is_some_and(|x| args.get(x - 1).is_none())
-    {
-        Some(GenericArg::from(callee_id.map_or(tcx.consts.true_, |def_id| {
-            tcx.expected_host_effect_param_for_body(def_id)
-        })))
-    } else {
-        None
-    };
-
     let trait_ref = TraitRef::new(
         tcx,
         trait_id,
-        [GenericArg::from(ty)].into_iter().chain(args).chain(effect_arg),
+        [GenericArg::from(ty)].into_iter().chain(args),
     );
 
     debug_assert_matches!(
@@ -989,7 +976,7 @@ pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 {
         (Ok(size), _) => size,
         (Err(_), ty::Tuple(list)) => list.iter().map(|t| approx_ty_size(cx, t)).sum(),
         (Err(_), ty::Array(t, n)) => {
-            n.try_eval_target_usize(cx.tcx, cx.param_env).unwrap_or_default() * approx_ty_size(cx, *t)
+            n.try_to_target_usize(cx.tcx).unwrap_or_default() * approx_ty_size(cx, *t)
         },
         (Err(_), ty::Adt(def, subst)) if def.is_struct() => def
             .variants()
@@ -1207,7 +1194,7 @@ impl<'tcx> InteriorMut<'tcx> {
         let chain = match *ty.kind() {
             ty::RawPtr(inner_ty, _) if !self.ignore_pointers => self.interior_mut_ty_chain(cx, inner_ty),
             ty::Ref(_, inner_ty, _) | ty::Slice(inner_ty) => self.interior_mut_ty_chain(cx, inner_ty),
-            ty::Array(inner_ty, size) if size.try_eval_target_usize(cx.tcx, cx.param_env) != Some(0) => {
+            ty::Array(inner_ty, size) if size.try_to_target_usize(cx.tcx) != Some(0) => {
                 self.interior_mut_ty_chain(cx, inner_ty)
             },
             ty::Tuple(fields) => fields.iter().find_map(|ty| self.interior_mut_ty_chain(cx, ty)),
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
index 41b424a8e5d..f7b6e1a186b 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
@@ -1,7 +1,7 @@
 #![warn(clippy::missing_const_for_fn)]
 #![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
-#![allow(unsupported_calling_conventions)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, abi_vectorcall)]
+
 
 use std::mem::transmute;
 
@@ -212,8 +212,8 @@ mod extern_fn {
     //~^ ERROR: this could be a `const fn`
     const extern "system-unwind" fn system_unwind() {}
     //~^ ERROR: this could be a `const fn`
-    pub const extern "stdcall" fn std_call() {}
+    pub const extern "vectorcall" fn std_call() {}
     //~^ ERROR: this could be a `const fn`
-    pub const extern "stdcall-unwind" fn std_call_unwind() {}
+    pub const extern "vectorcall-unwind" fn std_call_unwind() {}
     //~^ ERROR: this could be a `const fn`
 }
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
index 27593575a01..4866e321024 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
@@ -1,7 +1,7 @@
 #![warn(clippy::missing_const_for_fn)]
 #![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
-#![allow(unsupported_calling_conventions)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, abi_vectorcall)]
+
 
 use std::mem::transmute;
 
@@ -212,8 +212,8 @@ mod extern_fn {
     //~^ ERROR: this could be a `const fn`
     extern "system-unwind" fn system_unwind() {}
     //~^ ERROR: this could be a `const fn`
-    pub extern "stdcall" fn std_call() {}
+    pub extern "vectorcall" fn std_call() {}
     //~^ ERROR: this could be a `const fn`
-    pub extern "stdcall-unwind" fn std_call_unwind() {}
+    pub extern "vectorcall-unwind" fn std_call_unwind() {}
     //~^ ERROR: this could be a `const fn`
 }
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
index 12d97b17119..f28dec5c7f1 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
@@ -319,23 +319,23 @@ LL |     const extern "system-unwind" fn system_unwind() {}
 error: this could be a `const fn`
   --> tests/ui/missing_const_for_fn/could_be_const.rs:215:5
    |
-LL |     pub extern "stdcall" fn std_call() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     pub extern "vectorcall" fn std_call() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `const`
    |
-LL |     pub const extern "stdcall" fn std_call() {}
+LL |     pub const extern "vectorcall" fn std_call() {}
    |         +++++
 
 error: this could be a `const fn`
   --> tests/ui/missing_const_for_fn/could_be_const.rs:217:5
    |
-LL |     pub extern "stdcall-unwind" fn std_call_unwind() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     pub extern "vectorcall-unwind" fn std_call_unwind() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `const`
    |
-LL |     pub const extern "stdcall-unwind" fn std_call_unwind() {}
+LL |     pub const extern "vectorcall-unwind" fn std_call_unwind() {}
    |         +++++
 
 error: aborting due to 26 previous errors
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 1ee00a3a4e8..ff059940f7c 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -338,8 +338,8 @@ pub struct Config {
     /// created in `/<build_base>/rustfix_missing_coverage.txt`
     pub rustfix_coverage: bool,
 
-    /// whether to run `tidy` when a rustdoc test fails
-    pub has_tidy: bool,
+    /// whether to run `tidy` (html-tidy) when a rustdoc test fails
+    pub has_html_tidy: bool,
 
     /// whether to run `enzyme` autodiff tests
     pub has_enzyme: bool,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 099e620ffe0..d75cdefe635 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -57,7 +57,7 @@ impl EarlyProps {
             &mut poisoned,
             testfile,
             rdr,
-            &mut |DirectiveLine { directive: ln, .. }| {
+            &mut |DirectiveLine { raw_directive: ln, .. }| {
                 parse_and_update_aux(config, ln, &mut props.aux);
                 config.parse_and_update_revisions(testfile, ln, &mut props.revisions);
             },
@@ -344,8 +344,8 @@ impl TestProps {
                 &mut poisoned,
                 testfile,
                 file,
-                &mut |DirectiveLine { header_revision, directive: ln, .. }| {
-                    if header_revision.is_some() && header_revision != test_revision {
+                &mut |directive @ DirectiveLine { raw_directive: ln, .. }| {
+                    if !directive.applies_to_test_revision(test_revision) {
                         return;
                     }
 
@@ -678,28 +678,35 @@ impl TestProps {
     }
 }
 
-/// Extract an `(Option<line_revision>, directive)` directive from a line if comment is present.
-///
-/// See [`DirectiveLine`] for a diagram.
-pub fn line_directive<'line>(
+/// If the given line begins with the appropriate comment prefix for a directive,
+/// returns a struct containing various parts of the directive.
+fn line_directive<'line>(
+    line_number: usize,
     comment: &str,
     original_line: &'line str,
-) -> Option<(Option<&'line str>, &'line str)> {
+) -> Option<DirectiveLine<'line>> {
     // Ignore lines that don't start with the comment prefix.
     let after_comment = original_line.trim_start().strip_prefix(comment)?.trim_start();
 
+    let revision;
+    let raw_directive;
+
     if let Some(after_open_bracket) = after_comment.strip_prefix('[') {
         // A comment like `//@[foo]` only applies to revision `foo`.
-        let Some((line_revision, directive)) = after_open_bracket.split_once(']') else {
+        let Some((line_revision, after_close_bracket)) = after_open_bracket.split_once(']') else {
             panic!(
                 "malformed condition directive: expected `{comment}[foo]`, found `{original_line}`"
             )
         };
 
-        Some((Some(line_revision), directive.trim_start()))
+        revision = Some(line_revision);
+        raw_directive = after_close_bracket.trim_start();
     } else {
-        Some((None, after_comment))
-    }
+        revision = None;
+        raw_directive = after_comment;
+    };
+
+    Some(DirectiveLine { line_number, revision, raw_directive })
 }
 
 // To prevent duplicating the list of commmands between `compiletest`,`htmldocck` and `jsondocck`,
@@ -730,28 +737,37 @@ const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[
 const KNOWN_JSONDOCCK_DIRECTIVE_NAMES: &[&str] =
     &["count", "!count", "has", "!has", "is", "!is", "ismany", "!ismany", "set", "!set"];
 
-/// The broken-down contents of a line containing a test header directive,
+/// The (partly) broken-down contents of a line containing a test directive,
 /// which [`iter_header`] passes to its callback function.
 ///
 /// For example:
 ///
 /// ```text
 /// //@ compile-flags: -O
-///     ^^^^^^^^^^^^^^^^^ directive
+///     ^^^^^^^^^^^^^^^^^ raw_directive
 ///
 /// //@ [foo] compile-flags: -O
-///      ^^^                    header_revision
-///           ^^^^^^^^^^^^^^^^^ directive
+///      ^^^                    revision
+///           ^^^^^^^^^^^^^^^^^ raw_directive
 /// ```
 struct DirectiveLine<'ln> {
     line_number: usize,
-    /// Some header directives start with a revision name in square brackets
+    /// Some test directives start with a revision name in square brackets
     /// (e.g. `[foo]`), and only apply to that revision of the test.
     /// If present, this field contains the revision name (e.g. `foo`).
-    header_revision: Option<&'ln str>,
-    /// The main part of the header directive, after removing the comment prefix
+    revision: Option<&'ln str>,
+    /// The main part of the directive, after removing the comment prefix
     /// and the optional revision specifier.
-    directive: &'ln str,
+    ///
+    /// This is "raw" because the directive's name and colon-separated value
+    /// (if present) have not yet been extracted or checked.
+    raw_directive: &'ln str,
+}
+
+impl<'ln> DirectiveLine<'ln> {
+    fn applies_to_test_revision(&self, test_revision: Option<&str>) -> bool {
+        self.revision.is_none() || self.revision == test_revision
+    }
 }
 
 pub(crate) struct CheckDirectiveResult<'ln> {
@@ -819,8 +835,8 @@ fn iter_header(
             "ignore-cross-compile",
         ];
         // Process the extra implied directives, with a dummy line number of 0.
-        for directive in extra_directives {
-            it(DirectiveLine { line_number: 0, header_revision: None, directive });
+        for raw_directive in extra_directives {
+            it(DirectiveLine { line_number: 0, revision: None, raw_directive });
         }
     }
 
@@ -847,24 +863,21 @@ fn iter_header(
             return;
         }
 
-        let Some((header_revision, non_revisioned_directive_line)) = line_directive(comment, ln)
-        else {
+        let Some(directive_line) = line_directive(line_number, comment, ln) else {
             continue;
         };
 
         // Perform unknown directive check on Rust files.
         if testfile.extension().map(|e| e == "rs").unwrap_or(false) {
-            let directive_ln = non_revisioned_directive_line.trim();
-
             let CheckDirectiveResult { is_known_directive, trailing_directive } =
-                check_directive(directive_ln, mode, ln);
+                check_directive(directive_line.raw_directive, mode, ln);
 
             if !is_known_directive {
                 *poisoned = true;
 
                 eprintln!(
                     "error: detected unknown compiletest test directive `{}` in {}:{}",
-                    directive_ln,
+                    directive_line.raw_directive,
                     testfile.display(),
                     line_number,
                 );
@@ -888,11 +901,7 @@ fn iter_header(
             }
         }
 
-        it(DirectiveLine {
-            line_number,
-            header_revision,
-            directive: non_revisioned_directive_line,
-        });
+        it(directive_line);
     }
 }
 
@@ -1292,8 +1301,8 @@ pub fn make_test_description<R: Read>(
         &mut local_poisoned,
         path,
         src,
-        &mut |DirectiveLine { header_revision, directive: ln, line_number }| {
-            if header_revision.is_some() && header_revision != test_revision {
+        &mut |directive @ DirectiveLine { line_number, raw_directive: ln, .. }| {
+            if !directive.applies_to_test_revision(test_revision) {
                 return;
             }
 
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index d045c6fe053..7d6ede9bcda 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -230,14 +230,14 @@ pub fn parse_config(args: Vec<String>) -> Config {
     let run_ignored = matches.opt_present("ignored");
     let with_debug_assertions = matches.opt_present("with-debug-assertions");
     let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode");
-    let has_tidy = if mode == Mode::Rustdoc {
+    let has_html_tidy = if mode == Mode::Rustdoc {
         Command::new("tidy")
             .arg("--version")
             .stdout(Stdio::null())
             .status()
             .map_or(false, |status| status.success())
     } else {
-        // Avoid spawning an external command when we know tidy won't be used.
+        // Avoid spawning an external command when we know html-tidy won't be used.
         false
     };
     let has_enzyme = matches.opt_present("has-enzyme");
@@ -336,7 +336,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
             .opt_str("compare-mode")
             .map(|s| s.parse().expect("invalid --compare-mode provided")),
         rustfix_coverage: matches.opt_present("rustfix-coverage"),
-        has_tidy,
+        has_html_tidy,
         has_enzyme,
         channel: matches.opt_str("channel").unwrap(),
         git_hash: matches.opt_present("git-hash"),
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index b84dd956de0..2f0c7d8ddc5 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -18,7 +18,7 @@ fn main() {
 
     let config = Arc::new(parse_config(env::args().collect()));
 
-    if !config.has_tidy && config.mode == Mode::Rustdoc {
+    if !config.has_html_tidy && config.mode == Mode::Rustdoc {
         eprintln!("warning: `tidy` (html-tidy.org) is not installed; diffs will not be generated");
     }
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 5b8a96a54c2..36c5106ddad 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 use std::borrow::Cow;
 use std::collections::{HashMap, HashSet};
 use std::ffi::OsString;
@@ -1897,7 +1895,7 @@ impl<'test> TestCx<'test> {
     }
 
     fn compare_to_default_rustdoc(&mut self, out_dir: &Path) {
-        if !self.config.has_tidy {
+        if !self.config.has_html_tidy {
             return;
         }
         println!("info: generating a diff against nightly rustdoc");
diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs
index 985fe6381e8..c15422fb6f6 100644
--- a/src/tools/compiletest/src/runtest/debugger.rs
+++ b/src/tools/compiletest/src/runtest/debugger.rs
@@ -4,7 +4,6 @@ use std::io::{BufRead, BufReader};
 use std::path::{Path, PathBuf};
 
 use crate::common::Config;
-use crate::header::line_directive;
 use crate::runtest::ProcRes;
 
 /// Representation of information to invoke a debugger and check its output
@@ -24,7 +23,6 @@ impl DebuggerCommands {
         file: &Path,
         config: &Config,
         debugger_prefixes: &[&str],
-        rev: Option<&str>,
     ) -> Result<Self, String> {
         let directives = debugger_prefixes
             .iter()
@@ -39,18 +37,17 @@ impl DebuggerCommands {
         for (line_no, line) in reader.lines().enumerate() {
             counter += 1;
             let line = line.map_err(|e| format!("Error while parsing debugger commands: {}", e))?;
-            let (lnrev, line) = line_directive("//", &line).unwrap_or((None, &line));
-
-            // Skip any revision specific directive that doesn't match the current
-            // revision being tested
-            if lnrev.is_some() && lnrev != rev {
-                continue;
-            }
 
+            // Breakpoints appear on lines with actual code, typically at the end of the line.
             if line.contains("#break") {
                 breakpoint_lines.push(counter);
+                continue;
             }
 
+            let Some(line) = line.trim_start().strip_prefix("//").map(str::trim_start) else {
+                continue;
+            };
+
             for &(ref command_directive, ref check_directive) in &directives {
                 config
                     .parse_name_value_directive(&line, command_directive)
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
index bd0845b4524..c621c22ac99 100644
--- a/src/tools/compiletest/src/runtest/debuginfo.rs
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -66,13 +66,8 @@ impl TestCx<'_> {
         };
 
         // Parse debugger commands etc from test files
-        let dbg_cmds = DebuggerCommands::parse_from(
-            &self.testpaths.file,
-            self.config,
-            prefixes,
-            self.revision,
-        )
-        .unwrap_or_else(|e| self.fatal(&e));
+        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes)
+            .unwrap_or_else(|e| self.fatal(&e));
 
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
         let mut script_str = String::with_capacity(2048);
@@ -142,13 +137,8 @@ impl TestCx<'_> {
     }
 
     fn run_debuginfo_gdb_test_no_opt(&self) {
-        let dbg_cmds = DebuggerCommands::parse_from(
-            &self.testpaths.file,
-            self.config,
-            &["gdb"],
-            self.revision,
-        )
-        .unwrap_or_else(|e| self.fatal(&e));
+        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["gdb"])
+            .unwrap_or_else(|e| self.fatal(&e));
         let mut cmds = dbg_cmds.commands.join("\n");
 
         // compile test file (it should have 'compile-flags:-g' in the header)
@@ -413,13 +403,8 @@ impl TestCx<'_> {
         }
 
         // Parse debugger commands etc from test files
-        let dbg_cmds = DebuggerCommands::parse_from(
-            &self.testpaths.file,
-            self.config,
-            &["lldb"],
-            self.revision,
-        )
-        .unwrap_or_else(|e| self.fatal(&e));
+        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["lldb"])
+            .unwrap_or_else(|e| self.fatal(&e));
 
         // Write debugger script:
         // We don't want to hang when calling `quit` while the process is still running
diff --git a/src/tools/jsondoclint/Cargo.toml b/src/tools/jsondoclint/Cargo.toml
index 1318a1f4476..cc8ecefd530 100644
--- a/src/tools/jsondoclint/Cargo.toml
+++ b/src/tools/jsondoclint/Cargo.toml
@@ -9,7 +9,7 @@ edition = "2021"
 anyhow = "1.0.62"
 clap = { version = "4.0.15", features = ["derive"] }
 fs-err = "2.8.1"
-rustc-hash = "1.1.0"
+rustc-hash = "2.0.0"
 rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" }
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0.85"
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index fa77ab1e011..833e41df537 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -100,6 +100,7 @@ fn main() {
         links_ignored_external: 0,
         links_ignored_exception: 0,
         intra_doc_exceptions: 0,
+        has_broken_urls: false,
     };
     checker.walk(&docs, &mut report);
     report.report();
@@ -116,6 +117,8 @@ struct Checker {
 
 struct Report {
     errors: u32,
+    // Used to provide help message to remind the user to register a page in `SUMMARY.md`.
+    has_broken_urls: bool,
     start: Instant,
     html_files: u32,
     html_redirects: u32,
@@ -274,6 +277,7 @@ impl Checker {
                     report.links_ignored_exception += 1;
                 } else {
                     report.errors += 1;
+                    report.has_broken_urls = true;
                     println!("{}:{}: broken link - `{}`", pretty_path, i, target_pretty_path);
                 }
                 return;
@@ -438,6 +442,13 @@ impl Report {
         println!("number of links ignored due to exceptions: {}", self.links_ignored_exception);
         println!("number of intra doc links ignored: {}", self.intra_doc_exceptions);
         println!("errors found: {}", self.errors);
+
+        if self.has_broken_urls {
+            eprintln!(
+                "NOTE: if you are adding or renaming a markdown file in a mdBook, don't forget to \
+                register the page in SUMMARY.md"
+            );
+        }
     }
 }
 
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index 59776a484b5..0799b93dbb0 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -1,8 +1,7 @@
 use either::Either;
 use rustc_apfloat::{Float, Round};
-use rustc_middle::ty::FloatTy;
-use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
-use rustc_middle::{mir, ty};
+use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::{mir, ty, ty::FloatTy};
 use rustc_span::{Symbol, sym};
 use rustc_target::abi::{Endian, HasDataLayout};
 
@@ -633,9 +632,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
                 let index = generic_args[2]
                     .expect_const()
-                    .eval(*this.tcx, this.param_env(), this.tcx.span)
+                    .try_to_valtree()
                     .unwrap()
-                    .1
+                    .0
                     .unwrap_branch();
                 let index_len = index.len();
 
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 9814858beaa..660f2e493bc 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -11,8 +11,6 @@
 #![feature(let_chains)]
 #![feature(trait_upcasting)]
 #![feature(strict_overflow_ops)]
-#![feature(strict_provenance)]
-#![feature(exposed_provenance)]
 #![feature(pointer_is_aligned_to)]
 #![feature(unqualified_local_imports)]
 // Configure clippy and other lints
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs
index 3e20b8da622..c63e926376d 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs
@@ -1,4 +1,3 @@
-#![feature(strict_provenance)]
 use std::ptr;
 
 fn direct_raw(x: *const (i32, i32)) -> *const i32 {
diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.rs b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.rs
index fa40f942b8f..b22c1b4c5e8 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.rs
+++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.rs
@@ -1,6 +1,5 @@
 // Should be caught even without retagging
 //@compile-flags: -Zmiri-disable-stacked-borrows
-#![feature(strict_provenance)]
 use std::ptr::{self, addr_of_mut};
 
 // Deref'ing a dangling raw pointer is fine, but for a dangling box it is not.
diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.rs b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.rs
index 036ef2580a8..eeab7c333e5 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.rs
+++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.rs
@@ -1,6 +1,5 @@
 // Should be caught even without retagging
 //@compile-flags: -Zmiri-disable-stacked-borrows
-#![feature(strict_provenance)]
 use std::ptr::{self, addr_of_mut};
 
 // Deref'ing a dangling raw pointer is fine, but for a dangling reference it is not.
diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs
index c307dfddb6c..0acda559d3a 100644
--- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs
+++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs
@@ -1,4 +1,3 @@
-#![feature(strict_provenance)]
 use core::ptr;
 
 fn main() {
diff --git a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.rs b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.rs
index d6bbfd7d94c..da381596284 100644
--- a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.rs
+++ b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.rs
@@ -1,4 +1,3 @@
-#![feature(strict_provenance)]
 use std::mem;
 
 #[repr(C, usize)]
diff --git a/src/tools/miri/tests/fail/provenance/provenance_transmute.rs b/src/tools/miri/tests/fail/provenance/provenance_transmute.rs
index bc5dd53dcf5..d72f10530d7 100644
--- a/src/tools/miri/tests/fail/provenance/provenance_transmute.rs
+++ b/src/tools/miri/tests/fail/provenance/provenance_transmute.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-permissive-provenance
-#![feature(strict_provenance)]
 
 use std::mem;
 
diff --git a/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.rs b/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.rs
index f89378fcb3c..a43ba13e13d 100644
--- a/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.rs
+++ b/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-permissive-provenance
-#![feature(strict_provenance, exposed_provenance)]
 
 fn main() {
     let x: i32 = 3;
diff --git a/src/tools/miri/tests/fail/provenance/ptr_invalid.rs b/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
index 512473cd894..d4479f32e56 100644
--- a/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
+++ b/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
@@ -1,4 +1,3 @@
-#![feature(strict_provenance, exposed_provenance)]
 
 // Ensure that a `ptr::without_provenance` ptr is truly invalid.
 fn main() {
diff --git a/src/tools/miri/tests/fail/provenance/ptr_invalid_offset.rs b/src/tools/miri/tests/fail/provenance/ptr_invalid_offset.rs
index c8be521ef82..53a16ce5d1b 100644
--- a/src/tools/miri/tests/fail/provenance/ptr_invalid_offset.rs
+++ b/src/tools/miri/tests/fail/provenance/ptr_invalid_offset.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-strict-provenance
-#![feature(strict_provenance)]
 
 fn main() {
     let x = 22;
diff --git a/src/tools/miri/tests/fail/provenance/strict_provenance_cast.rs b/src/tools/miri/tests/fail/provenance/strict_provenance_cast.rs
index d7b54f640f6..4674ba841b4 100644
--- a/src/tools/miri/tests/fail/provenance/strict_provenance_cast.rs
+++ b/src/tools/miri/tests/fail/provenance/strict_provenance_cast.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-strict-provenance
-#![feature(exposed_provenance)]
 
 fn main() {
     let addr = &0 as *const i32 as usize;
diff --git a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
index 608ab718919..dfd7d4bb0be 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-permissive-provenance
-#![feature(exposed_provenance)]
 
 // If we have only exposed read-only pointers, doing a write through a wildcard ptr should fail.
 
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs
index e075db66039..009ce1eb882 100644
--- a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs
+++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs
@@ -1,6 +1,5 @@
 //@compile-flags: -Zmiri-symbolic-alignment-check
 //@revisions: call_unaligned_ptr read_unaligned_ptr
-#![feature(strict_provenance)]
 
 #[path = "../../utils/mod.rs"]
 mod utils;
diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs
index 954571f4a22..1cf70d9d9a3 100644
--- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs
+++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs
@@ -1,7 +1,6 @@
 //@compile-flags: -Zmiri-disable-validation
 //@error-in-other-file: memory is uninitialized at [0x4..0x8]
 //@normalize-stderr-test: "a[0-9]+" -> "ALLOC"
-#![feature(strict_provenance)]
 #![allow(dropping_copy_types)]
 
 // Test printing allocations that contain single-byte provenance.
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-affinity.rs b/src/tools/miri/tests/pass-dep/libc/libc-affinity.rs
index 8aa8c7dcb8e..3c4311efc4c 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-affinity.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-affinity.rs
@@ -3,7 +3,6 @@
 //@compile-flags: -Zmiri-disable-isolation -Zmiri-num-cpus=4
 #![feature(io_error_more)]
 #![feature(pointer_is_aligned_to)]
-#![feature(strict_provenance)]
 
 use std::mem::{size_of, size_of_val};
 
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
index 3ea34513376..288c1d41f30 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
@@ -1,6 +1,5 @@
 //@only-target: linux
 
-#![feature(strict_provenance)]
 use std::convert::TryInto;
 
 fn main() {
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
index c399616b9ae..10be78798a6 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
@@ -1,4 +1,4 @@
-#![feature(strict_provenance, pointer_is_aligned_to)]
+#![feature(pointer_is_aligned_to)]
 use std::{mem, ptr, slice};
 
 fn test_memcpy() {
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs
index f3261eaa43c..f07007fa705 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs
@@ -2,7 +2,6 @@
 //@compile-flags: -Zmiri-disable-isolation
 #![feature(io_error_more)]
 #![feature(pointer_is_aligned_to)]
-#![feature(strict_provenance)]
 
 use std::mem::transmute;
 
diff --git a/src/tools/miri/tests/pass-dep/libc/mmap.rs b/src/tools/miri/tests/pass-dep/libc/mmap.rs
index db305acbf4a..bfd840d2fb8 100644
--- a/src/tools/miri/tests/pass-dep/libc/mmap.rs
+++ b/src/tools/miri/tests/pass-dep/libc/mmap.rs
@@ -1,6 +1,5 @@
 //@ignore-target: windows # No mmap on Windows
 //@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance
-#![feature(strict_provenance)]
 
 use std::io::Error;
 use std::{ptr, slice};
diff --git a/src/tools/miri/tests/pass/align_offset_symbolic.rs b/src/tools/miri/tests/pass/align_offset_symbolic.rs
index 9647277821f..c836a3b07cb 100644
--- a/src/tools/miri/tests/pass/align_offset_symbolic.rs
+++ b/src/tools/miri/tests/pass/align_offset_symbolic.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-symbolic-alignment-check
-#![feature(strict_provenance)]
 
 use std::mem;
 
diff --git a/src/tools/miri/tests/pass/atomic.rs b/src/tools/miri/tests/pass/atomic.rs
index f84fe825d01..2b2e89e6d70 100644
--- a/src/tools/miri/tests/pass/atomic.rs
+++ b/src/tools/miri/tests/pass/atomic.rs
@@ -2,7 +2,7 @@
 //@[tree]compile-flags: -Zmiri-tree-borrows
 //@compile-flags: -Zmiri-strict-provenance
 
-#![feature(strict_provenance, strict_provenance_atomic_ptr)]
+#![feature(strict_provenance_atomic_ptr)]
 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
 #![allow(static_mut_refs)]
 
diff --git a/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs b/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
index 0a61db960c1..63329118283 100644
--- a/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
+++ b/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
@@ -5,7 +5,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
 #![feature(allocator_api)]
-#![feature(strict_provenance)]
 
 use std::alloc::{AllocError, Allocator, Layout};
 use std::cell::{Cell, UnsafeCell};
diff --git a/src/tools/miri/tests/pass/concurrency/address_reuse_happens_before.rs b/src/tools/miri/tests/pass/concurrency/address_reuse_happens_before.rs
index 255f4061abc..a293dd0bef1 100644
--- a/src/tools/miri/tests/pass/concurrency/address_reuse_happens_before.rs
+++ b/src/tools/miri/tests/pass/concurrency/address_reuse_happens_before.rs
@@ -1,7 +1,6 @@
 //! Regression test for <https://github.com/rust-lang/miri/issues/3450>:
 //! When the address gets reused, there should be a happens-before relation.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=1.0
-#![feature(strict_provenance)]
 #![feature(sync_unsafe_cell)]
 
 use std::cell::SyncUnsafeCell;
diff --git a/src/tools/miri/tests/pass/const-addrs.rs b/src/tools/miri/tests/pass/const-addrs.rs
index 727c67ebfb5..af68b28b2b8 100644
--- a/src/tools/miri/tests/pass/const-addrs.rs
+++ b/src/tools/miri/tests/pass/const-addrs.rs
@@ -7,7 +7,6 @@
 // MIR inlining will put every evaluation of the const we're repeatedly evaluating into the same
 // stack frame, breaking this test.
 //@compile-flags: -Zinline-mir=no
-#![feature(strict_provenance)]
 
 const EVALS: usize = 256;
 
diff --git a/src/tools/miri/tests/pass/drop_type_without_drop_glue.rs b/src/tools/miri/tests/pass/drop_type_without_drop_glue.rs
index 43ddc8a4d8b..2f8665e8d62 100644
--- a/src/tools/miri/tests/pass/drop_type_without_drop_glue.rs
+++ b/src/tools/miri/tests/pass/drop_type_without_drop_glue.rs
@@ -1,4 +1,4 @@
-#![feature(custom_mir, core_intrinsics, strict_provenance)]
+#![feature(custom_mir, core_intrinsics)]
 use std::intrinsics::mir::*;
 
 // The `Drop` terminator on a type with no drop glue should be a NOP.
diff --git a/src/tools/miri/tests/pass/extern_types.rs b/src/tools/miri/tests/pass/extern_types.rs
index eade5c6ac08..08e9caf4f1c 100644
--- a/src/tools/miri/tests/pass/extern_types.rs
+++ b/src/tools/miri/tests/pass/extern_types.rs
@@ -1,6 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
-#![feature(extern_types, strict_provenance)]
+#![feature(extern_types)]
 
 use std::ptr;
 
diff --git a/src/tools/miri/tests/pass/provenance.rs b/src/tools/miri/tests/pass/provenance.rs
index 2e4d240cc48..8c52b703190 100644
--- a/src/tools/miri/tests/pass/provenance.rs
+++ b/src/tools/miri/tests/pass/provenance.rs
@@ -1,6 +1,5 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
-#![feature(strict_provenance)]
 use std::{mem, ptr};
 
 const PTR_SIZE: usize = mem::size_of::<&i32>();
diff --git a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
index ade5f537785..9a76c8dd349 100644
--- a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
+++ b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
@@ -2,7 +2,6 @@
 // Tree Borrows doesn't support int2ptr casts, but let's make sure we don't immediately crash either.
 //@[tree]compile-flags: -Zmiri-tree-borrows
 //@[stack]compile-flags: -Zmiri-permissive-provenance
-#![feature(strict_provenance, exposed_provenance)]
 
 use std::ptr;
 
diff --git a/src/tools/miri/tests/pass/ptr_raw.rs b/src/tools/miri/tests/pass/ptr_raw.rs
index dcf13d97ce3..c958dfddf69 100644
--- a/src/tools/miri/tests/pass/ptr_raw.rs
+++ b/src/tools/miri/tests/pass/ptr_raw.rs
@@ -1,4 +1,3 @@
-#![feature(strict_provenance)]
 use std::mem;
 use std::ptr::{self, addr_of};
 
diff --git a/src/tools/miri/tests/pass/shims/ptr_mask.rs b/src/tools/miri/tests/pass/shims/ptr_mask.rs
index fb8bb6b13db..6872ba577d2 100644
--- a/src/tools/miri/tests/pass/shims/ptr_mask.rs
+++ b/src/tools/miri/tests/pass/shims/ptr_mask.rs
@@ -1,5 +1,4 @@
 #![feature(ptr_mask)]
-#![feature(strict_provenance)]
 
 fn main() {
     let v: u32 = 0xABCDABCD;
diff --git a/src/tools/miri/tests/pass/slices.rs b/src/tools/miri/tests/pass/slices.rs
index 39e1d1cb97f..dd18a061cdd 100644
--- a/src/tools/miri/tests/pass/slices.rs
+++ b/src/tools/miri/tests/pass/slices.rs
@@ -4,7 +4,6 @@
 #![feature(slice_as_chunks)]
 #![feature(slice_partition_dedup)]
 #![feature(layout_for_ptr)]
-#![feature(strict_provenance)]
 
 use std::{ptr, slice};
 
diff --git a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
index c89d79b42e3..8a05fca3f31 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-permissive-provenance
-#![feature(exposed_provenance)]
 use std::ptr;
 
 // Just to make sure that casting a ref to raw, to int and back to raw
diff --git a/src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs b/src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs
index 1478b21d6c1..e507f49b955 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs
@@ -2,7 +2,6 @@
 // printing, not how it interacts with the GC.
 //@compile-flags: -Zmiri-permissive-provenance -Zmiri-provenance-gc=0
 
-#![feature(strict_provenance)]
 use std::alloc::{self, Layout};
 use std::mem::ManuallyDrop;
 
diff --git a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
index 55356814a1a..b0f53283cda 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-permissive-provenance
-#![feature(exposed_provenance)]
 
 use std::ptr;
 
diff --git a/src/tools/miri/tests/pass/transmute_ptr.rs b/src/tools/miri/tests/pass/transmute_ptr.rs
index ce6d86b7068..0944781c6de 100644
--- a/src/tools/miri/tests/pass/transmute_ptr.rs
+++ b/src/tools/miri/tests/pass/transmute_ptr.rs
@@ -1,6 +1,5 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
-#![feature(strict_provenance)]
 use std::{mem, ptr};
 
 fn t1() {
diff --git a/src/tools/miri/tests/pass/underscore_pattern.rs b/src/tools/miri/tests/pass/underscore_pattern.rs
index f59bb9f5c82..2f203bdc01e 100644
--- a/src/tools/miri/tests/pass/underscore_pattern.rs
+++ b/src/tools/miri/tests/pass/underscore_pattern.rs
@@ -1,5 +1,4 @@
 // Various tests ensuring that underscore patterns really just construct the place, but don't check its contents.
-#![feature(strict_provenance)]
 #![feature(never_type)]
 
 use std::ptr;
diff --git a/src/tools/miri/tests/pass/zero-sized-accesses-and-offsets.rs b/src/tools/miri/tests/pass/zero-sized-accesses-and-offsets.rs
index a3356b682a6..6c0d9bc253a 100644
--- a/src/tools/miri/tests/pass/zero-sized-accesses-and-offsets.rs
+++ b/src/tools/miri/tests/pass/zero-sized-accesses-and-offsets.rs
@@ -1,5 +1,4 @@
 //! Tests specific for <https://github.com/rust-lang/rust/issues/117945>: zero-sized operations.
-#![feature(strict_provenance)]
 
 use std::ptr;
 
diff --git a/src/tools/miropt-test-tools/src/lib.rs b/src/tools/miropt-test-tools/src/lib.rs
index 4317f23a822..41b53d2ad0e 100644
--- a/src/tools/miropt-test-tools/src/lib.rs
+++ b/src/tools/miropt-test-tools/src/lib.rs
@@ -129,6 +129,9 @@ pub fn files_for_miropt_test(
 
             out.push(MiroptTestFile { expected_file, from_file, to_file });
         }
+        if !run_filecheck && l.trim_start().starts_with("// CHECK") {
+            panic!("error: test contains filecheck directive but is marked `skip-filecheck`");
+        }
     }
 
     MiroptTest { run_filecheck, suffix, files: out, passes }
diff --git a/src/tools/rust-analyzer/.editorconfig b/src/tools/rust-analyzer/.editorconfig
index e337066f7ea..6bb743a6736 100644
--- a/src/tools/rust-analyzer/.editorconfig
+++ b/src/tools/rust-analyzer/.editorconfig
@@ -13,5 +13,5 @@ max_line_length = 100
 [*.md]
 indent_size = 2
 
-[*.{yml, yaml}]
+[*.{yml,yaml}]
 indent_size = 2
diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml
index 6d3e488bb08..5cf4a8fd439 100644
--- a/src/tools/rust-analyzer/.github/workflows/ci.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml
@@ -104,11 +104,11 @@ jobs:
         if: matrix.os == 'ubuntu-latest'
         run: target/${{ matrix.target }}/debug/rust-analyzer analysis-stats .
 
-      - name: Run analysis-stats on rust std library
+      - name: Run analysis-stats on the rust standard libraries
         if: matrix.os == 'ubuntu-latest'
         env:
-          RUSTC_BOOTSTRAP: 1
-        run: target/${{ matrix.target }}/debug/rust-analyzer analysis-stats --with-deps $(rustc --print sysroot)/lib/rustlib/src/rust/library/std
+            RUSTC_BOOTSTRAP: 1
+        run: target/${{ matrix.target }}/debug/rust-analyzer analysis-stats --with-deps --no-sysroot --no-test $(rustc --print sysroot)/lib/rustlib/src/rust/library/
 
       - name: clippy
         if: matrix.os == 'windows-latest'
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 4a6da47a47d..fd569571b38 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -73,7 +73,7 @@ dependencies = [
  "intern",
  "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lz4_flex",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "salsa",
  "semver",
  "span",
@@ -161,7 +161,7 @@ dependencies = [
  "expect-test",
  "intern",
  "oorandom",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "syntax",
  "syntax-bridge",
  "tt",
@@ -216,7 +216,7 @@ dependencies = [
  "chalk-derive",
  "chalk-ir",
  "chalk-solve",
- "rustc-hash",
+ "rustc-hash 1.1.0",
  "tracing",
 ]
 
@@ -232,7 +232,7 @@ dependencies = [
  "indexmap",
  "itertools",
  "petgraph",
- "rustc-hash",
+ "rustc-hash 1.1.0",
  "tracing",
 ]
 
@@ -513,7 +513,7 @@ dependencies = [
  "hir-ty",
  "intern",
  "itertools",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "smallvec",
  "span",
  "stdx",
@@ -547,7 +547,7 @@ dependencies = [
  "mbe",
  "ra-ap-rustc_abi",
  "ra-ap-rustc_parse_format",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "rustc_apfloat",
  "smallvec",
  "span",
@@ -577,7 +577,7 @@ dependencies = [
  "limit",
  "mbe",
  "parser",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "smallvec",
  "span",
  "stdx",
@@ -616,7 +616,7 @@ dependencies = [
  "ra-ap-rustc_abi",
  "ra-ap-rustc_index",
  "ra-ap-rustc_pattern_analysis",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "rustc_apfloat",
  "scoped-tls",
  "smallvec",
@@ -731,13 +731,13 @@ dependencies = [
  "indexmap",
  "itertools",
  "limit",
- "line-index 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "line-index 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr",
  "nohash-hasher",
  "parser",
  "profile",
  "rayon",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "span",
  "stdx",
  "syntax",
@@ -834,7 +834,7 @@ version = "0.0.0"
 dependencies = [
  "dashmap",
  "hashbrown",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "sptr",
  "triomphe",
 ]
@@ -939,7 +939,7 @@ version = "0.0.0"
 
 [[package]]
 name = "line-index"
-version = "0.1.1"
+version = "0.1.2"
 dependencies = [
  "nohash-hasher",
  "oorandom",
@@ -948,9 +948,9 @@ dependencies = [
 
 [[package]]
 name = "line-index"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67d61795376ae2683928c218fda7d7d7db136fd38c06b7552904667f0d55580a"
+checksum = "3e27e0ed5a392a7f5ba0b3808a2afccff16c64933312c84b57618b49d1209bd2"
 dependencies = [
  "nohash-hasher",
  "text-size",
@@ -1051,7 +1051,7 @@ dependencies = [
  "intern",
  "parser",
  "ra-ap-rustc_lexer",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "smallvec",
  "span",
  "stdx",
@@ -1345,7 +1345,7 @@ dependencies = [
  "indexmap",
  "intern",
  "paths",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "serde",
  "serde_json",
  "span",
@@ -1435,7 +1435,7 @@ dependencies = [
  "itertools",
  "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "paths",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "semver",
  "serde",
  "serde_json",
@@ -1497,9 +1497,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_abi"
-version = "0.71.0"
+version = "0.73.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6999d098000b98415939f13158dac78cb3eeeb7b0c073847f3e4b623866e27c"
+checksum = "879ece0781e3c1cb670b9f29775c81a43a16db789d1296fad6bc5c74065b2fac"
 dependencies = [
  "bitflags 2.6.0",
  "ra-ap-rustc_index",
@@ -1508,9 +1508,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_index"
-version = "0.71.0"
+version = "0.73.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae9fb312d942817dab10790881f555928c1f6a11a85186e8e573ad4a86c7d3be"
+checksum = "6910087ff89bb9f3db114bfcd86b5139042731fe7278d3ff4ceaa69a140154a7"
 dependencies = [
  "arrayvec",
  "ra-ap-rustc_index_macros",
@@ -1519,9 +1519,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_index_macros"
-version = "0.71.0"
+version = "0.73.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "766e3990eb1066a06deefc561b5a01b32ca5c9211feea31cbf4ed50611519872"
+checksum = "3b6f7bd12b678fbb37444ba77f3b0cfc13b7394a6dc7b0c799491fc9df0a9997"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1530,9 +1530,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_lexer"
-version = "0.71.0"
+version = "0.73.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4afa98eb7889c137d5a3f1cd189089e16da04d1e4837d358a67aa3dab10ffbe"
+checksum = "119bc05b5b6bc3e7f5b67ce8b8080e185da94bd83c447f91b6b3f3ecf60cbab1"
 dependencies = [
  "unicode-properties",
  "unicode-xid",
@@ -1540,9 +1540,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_parse_format"
-version = "0.71.0"
+version = "0.73.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9234c96ffb0565286790407fb7eb7f55ebf69267de4db382fdec0a17f14b0e2"
+checksum = "70ed6150ae71d905c064dc88d7824ebb0fa81083f45d7477cba7b57176f2f635"
 dependencies = [
  "ra-ap-rustc_index",
  "ra-ap-rustc_lexer",
@@ -1550,12 +1550,12 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_pattern_analysis"
-version = "0.71.0"
+version = "0.73.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "273d5f72926a58c7eea27aebc898d1d5b32d23d2342f692a94a2cf8746aa4a2f"
+checksum = "6e830862a0ec85fce211d34735315686bb8d6a12d418d6d735fb534aa1cd3293"
 dependencies = [
  "ra-ap-rustc_index",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "rustc_apfloat",
  "smallvec",
  "tracing",
@@ -1640,7 +1640,7 @@ dependencies = [
  "countme",
  "hashbrown",
  "memoffset",
- "rustc-hash",
+ "rustc-hash 1.1.0",
  "text-size",
 ]
 
@@ -1680,7 +1680,7 @@ dependencies = [
  "profile",
  "project-model",
  "rayon",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "scip",
  "semver",
  "serde",
@@ -1718,6 +1718,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 
 [[package]]
+name = "rustc-hash"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
+
+[[package]]
 name = "rustc_apfloat"
 version = "0.2.1+llvm-462a31f5a5ab"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1746,7 +1752,7 @@ dependencies = [
  "oorandom",
  "parking_lot",
  "rand",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "salsa-macros",
  "smallvec",
  "tracing",
@@ -1898,7 +1904,7 @@ version = "0.0.0"
 dependencies = [
  "hashbrown",
  "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "salsa",
  "stdx",
  "syntax",
@@ -1967,7 +1973,7 @@ dependencies = [
  "ra-ap-rustc_lexer",
  "rayon",
  "rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "rustc_apfloat",
  "smol_str",
  "stdx",
@@ -1983,7 +1989,7 @@ version = "0.0.0"
 dependencies = [
  "intern",
  "parser",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "span",
  "stdx",
  "syntax",
@@ -2000,7 +2006,7 @@ dependencies = [
  "cfg",
  "hir-expand",
  "intern",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "span",
  "stdx",
  "test-utils",
@@ -2014,7 +2020,7 @@ dependencies = [
  "dissimilar",
  "paths",
  "profile",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "stdx",
  "text-size",
  "tracing",
@@ -2361,7 +2367,7 @@ dependencies = [
  "indexmap",
  "nohash-hasher",
  "paths",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "stdx",
  "tracing",
 ]
@@ -2374,7 +2380,7 @@ dependencies = [
  "notify",
  "paths",
  "rayon",
- "rustc-hash",
+ "rustc-hash 2.0.0",
  "stdx",
  "tracing",
  "vfs",
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 8c099f324b4..9db62de9abf 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -85,18 +85,18 @@ tt = { path = "./crates/tt", version = "0.0.0" }
 vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
 vfs = { path = "./crates/vfs", version = "0.0.0" }
 
-ra-ap-rustc_lexer = { version = "0.71.0", default-features = false }
-ra-ap-rustc_parse_format = { version = "0.71.0", default-features = false }
-ra-ap-rustc_index = { version = "0.71.0", default-features = false }
-ra-ap-rustc_abi = { version = "0.71.0", default-features = false }
-ra-ap-rustc_pattern_analysis = { version = "0.71.0", default-features = false }
+ra-ap-rustc_lexer = { version = "0.73", default-features = false }
+ra-ap-rustc_parse_format = { version = "0.73", default-features = false }
+ra-ap-rustc_index = { version = "0.73", default-features = false }
+ra-ap-rustc_abi = { version = "0.73", default-features = false }
+ra-ap-rustc_pattern_analysis = { version = "0.73", default-features = false }
 
 # local crates that aren't published to crates.io. These should not have versions.
 test-fixture = { path = "./crates/test-fixture" }
 test-utils = { path = "./crates/test-utils" }
 
 # In-tree crates that are published separately and follow semver. See lib/README.md
-line-index = { version = "0.1.1" }
+line-index = { version = "0.1.2" }
 la-arena = { version = "0.3.1" }
 lsp-server = { version = "0.7.6" }
 
@@ -136,7 +136,7 @@ process-wrap = { version = "8.0.2", features = ["std"] }
 pulldown-cmark-to-cmark = "10.0.4"
 pulldown-cmark = { version = "0.9.0", default-features = false }
 rayon = "1.8.0"
-rustc-hash = "1.1.0"
+rustc-hash = "2.0.0"
 semver = "1.0.14"
 serde = { version = "1.0.192", features = ["derive"] }
 serde_json = "1.0.108"
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index 3ecb57c7567..263fad51d78 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -148,6 +148,10 @@ impl FunctionData {
         self.flags.contains(FnFlags::HAS_UNSAFE_KW)
     }
 
+    pub fn is_safe(&self) -> bool {
+        self.flags.contains(FnFlags::HAS_SAFE_KW)
+    }
+
     pub fn is_varargs(&self) -> bool {
         self.flags.contains(FnFlags::IS_VARARGS)
     }
@@ -567,6 +571,8 @@ pub struct StaticData {
     pub visibility: RawVisibility,
     pub mutable: bool,
     pub is_extern: bool,
+    pub has_safe_kw: bool,
+    pub has_unsafe_kw: bool,
 }
 
 impl StaticData {
@@ -581,6 +587,8 @@ impl StaticData {
             visibility: item_tree[statik.visibility].clone(),
             mutable: statik.mutable,
             is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
+            has_safe_kw: statik.has_safe_kw,
+            has_unsafe_kw: statik.has_unsafe_kw,
         })
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index f16230e1dc3..7cb833fdce7 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -754,6 +754,7 @@ bitflags::bitflags! {
         const HAS_ASYNC_KW = 1 << 4;
         const HAS_UNSAFE_KW = 1 << 5;
         const IS_VARARGS = 1 << 6;
+        const HAS_SAFE_KW = 1 << 7;
     }
 }
 
@@ -822,7 +823,10 @@ pub struct Const {
 pub struct Static {
     pub name: Name,
     pub visibility: RawVisibilityId,
+    // TODO: use bitflags when we have more flags
     pub mutable: bool,
+    pub has_safe_kw: bool,
+    pub has_unsafe_kw: bool,
     pub type_ref: Interned<TypeRef>,
     pub ast_id: FileAstId<ast::Static>,
 }
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 7aac383ab47..431a7f66f40 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
@@ -440,6 +440,9 @@ impl<'a> Ctx<'a> {
         if func.unsafe_token().is_some() {
             flags |= FnFlags::HAS_UNSAFE_KW;
         }
+        if func.safe_token().is_some() {
+            flags |= FnFlags::HAS_SAFE_KW;
+        }
         if has_var_args {
             flags |= FnFlags::IS_VARARGS;
         }
@@ -484,8 +487,11 @@ impl<'a> Ctx<'a> {
         let type_ref = self.lower_type_ref_opt(static_.ty());
         let visibility = self.lower_visibility(static_);
         let mutable = static_.mut_token().is_some();
+        let has_safe_kw = static_.safe_token().is_some();
+        let has_unsafe_kw = static_.unsafe_token().is_some();
         let ast_id = self.source_ast_id_map.ast_id(static_);
-        let res = Static { name, visibility, mutable, type_ref, ast_id };
+        let res =
+            Static { name, visibility, mutable, type_ref, ast_id, has_safe_kw, has_unsafe_kw };
         Some(id(self.data().statics.alloc(res)))
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
index b5a65abce86..9dce28b2e49 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
@@ -278,6 +278,9 @@ impl Printer<'_> {
                 if flags.contains(FnFlags::HAS_UNSAFE_KW) {
                     w!(self, "unsafe ");
                 }
+                if flags.contains(FnFlags::HAS_SAFE_KW) {
+                    w!(self, "safe ");
+                }
                 if let Some(abi) = abi {
                     w!(self, "extern \"{}\" ", abi);
                 }
@@ -379,9 +382,23 @@ impl Printer<'_> {
                 wln!(self, " = _;");
             }
             ModItem::Static(it) => {
-                let Static { name, visibility, mutable, type_ref, ast_id } = &self.tree[it];
+                let Static {
+                    name,
+                    visibility,
+                    mutable,
+                    type_ref,
+                    ast_id,
+                    has_safe_kw,
+                    has_unsafe_kw,
+                } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
+                if *has_safe_kw {
+                    w!(self, "safe ");
+                }
+                if *has_unsafe_kw {
+                    w!(self, "unsafe ");
+                }
                 w!(self, "static ");
                 if *mutable {
                     w!(self, "mut ");
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
index 11d91513f12..3aeb88047a0 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
@@ -139,13 +139,11 @@ impl Visibility {
         let def_map_block = def_map.block_id();
         loop {
             match (to_module.block, def_map_block) {
-                // to_module is not a block, so there is no parent def map to use
+                // `to_module` is not a block, so there is no parent def map to use.
                 (None, _) => (),
+                // `to_module` is at `def_map`'s block, no need to move further.
                 (Some(a), Some(b)) if a == b => {
                     cov_mark::hit!(is_visible_from_same_block_def_map);
-                    if let Some(parent) = def_map.parent() {
-                        to_module = parent;
-                    }
                 }
                 _ => {
                     if let Some(parent) = to_module.def_map(db).parent() {
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 d04225b8722..4894c7a9311 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
@@ -5,19 +5,20 @@ use cfg::CfgExpr;
 use either::Either;
 use intern::{sym, Symbol};
 use mbe::{expect_fragment, DelimiterKind};
-use span::{Edition, EditionedFileId, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
+use span::{Edition, EditionedFileId, Span};
 use stdx::format_to;
 use syntax::{
     format_smolstr,
     unescape::{unescape_byte, unescape_char, unescape_unicode, Mode},
 };
-use syntax_bridge::parse_to_token_tree;
+use syntax_bridge::syntax_node_to_token_tree;
 
 use crate::{
     builtin::quote::{dollar_crate, quote},
     db::ExpandDatabase,
     hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt},
     name,
+    span_map::SpanMap,
     tt::{self, DelimSpan},
     ExpandError, ExpandResult, HirFileIdExt, Lookup as _, MacroCallId,
 };
@@ -739,18 +740,14 @@ fn include_expand(
             return ExpandResult::new(tt::Subtree::empty(DelimSpan { open: span, close: span }), e)
         }
     };
-    match parse_to_token_tree(
-        file_id.edition(),
-        SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID },
-        SyntaxContextId::ROOT,
-        &db.file_text(file_id.file_id()),
-    ) {
-        Some(it) => ExpandResult::ok(it),
-        None => ExpandResult::new(
-            tt::Subtree::empty(DelimSpan { open: span, close: span }),
-            ExpandError::other(span, "failed to parse included file"),
-        ),
-    }
+    let span_map = db.real_span_map(file_id);
+    // FIXME: Parse errors
+    ExpandResult::ok(syntax_node_to_token_tree(
+        &db.parse(file_id).syntax_node(),
+        SpanMap::RealSpanMap(span_map),
+        span,
+        syntax_bridge::DocCommentDesugarMode::ProcMacro,
+    ))
 }
 
 pub fn include_input_to_file_id(
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
index d412bf4eee5..0d19ae202ce 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
@@ -35,7 +35,7 @@ type MacroArgResult = (Arc<tt::Subtree>, SyntaxFixupUndoInfo, Span);
 /// an error will be emitted.
 ///
 /// Actual max for `analysis-stats .` at some point: 30672.
-static TOKEN_LIMIT: Limit = Limit::new(1_048_576);
+static TOKEN_LIMIT: Limit = Limit::new(2_097_152);
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum TokenExpander {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
index 7093fcadcb0..0a8bfaa70f8 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
@@ -95,7 +95,8 @@ fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8], &MemoryMap)) {
 fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String {
     let mut err = String::new();
     let span_formatter = |file, range| format!("{file:?} {range:?}");
-    let edition = db.crate_graph()[db.test_crate()].edition;
+    let edition =
+        db.crate_graph()[*db.crate_graph().crates_in_topological_order().last().unwrap()].edition;
     match e {
         ConstEvalError::MirLowerError(e) => e.pretty_print(&mut err, &db, span_formatter, edition),
         ConstEvalError::MirEvalError(e) => e.pretty_print(&mut err, &db, span_formatter, edition),
@@ -2896,7 +2897,7 @@ fn recursive_adt() {
                 {
                     const VARIANT_TAG_TREE: TagTree = TagTree::Choice(
                         &[
-                            TagTree::Leaf,
+                            TAG_TREE,
                         ],
                     );
                     VARIANT_TAG_TREE
@@ -2905,6 +2906,6 @@ fn recursive_adt() {
             TAG_TREE
         };
     "#,
-        |e| matches!(e, ConstEvalError::MirEvalError(MirEvalError::StackOverflow)),
+        |e| matches!(e, ConstEvalError::MirLowerError(MirLowerError::Loop)),
     );
 }
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 ff45c725c73..bcfc37c8671 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
@@ -89,7 +89,7 @@ fn walk_unsafe(
             let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
             if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
                 let static_data = db.static_data(id);
-                if static_data.mutable || static_data.is_extern {
+                if static_data.mutable || (static_data.is_extern && !static_data.has_safe_kw) {
                     unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
index 7300453ff00..e4881d75201 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
@@ -917,9 +917,19 @@ impl<'a> InferenceTable<'a> {
     /// Check if given type is `Sized` or not
     pub(crate) fn is_sized(&mut self, ty: &Ty) -> bool {
         // Early return for some obvious types
-        if matches!(ty.kind(Interner), TyKind::Scalar(..) | TyKind::Ref(..) | TyKind::Raw(..)) {
+        if matches!(
+            ty.kind(Interner),
+            TyKind::Scalar(..)
+                | TyKind::Ref(..)
+                | TyKind::Raw(..)
+                | TyKind::Never
+                | TyKind::FnDef(..)
+                | TyKind::Array(..)
+                | TyKind::Function(_)
+        ) {
             return true;
         }
+
         if let Some((AdtId::StructId(id), subst)) = ty.as_adt() {
             let struct_data = self.db.struct_data(id);
             if let Some((last_field, _)) = struct_data.variant_data.fields().iter().last() {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index 2c68d50013e..80831440720 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -72,18 +72,15 @@ pub type Variants = hir_def::layout::Variants<RustcFieldIdx, RustcEnumVariantIdx
 
 #[derive(Debug, PartialEq, Eq, Clone)]
 pub enum LayoutError {
-    // FIXME: Remove variants that duplicate LayoutCalculatorError's variants after sync
+    // FIXME: Remove more variants once they get added to LayoutCalculatorError
     BadCalc(LayoutCalculatorError<()>),
-    EmptyUnion,
     HasErrorConst,
     HasErrorType,
     HasPlaceholder,
     InvalidSimdType,
     NotImplemented,
     RecursiveTypeWithoutIndirection,
-    SizeOverflow,
     TargetLayoutNotAvailable,
-    UnexpectedUnsized,
     Unknown,
     UserReprTooSmall,
 }
@@ -93,7 +90,6 @@ impl fmt::Display for LayoutError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             LayoutError::BadCalc(err) => err.fallback_fmt(f),
-            LayoutError::EmptyUnion => write!(f, "type is an union with no fields"),
             LayoutError::HasErrorConst => write!(f, "type contains an unevaluatable const"),
             LayoutError::HasErrorType => write!(f, "type contains an error"),
             LayoutError::HasPlaceholder => write!(f, "type contains placeholders"),
@@ -102,11 +98,7 @@ impl fmt::Display for LayoutError {
             LayoutError::RecursiveTypeWithoutIndirection => {
                 write!(f, "recursive type without indirection")
             }
-            LayoutError::SizeOverflow => write!(f, "size overflow"),
             LayoutError::TargetLayoutNotAvailable => write!(f, "target layout not available"),
-            LayoutError::UnexpectedUnsized => {
-                write!(f, "an unsized type was found where a sized type was expected")
-            }
             LayoutError::Unknown => write!(f, "unknown"),
             LayoutError::UserReprTooSmall => {
                 write!(f, "the `#[repr]` hint is too small to hold the discriminants of the enum")
@@ -181,7 +173,10 @@ fn layout_of_simd_ty(
     };
 
     // Compute the size and alignment of the vector:
-    let size = e_ly.size.checked_mul(e_len, dl).ok_or(LayoutError::SizeOverflow)?;
+    let size = e_ly
+        .size
+        .checked_mul(e_len, dl)
+        .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
     let align = dl.vector_align(size);
     let size = size.align_to(align.abi);
 
@@ -294,7 +289,10 @@ pub fn layout_of_ty_query(
         TyKind::Array(element, count) => {
             let count = try_const_usize(db, count).ok_or(LayoutError::HasErrorConst)? as u64;
             let element = db.layout_of_ty(element.clone(), trait_env)?;
-            let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow)?;
+            let size = element
+                .size
+                .checked_mul(count, dl)
+                .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
 
             let abi = if count != 0 && matches!(element.abi, Abi::Uninhabited) {
                 Abi::Uninhabited
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 649cf88bb8d..9c1d8bcf36f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -51,10 +51,7 @@ mod test_db;
 #[cfg(test)]
 mod tests;
 
-use std::{
-    collections::hash_map::Entry,
-    hash::{BuildHasherDefault, Hash},
-};
+use std::hash::Hash;
 
 use base_db::ra_salsa::InternValueTrivial;
 use chalk_ir::{
@@ -65,10 +62,11 @@ use chalk_ir::{
 use either::Either;
 use hir_def::{hir::ExprId, type_ref::Rawness, CallableDefId, GeneralConstId, TypeOrConstParamId};
 use hir_expand::name::Name;
+use indexmap::{map::Entry, IndexMap};
 use intern::{sym, Symbol};
 use la_arena::{Arena, Idx};
 use mir::{MirEvalError, VTableMap};
-use rustc_hash::{FxHashMap, FxHashSet};
+use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
 use span::Edition;
 use syntax::ast::{make, ConstArg};
 use traits::FnTrait;
@@ -199,7 +197,7 @@ pub enum MemoryMap {
 
 #[derive(Debug, Default, Clone, PartialEq, Eq)]
 pub struct ComplexMemoryMap {
-    memory: FxHashMap<usize, Box<[u8]>>,
+    memory: IndexMap<usize, Box<[u8]>, FxBuildHasher>,
     vtable: VTableMap,
 }
 
@@ -245,7 +243,7 @@ impl MemoryMap {
         match self {
             MemoryMap::Empty => Ok(Default::default()),
             MemoryMap::Simple(m) => transform((&0, m)).map(|(addr, val)| {
-                let mut map = FxHashMap::with_capacity_and_hasher(1, BuildHasherDefault::default());
+                let mut map = FxHashMap::with_capacity_and_hasher(1, rustc_hash::FxBuildHasher);
                 map.insert(addr, val);
                 map
             }),
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 d1ce68da6d6..620bba2d75c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -257,10 +257,12 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
         return true;
     }
 
-    match func.lookup(db.upcast()).container {
+    let loc = func.lookup(db.upcast());
+    match loc.container {
         hir_def::ItemContainerId::ExternBlockId(block) => {
-            // Function in an `extern` block are always unsafe to call, except when it has
-            // `"rust-intrinsic"` ABI there are a few exceptions.
+            // Function in an `extern` block are always unsafe to call, except when
+            // it is marked as `safe` or it has `"rust-intrinsic"` ABI there are a
+            // few exceptions.
             let id = block.lookup(db.upcast()).id;
 
             let is_intrinsic =
@@ -270,8 +272,8 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
                 // Intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
                 !data.attrs.by_key(&sym::rustc_safe_intrinsic).exists()
             } else {
-                // Extern items are always unsafe
-                true
+                // Extern items without `safe` modifier are always unsafe
+                !data.is_safe()
             }
         }
         _ => false,
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index b27f1fbb5db..3eac33ce990 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -892,29 +892,8 @@ impl<'db> SemanticsImpl<'db> {
         f: &mut dyn FnMut(InFile<SyntaxToken>, SyntaxContextId) -> ControlFlow<T>,
     ) -> Option<T> {
         let _p = tracing::info_span!("descend_into_macros_impl").entered();
-        let (sa, span, file_id) = token
-            .parent()
-            .and_then(|parent| {
-                self.analyze_impl(InRealFile::new(file_id, &parent).into(), None, false)
-            })
-            .and_then(|sa| {
-                let file_id = sa.file_id.file_id()?;
-                Some((
-                    sa,
-                    self.db.real_span_map(file_id).span_for_range(token.text_range()),
-                    HirFileId::from(file_id),
-                ))
-            })?;
 
-        let mut m_cache = self.macro_call_cache.borrow_mut();
-        let def_map = sa.resolver.def_map();
-
-        // A stack of tokens to process, along with the file they came from
-        // These are tracked to know which macro calls we still have to look into
-        // the tokens themselves aren't that interesting as the span that is being used to map
-        // things down never changes.
-        let mut stack: Vec<(_, SmallVec<[_; 2]>)> =
-            vec![(file_id, smallvec![(token, SyntaxContextId::ROOT)])];
+        let span = self.db.real_span_map(file_id).span_for_range(token.text_range());
 
         // Process the expansion of a call, pushing all tokens with our span in the expansion back onto our stack
         let process_expansion_for_token = |stack: &mut Vec<_>, macro_file| {
@@ -926,7 +905,6 @@ impl<'db> SemanticsImpl<'db> {
                         .map(SmallVec::<[_; 2]>::from_iter),
                 )
             })?;
-
             // we have found a mapping for the token if the vec is non-empty
             let res = mapped_tokens.is_empty().not().then_some(());
             // requeue the tokens we got from mapping our current token down
@@ -934,6 +912,33 @@ impl<'db> SemanticsImpl<'db> {
             res
         };
 
+        // A stack of tokens to process, along with the file they came from
+        // These are tracked to know which macro calls we still have to look into
+        // the tokens themselves aren't that interesting as the span that is being used to map
+        // things down never changes.
+        let mut stack: Vec<(_, SmallVec<[_; 2]>)> = vec![];
+        let include = self.s2d_cache.borrow_mut().get_or_insert_include_for(self.db, file_id);
+        match include {
+            Some(include) => {
+                // include! inputs are always from real files, so they only need to be handled once upfront
+                process_expansion_for_token(&mut stack, include)?;
+            }
+            None => {
+                stack.push((file_id.into(), smallvec![(token, SyntaxContextId::ROOT)]));
+            }
+        }
+
+        let (file_id, tokens) = stack.first()?;
+        // make sure we pick the token in the expanded include if we encountered an include,
+        // otherwise we'll get the wrong semantics
+        let sa =
+            tokens.first()?.0.parent().and_then(|parent| {
+                self.analyze_impl(InFile::new(*file_id, &parent), None, false)
+            })?;
+
+        let mut m_cache = self.macro_call_cache.borrow_mut();
+        let def_map = sa.resolver.def_map();
+
         // Filters out all tokens that contain the given range (usually the macro call), any such
         // token is redundant as the corresponding macro call has already been processed
         let filter_duplicates = |tokens: &mut SmallVec<_>, range: TextRange| {
@@ -1011,6 +1016,7 @@ impl<'db> SemanticsImpl<'db> {
                                         ) {
                                         call.as_macro_file()
                                     } else {
+                                        // FIXME: This is wrong, the SourceAnalyzer might be invalid here
                                         sa.expand(self.db, mcall.as_ref())?
                                     };
                                     m_cache.insert(mcall, it);
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
index fd6d52d6c9d..389778b44ed 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
@@ -104,7 +104,7 @@ use hir_expand::{
 };
 use rustc_hash::FxHashMap;
 use smallvec::SmallVec;
-use span::{FileId, MacroFileId};
+use span::{EditionedFileId, FileId, MacroFileId};
 use stdx::impl_from;
 use syntax::{
     ast::{self, HasName},
@@ -118,9 +118,27 @@ pub(super) struct SourceToDefCache {
     pub(super) dynmap_cache: FxHashMap<(ChildContainer, HirFileId), DynMap>,
     expansion_info_cache: FxHashMap<MacroFileId, ExpansionInfo>,
     pub(super) file_to_def_cache: FxHashMap<FileId, SmallVec<[ModuleId; 1]>>,
+    pub(super) included_file_cache: FxHashMap<EditionedFileId, Option<MacroFileId>>,
 }
 
 impl SourceToDefCache {
+    pub(super) fn get_or_insert_include_for(
+        &mut self,
+        db: &dyn HirDatabase,
+        file: EditionedFileId,
+    ) -> Option<MacroFileId> {
+        if let Some(&m) = self.included_file_cache.get(&file) {
+            return m;
+        }
+        self.included_file_cache.insert(file, None);
+        for &crate_id in db.relevant_crates(file.into()).iter() {
+            db.include_macro_invoc(crate_id).iter().for_each(|&(macro_call_id, file_id)| {
+                self.included_file_cache.insert(file_id, Some(MacroFileId { macro_call_id }));
+            });
+        }
+        self.included_file_cache.get(&file).copied().flatten()
+    }
+
     pub(super) fn get_or_insert_expansion(
         &mut self,
         sema: &SemanticsImpl<'_>,
@@ -163,9 +181,13 @@ impl SourceToDefCtx<'_, '_> {
                             .include_macro_invoc(crate_id)
                             .iter()
                             .filter(|&&(_, file_id)| file_id == file)
-                            .flat_map(|(call, _)| {
+                            .flat_map(|&(macro_call_id, file_id)| {
+                                self.cache
+                                    .included_file_cache
+                                    .insert(file_id, Some(MacroFileId { macro_call_id }));
                                 modules(
-                                    call.lookup(self.db.upcast())
+                                    macro_call_id
+                                        .lookup(self.db.upcast())
                                         .kind
                                         .file_id()
                                         .original_file(self.db.upcast())
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
index cd5fe0f8626..c035c59ffca 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
@@ -1095,6 +1095,7 @@ fn main() {
 
     #[test]
     fn field_enum_cross_file() {
+        // FIXME: The import is missing
         check_assist(
             bool_to_enum,
             r#"
@@ -1132,7 +1133,7 @@ fn foo() {
 }
 
 //- /main.rs
-use foo::{Bool, Foo};
+use foo::Foo;
 
 mod foo;
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_result_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_result_return_type.rs
deleted file mode 100644
index a1987247cb6..00000000000
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_result_return_type.rs
+++ /dev/null
@@ -1,1115 +0,0 @@
-use ide_db::{
-    famous_defs::FamousDefs,
-    syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
-};
-use itertools::Itertools;
-use syntax::{
-    ast::{self, Expr, HasGenericArgs},
-    match_ast, AstNode, NodeOrToken, SyntaxKind, TextRange,
-};
-
-use crate::{AssistContext, AssistId, AssistKind, Assists};
-
-// Assist: unwrap_result_return_type
-//
-// Unwrap the function's return type.
-//
-// ```
-// # //- minicore: result
-// fn foo() -> Result<i32>$0 { Ok(42i32) }
-// ```
-// ->
-// ```
-// fn foo() -> i32 { 42i32 }
-// ```
-pub(crate) fn unwrap_result_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
-    let parent = ret_type.syntax().parent()?;
-    let body = match_ast! {
-        match parent {
-            ast::Fn(func) => func.body()?,
-            ast::ClosureExpr(closure) => match closure.body()? {
-                Expr::BlockExpr(block) => block,
-                // closures require a block when a return type is specified
-                _ => return None,
-            },
-            _ => return None,
-        }
-    };
-
-    let type_ref = &ret_type.ty()?;
-    let Some(hir::Adt::Enum(ret_enum)) = ctx.sema.resolve_type(type_ref)?.as_adt() else {
-        return None;
-    };
-    let result_enum =
-        FamousDefs(&ctx.sema, ctx.sema.scope(type_ref.syntax())?.krate()).core_result_Result()?;
-    if ret_enum != result_enum {
-        return None;
-    }
-
-    let ok_type = unwrap_result_type(type_ref)?;
-
-    acc.add(
-        AssistId("unwrap_result_return_type", AssistKind::RefactorRewrite),
-        "Unwrap Result return type",
-        type_ref.syntax().text_range(),
-        |builder| {
-            let body = ast::Expr::BlockExpr(body);
-
-            let mut exprs_to_unwrap = Vec::new();
-            let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_unwrap, e);
-            walk_expr(&body, &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);
-                    }
-                }
-            });
-            for_each_tail_expr(&body, tail_cb);
-
-            let is_unit_type = is_unit_type(&ok_type);
-            if is_unit_type {
-                let mut text_range = ret_type.syntax().text_range();
-
-                if let Some(NodeOrToken::Token(token)) = ret_type.syntax().next_sibling_or_token() {
-                    if token.kind() == SyntaxKind::WHITESPACE {
-                        text_range = TextRange::new(text_range.start(), token.text_range().end());
-                    }
-                }
-
-                builder.delete(text_range);
-            } else {
-                builder.replace(type_ref.syntax().text_range(), ok_type.syntax().text());
-            }
-
-            for ret_expr_arg in exprs_to_unwrap {
-                let ret_expr_str = ret_expr_arg.to_string();
-                if ret_expr_str.starts_with("Ok(") || ret_expr_str.starts_with("Err(") {
-                    let arg_list = ret_expr_arg.syntax().children().find_map(ast::ArgList::cast);
-                    if let Some(arg_list) = arg_list {
-                        if is_unit_type {
-                            match ret_expr_arg.syntax().prev_sibling_or_token() {
-                                // Useful to delete the entire line without leaving trailing whitespaces
-                                Some(whitespace) => {
-                                    let new_range = TextRange::new(
-                                        whitespace.text_range().start(),
-                                        ret_expr_arg.syntax().text_range().end(),
-                                    );
-                                    builder.delete(new_range);
-                                }
-                                None => {
-                                    builder.delete(ret_expr_arg.syntax().text_range());
-                                }
-                            }
-                        } else {
-                            builder.replace(
-                                ret_expr_arg.syntax().text_range(),
-                                arg_list.args().join(", "),
-                            );
-                        }
-                    }
-                }
-            }
-        },
-    )
-}
-
-fn tail_cb_impl(acc: &mut Vec<ast::Expr>, e: &ast::Expr) {
-    match e {
-        Expr::BreakExpr(break_expr) => {
-            if let Some(break_expr_arg) = break_expr.expr() {
-                for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(acc, e))
-            }
-        }
-        Expr::ReturnExpr(_) => {
-            // all return expressions have already been handled by the walk loop
-        }
-        e => acc.push(e.clone()),
-    }
-}
-
-// Tries to extract `T` from `Result<T, E>`.
-fn unwrap_result_type(ty: &ast::Type) -> Option<ast::Type> {
-    let ast::Type::PathType(path_ty) = ty else {
-        return None;
-    };
-    let path = path_ty.path()?;
-    let segment = path.first_segment()?;
-    let generic_arg_list = segment.generic_arg_list()?;
-    let generic_args: Vec<_> = generic_arg_list.generic_args().collect();
-    let ast::GenericArg::TypeArg(ok_type) = generic_args.first()? else {
-        return None;
-    };
-    ok_type.ty()
-}
-
-fn is_unit_type(ty: &ast::Type) -> bool {
-    let ast::Type::TupleType(tuple) = ty else { return false };
-    tuple.fields().next().is_none()
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable};
-
-    use super::*;
-
-    #[test]
-    fn unwrap_result_return_type_simple() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i3$02> {
-    let test = "test";
-    return Ok(42i32);
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let test = "test";
-    return 42i32;
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_unit_type() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<(), Box<dyn Error$0>> {
-    Ok(())
-}
-"#,
-            r#"
-fn foo() {
-}
-"#,
-        );
-
-        // Unformatted return type
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<(), Box<dyn Error$0>>{
-    Ok(())
-}
-"#,
-            r#"
-fn foo() {
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_ending_with_parent() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32, Box<dyn Error$0>> {
-    if true {
-        Ok(42)
-    } else {
-        foo()
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    if true {
-        42
-    } else {
-        foo()
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_return_type_break_split_tail() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i3$02, String> {
-    loop {
-        break if true {
-            Ok(1)
-        } else {
-            Ok(0)
-        };
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    loop {
-        break if true {
-            1
-        } else {
-            0
-        };
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_closure() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() {
-    || -> Result<i32$0> {
-        let test = "test";
-        return Ok(42i32);
-    };
-}
-"#,
-            r#"
-fn foo() {
-    || -> i32 {
-        let test = "test";
-        return 42i32;
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_return_type_bad_cursor() {
-        check_assist_not_applicable(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> i32 {
-    let test = "test";$0
-    return 42i32;
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_return_type_bad_cursor_closure() {
-        check_assist_not_applicable(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() {
-    || -> i32 {
-        let test = "test";$0
-        return 42i32;
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_closure_non_block() {
-        check_assist_not_applicable(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() { || -> i$032 3; }
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_return_type_already_not_result_std() {
-        check_assist_not_applicable(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    let test = "test";
-    return 42i32;
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_return_type_already_not_result_closure() {
-        check_assist_not_applicable(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() {
-    || -> i32$0 {
-        let test = "test";
-        return 42i32;
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_tail() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() ->$0 Result<i32> {
-    let test = "test";
-    Ok(42i32)
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let test = "test";
-    42i32
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_tail_closure() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() {
-    || ->$0 Result<i32, String> {
-        let test = "test";
-        Ok(42i32)
-    };
-}
-"#,
-            r#"
-fn foo() {
-    || -> i32 {
-        let test = "test";
-        42i32
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_tail_only() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0> { Ok(42i32) }
-"#,
-            r#"
-fn foo() -> i32 { 42i32 }
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_tail_block_like() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32>$0 {
-    if true {
-        Ok(42i32)
-    } else {
-        Ok(24i32)
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    if true {
-        42i32
-    } else {
-        24i32
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_without_block_closure() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() {
-    || -> Result<i32, String>$0 {
-        if true {
-            Ok(42i32)
-        } else {
-            Ok(24i32)
-        }
-    };
-}
-"#,
-            r#"
-fn foo() {
-    || -> i32 {
-        if true {
-            42i32
-        } else {
-            24i32
-        }
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_nested_if() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32>$0 {
-    if true {
-        if false {
-            Ok(1)
-        } else {
-            Ok(2)
-        }
-    } else {
-        Ok(24i32)
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    if true {
-        if false {
-            1
-        } else {
-            2
-        }
-    } else {
-        24i32
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_await() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-async fn foo() -> Result<i$032> {
-    if true {
-        if false {
-            Ok(1.await)
-        } else {
-            Ok(2.await)
-        }
-    } else {
-        Ok(24i32.await)
-    }
-}
-"#,
-            r#"
-async fn foo() -> i32 {
-    if true {
-        if false {
-            1.await
-        } else {
-            2.await
-        }
-    } else {
-        24i32.await
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_array() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<[i32; 3]$0> { Ok([1, 2, 3]) }
-"#,
-            r#"
-fn foo() -> [i32; 3] { [1, 2, 3] }
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_cast() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -$0> Result<i32> {
-    if true {
-        if false {
-            Ok(1 as i32)
-        } else {
-            Ok(2 as i32)
-        }
-    } else {
-        Ok(24 as i32)
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    if true {
-        if false {
-            1 as i32
-        } else {
-            2 as i32
-        }
-    } else {
-        24 as i32
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_tail_block_like_match() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0> {
-    let my_var = 5;
-    match my_var {
-        5 => Ok(42i32),
-        _ => Ok(24i32),
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let my_var = 5;
-    match my_var {
-        5 => 42i32,
-        _ => 24i32,
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_loop_with_tail() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0> {
-    let my_var = 5;
-    loop {
-        println!("test");
-        5
-    }
-    Ok(my_var)
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let my_var = 5;
-    loop {
-        println!("test");
-        5
-    }
-    my_var
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_loop_in_let_stmt() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0> {
-    let my_var = let x = loop {
-        break 1;
-    };
-    Ok(my_var)
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let my_var = let x = loop {
-        break 1;
-    };
-    my_var
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_tail_block_like_match_return_expr() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32>$0 {
-    let my_var = 5;
-    let res = match my_var {
-        5 => 42i32,
-        _ => return Ok(24i32),
-    };
-    Ok(res)
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let my_var = 5;
-    let res = match my_var {
-        5 => 42i32,
-        _ => return 24i32,
-    };
-    res
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0> {
-    let my_var = 5;
-    let res = if my_var == 5 {
-        42i32
-    } else {
-        return Ok(24i32);
-    };
-    Ok(res)
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let my_var = 5;
-    let res = if my_var == 5 {
-        42i32
-    } else {
-        return 24i32;
-    };
-    res
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_tail_block_like_match_deeper() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0> {
-    let my_var = 5;
-    match my_var {
-        5 => {
-            if true {
-                Ok(42i32)
-            } else {
-                Ok(25i32)
-            }
-        },
-        _ => {
-            let test = "test";
-            if test == "test" {
-                return Ok(bar());
-            }
-            Ok(53i32)
-        },
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let my_var = 5;
-    match my_var {
-        5 => {
-            if true {
-                42i32
-            } else {
-                25i32
-            }
-        },
-        _ => {
-            let test = "test";
-            if test == "test" {
-                return bar();
-            }
-            53i32
-        },
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_tail_block_like_early_return() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0> {
-    let test = "test";
-    if test == "test" {
-        return Ok(24i32);
-    }
-    Ok(53i32)
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let test = "test";
-    if test == "test" {
-        return 24i32;
-    }
-    53i32
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_in_tail_position() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo(num: i32) -> $0Result<i32, String> {
-    return Ok(num)
-}
-"#,
-            r#"
-fn foo(num: i32) -> i32 {
-    return num
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_closure() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> Result<u32$0> {
-    let true_closure = || { return true; };
-    if the_field < 5 {
-        let mut i = 0;
-        if true_closure() {
-            return Ok(99);
-        } else {
-            return Ok(0);
-        }
-    }
-    Ok(the_field)
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> u32 {
-    let true_closure = || { return true; };
-    if the_field < 5 {
-        let mut i = 0;
-        if true_closure() {
-            return 99;
-        } else {
-            return 0;
-        }
-    }
-    the_field
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> Result<u32$0> {
-    let true_closure = || {
-        return true;
-    };
-    if the_field < 5 {
-        let mut i = 0;
-
-
-        if true_closure() {
-            return Ok(99);
-        } else {
-            return Ok(0);
-        }
-    }
-    let t = None;
-
-    Ok(t.unwrap_or_else(|| the_field))
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> u32 {
-    let true_closure = || {
-        return true;
-    };
-    if the_field < 5 {
-        let mut i = 0;
-
-
-        if true_closure() {
-            return 99;
-        } else {
-            return 0;
-        }
-    }
-    let t = None;
-
-    t.unwrap_or_else(|| the_field)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_simple_with_weird_forms() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0> {
-    let test = "test";
-    if test == "test" {
-        return Ok(24i32);
-    }
-    let mut i = 0;
-    loop {
-        if i == 1 {
-            break Ok(55);
-        }
-        i += 1;
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    let test = "test";
-    if test == "test" {
-        return 24i32;
-    }
-    let mut i = 0;
-    loop {
-        if i == 1 {
-            break 55;
-        }
-        i += 1;
-    }
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> Result<u32$0> {
-    if the_field < 5 {
-        let mut i = 0;
-        loop {
-            if i > 5 {
-                return Ok(55u32);
-            }
-            i += 3;
-        }
-        match i {
-            5 => return Ok(99),
-            _ => return Ok(0),
-        };
-    }
-    Ok(the_field)
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> u32 {
-    if the_field < 5 {
-        let mut i = 0;
-        loop {
-            if i > 5 {
-                return 55u32;
-            }
-            i += 3;
-        }
-        match i {
-            5 => return 99,
-            _ => return 0,
-        };
-    }
-    the_field
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> Result<u32$0> {
-    if the_field < 5 {
-        let mut i = 0;
-        match i {
-            5 => return Ok(99),
-            _ => return Ok(0),
-        }
-    }
-    Ok(the_field)
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> u32 {
-    if the_field < 5 {
-        let mut i = 0;
-        match i {
-            5 => return 99,
-            _ => return 0,
-        }
-    }
-    the_field
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> Result<u32$0> {
-    if the_field < 5 {
-        let mut i = 0;
-        if i == 5 {
-            return Ok(99)
-        } else {
-            return Ok(0)
-        }
-    }
-    Ok(the_field)
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> u32 {
-    if the_field < 5 {
-        let mut i = 0;
-        if i == 5 {
-            return 99
-        } else {
-            return 0
-        }
-    }
-    the_field
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> Result<u3$02> {
-    if the_field < 5 {
-        let mut i = 0;
-        if i == 5 {
-            return Ok(99);
-        } else {
-            return Ok(0);
-        }
-    }
-    Ok(the_field)
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> u32 {
-    if the_field < 5 {
-        let mut i = 0;
-        if i == 5 {
-            return 99;
-        } else {
-            return 0;
-        }
-    }
-    the_field
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_result_return_type_nested_type() {
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result, option
-fn foo() -> Result<Option<i32$0>, ()> {
-    Ok(Some(42))
-}
-"#,
-            r#"
-fn foo() -> Option<i32> {
-    Some(42)
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result, option
-fn foo() -> Result<Option<Result<i32$0, ()>>, ()> {
-    Ok(None)
-}
-"#,
-            r#"
-fn foo() -> Option<Result<i32, ()>> {
-    None
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_result_return_type,
-            r#"
-//- minicore: result, option, iterators
-fn foo() -> Result<impl Iterator<Item = i32>$0, ()> {
-    Ok(Some(42).into_iter())
-}
-"#,
-            r#"
-fn foo() -> impl Iterator<Item = i32> {
-    Some(42).into_iter()
-}
-"#,
-        );
-    }
-}
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
new file mode 100644
index 00000000000..64d5e2c9b82
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs
@@ -0,0 +1,2229 @@
+use ide_db::{
+    famous_defs::FamousDefs,
+    syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
+};
+use itertools::Itertools;
+use syntax::{
+    ast::{self, Expr, HasGenericArgs},
+    match_ast, AstNode, NodeOrToken, SyntaxKind, TextRange,
+};
+
+use crate::{AssistContext, AssistId, AssistKind, Assists};
+
+// Assist: unwrap_option_return_type
+//
+// Unwrap the function's return type.
+//
+// ```
+// # //- minicore: option
+// fn foo() -> Option<i32>$0 { Some(42i32) }
+// ```
+// ->
+// ```
+// fn foo() -> i32 { 42i32 }
+// ```
+
+// Assist: unwrap_result_return_type
+//
+// Unwrap the function's return type.
+//
+// ```
+// # //- minicore: result
+// fn foo() -> Result<i32>$0 { Ok(42i32) }
+// ```
+// ->
+// ```
+// fn foo() -> i32 { 42i32 }
+// ```
+
+pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
+    let parent = ret_type.syntax().parent()?;
+    let body = match_ast! {
+        match parent {
+            ast::Fn(func) => func.body()?,
+            ast::ClosureExpr(closure) => match closure.body()? {
+                Expr::BlockExpr(block) => block,
+                // closures require a block when a return type is specified
+                _ => return None,
+            },
+            _ => return None,
+        }
+    };
+
+    let type_ref = &ret_type.ty()?;
+    let Some(hir::Adt::Enum(ret_enum)) = ctx.sema.resolve_type(type_ref)?.as_adt() else {
+        return None;
+    };
+
+    let famous_defs = FamousDefs(&ctx.sema, ctx.sema.scope(type_ref.syntax())?.krate());
+
+    let kind = UnwrapperKind::ALL
+        .iter()
+        .find(|k| matches!(k.core_type(&famous_defs), Some(core_type) if ret_enum == core_type))?;
+
+    let happy_type = extract_wrapped_type(type_ref)?;
+
+    acc.add(kind.assist_id(), kind.label(), type_ref.syntax().text_range(), |builder| {
+        let body = ast::Expr::BlockExpr(body);
+
+        let mut exprs_to_unwrap = Vec::new();
+        let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_unwrap, e);
+        walk_expr(&body, &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);
+                }
+            }
+        });
+        for_each_tail_expr(&body, tail_cb);
+
+        let is_unit_type = is_unit_type(&happy_type);
+        if is_unit_type {
+            let mut text_range = ret_type.syntax().text_range();
+
+            if let Some(NodeOrToken::Token(token)) = ret_type.syntax().next_sibling_or_token() {
+                if token.kind() == SyntaxKind::WHITESPACE {
+                    text_range = TextRange::new(text_range.start(), token.text_range().end());
+                }
+            }
+
+            builder.delete(text_range);
+        } else {
+            builder.replace(type_ref.syntax().text_range(), happy_type.syntax().text());
+        }
+
+        for ret_expr_arg in exprs_to_unwrap {
+            let ret_expr_str = ret_expr_arg.to_string();
+
+            let needs_replacing = match kind {
+                UnwrapperKind::Option => ret_expr_str.starts_with("Some("),
+                UnwrapperKind::Result => {
+                    ret_expr_str.starts_with("Ok(") || ret_expr_str.starts_with("Err(")
+                }
+            };
+
+            if needs_replacing {
+                let arg_list = ret_expr_arg.syntax().children().find_map(ast::ArgList::cast);
+                if let Some(arg_list) = arg_list {
+                    if is_unit_type {
+                        match ret_expr_arg.syntax().prev_sibling_or_token() {
+                            // Useful to delete the entire line without leaving trailing whitespaces
+                            Some(whitespace) => {
+                                let new_range = TextRange::new(
+                                    whitespace.text_range().start(),
+                                    ret_expr_arg.syntax().text_range().end(),
+                                );
+                                builder.delete(new_range);
+                            }
+                            None => {
+                                builder.delete(ret_expr_arg.syntax().text_range());
+                            }
+                        }
+                    } else {
+                        builder.replace(
+                            ret_expr_arg.syntax().text_range(),
+                            arg_list.args().join(", "),
+                        );
+                    }
+                }
+            } else if matches!(kind, UnwrapperKind::Option if ret_expr_str == "None") {
+                builder.replace(ret_expr_arg.syntax().text_range(), "()");
+            }
+        }
+    })
+}
+
+enum UnwrapperKind {
+    Option,
+    Result,
+}
+
+impl UnwrapperKind {
+    const ALL: &'static [UnwrapperKind] = &[UnwrapperKind::Option, UnwrapperKind::Result];
+
+    fn assist_id(&self) -> AssistId {
+        let s = match self {
+            UnwrapperKind::Option => "unwrap_option_return_type",
+            UnwrapperKind::Result => "unwrap_result_return_type",
+        };
+
+        AssistId(s, AssistKind::RefactorRewrite)
+    }
+
+    fn label(&self) -> &'static str {
+        match self {
+            UnwrapperKind::Option => "Unwrap Option return type",
+            UnwrapperKind::Result => "Unwrap Result return type",
+        }
+    }
+
+    fn core_type(&self, famous_defs: &FamousDefs<'_, '_>) -> Option<hir::Enum> {
+        match self {
+            UnwrapperKind::Option => famous_defs.core_option_Option(),
+            UnwrapperKind::Result => famous_defs.core_result_Result(),
+        }
+    }
+}
+
+fn tail_cb_impl(acc: &mut Vec<ast::Expr>, e: &ast::Expr) {
+    match e {
+        Expr::BreakExpr(break_expr) => {
+            if let Some(break_expr_arg) = break_expr.expr() {
+                for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(acc, e))
+            }
+        }
+        Expr::ReturnExpr(_) => {
+            // all return expressions have already been handled by the walk loop
+        }
+        e => acc.push(e.clone()),
+    }
+}
+
+// Tries to extract `T` from `Option<T>` or `Result<T, E>`.
+fn extract_wrapped_type(ty: &ast::Type) -> Option<ast::Type> {
+    let ast::Type::PathType(path_ty) = ty else {
+        return None;
+    };
+    let path = path_ty.path()?;
+    let segment = path.first_segment()?;
+    let generic_arg_list = segment.generic_arg_list()?;
+    let generic_args: Vec<_> = generic_arg_list.generic_args().collect();
+    let ast::GenericArg::TypeArg(happy_type) = generic_args.first()? else {
+        return None;
+    };
+    happy_type.ty()
+}
+
+fn is_unit_type(ty: &ast::Type) -> bool {
+    let ast::Type::TupleType(tuple) = ty else { return false };
+    tuple.fields().next().is_none()
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tests::{check_assist_by_label, check_assist_not_applicable_by_label};
+
+    use super::*;
+
+    #[test]
+    fn unwrap_option_return_type_simple() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i3$02> {
+    let test = "test";
+    return Some(42i32);
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_unit_type() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<()$0> {
+    Some(())
+}
+"#,
+            r#"
+fn foo() {
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        // Unformatted return type
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<()$0>{
+    Some(())
+}
+"#,
+            r#"
+fn foo() {
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_none() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i3$02> {
+    if true {
+        Some(42)
+    } else {
+        None
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        42
+    } else {
+        ()
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_ending_with_parent() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i3$02> {
+    if true {
+        Some(42)
+    } else {
+        foo()
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        42
+    } else {
+        foo()
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_break_split_tail() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i3$02> {
+    loop {
+        break if true {
+            Some(1)
+        } else {
+            Some(0)
+        };
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    loop {
+        break if true {
+            1
+        } else {
+            0
+        };
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_closure() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || -> Option<i32$0> {
+        let test = "test";
+        return Some(42i32);
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> i32 {
+        let test = "test";
+        return 42i32;
+    };
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_return_type_bad_cursor() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32 {
+    let test = "test";$0
+    return 42i32;
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_return_type_bad_cursor_closure() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || -> i32 {
+        let test = "test";$0
+        return 42i32;
+    };
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_closure_non_block() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() { || -> i$032 3; }
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_return_type_already_not_option_std() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_return_type_already_not_option_closure() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || -> i32$0 {
+        let test = "test";
+        return 42i32;
+    };
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_tail() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() ->$0 Option<i32> {
+    let test = "test";
+    Some(42i32)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let test = "test";
+    42i32
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_tail_closure() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || ->$0 Option<i32> {
+        let test = "test";
+        Some(42i32)
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> i32 {
+        let test = "test";
+        42i32
+    };
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_tail_only() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> { Some(42i32) }
+"#,
+            r#"
+fn foo() -> i32 { 42i32 }
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_tail_block_like() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32>$0 {
+    if true {
+        Some(42i32)
+    } else {
+        Some(24i32)
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        42i32
+    } else {
+        24i32
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_without_block_closure() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || -> Option<i32>$0 {
+        if true {
+            Some(42i32)
+        } else {
+            Some(24i32)
+        }
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> i32 {
+        if true {
+            42i32
+        } else {
+            24i32
+        }
+    };
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_nested_if() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32>$0 {
+    if true {
+        if false {
+            Some(1)
+        } else {
+            Some(2)
+        }
+    } else {
+        Some(24i32)
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        if false {
+            1
+        } else {
+            2
+        }
+    } else {
+        24i32
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_await() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+async fn foo() -> Option<i$032> {
+    if true {
+        if false {
+            Some(1.await)
+        } else {
+            Some(2.await)
+        }
+    } else {
+        Some(24i32.await)
+    }
+}
+"#,
+            r#"
+async fn foo() -> i32 {
+    if true {
+        if false {
+            1.await
+        } else {
+            2.await
+        }
+    } else {
+        24i32.await
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_array() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<[i32; 3]$0> { Some([1, 2, 3]) }
+"#,
+            r#"
+fn foo() -> [i32; 3] { [1, 2, 3] }
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_cast() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -$0> Option<i32> {
+    if true {
+        if false {
+            Some(1 as i32)
+        } else {
+            Some(2 as i32)
+        }
+    } else {
+        Some(24 as i32)
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        if false {
+            1 as i32
+        } else {
+            2 as i32
+        }
+    } else {
+        24 as i32
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_tail_block_like_match() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> {
+    let my_var = 5;
+    match my_var {
+        5 => Some(42i32),
+        _ => Some(24i32),
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    match my_var {
+        5 => 42i32,
+        _ => 24i32,
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_loop_with_tail() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> {
+    let my_var = 5;
+    loop {
+        println!("test");
+        5
+    }
+    Some(my_var)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    loop {
+        println!("test");
+        5
+    }
+    my_var
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_loop_in_let_stmt() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> {
+    let my_var = let x = loop {
+        break 1;
+    };
+    Some(my_var)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = let x = loop {
+        break 1;
+    };
+    my_var
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_tail_block_like_match_return_expr() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32>$0 {
+    let my_var = 5;
+    let res = match my_var {
+        5 => 42i32,
+        _ => return Some(24i32),
+    };
+    Some(res)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    let res = match my_var {
+        5 => 42i32,
+        _ => return 24i32,
+    };
+    res
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> {
+    let my_var = 5;
+    let res = if my_var == 5 {
+        42i32
+    } else {
+        return Some(24i32);
+    };
+    Some(res)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    let res = if my_var == 5 {
+        42i32
+    } else {
+        return 24i32;
+    };
+    res
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_tail_block_like_match_deeper() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> {
+    let my_var = 5;
+    match my_var {
+        5 => {
+            if true {
+                Some(42i32)
+            } else {
+                Some(25i32)
+            }
+        },
+        _ => {
+            let test = "test";
+            if test == "test" {
+                return Some(bar());
+            }
+            Some(53i32)
+        },
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    match my_var {
+        5 => {
+            if true {
+                42i32
+            } else {
+                25i32
+            }
+        },
+        _ => {
+            let test = "test";
+            if test == "test" {
+                return bar();
+            }
+            53i32
+        },
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_tail_block_like_early_return() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> {
+    let test = "test";
+    if test == "test" {
+        return Some(24i32);
+    }
+    Some(53i32)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let test = "test";
+    if test == "test" {
+        return 24i32;
+    }
+    53i32
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_in_tail_position() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo(num: i32) -> $0Option<i32> {
+    return Some(num)
+}
+"#,
+            r#"
+fn foo(num: i32) -> i32 {
+    return num
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_closure() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> Option<u32$0> {
+    let true_closure = || { return true; };
+    if the_field < 5 {
+        let mut i = 0;
+        if true_closure() {
+            return Some(99);
+        } else {
+            return Some(0);
+        }
+    }
+    Some(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    let true_closure = || { return true; };
+    if the_field < 5 {
+        let mut i = 0;
+        if true_closure() {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    the_field
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> Option<u32$0> {
+    let true_closure = || {
+        return true;
+    };
+    if the_field < 5 {
+        let mut i = 0;
+
+
+        if true_closure() {
+            return Some(99);
+        } else {
+            return Some(0);
+        }
+    }
+    let t = None;
+
+    Some(t.unwrap_or_else(|| the_field))
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    let true_closure = || {
+        return true;
+    };
+    if the_field < 5 {
+        let mut i = 0;
+
+
+        if true_closure() {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    let t = None;
+
+    t.unwrap_or_else(|| the_field)
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_simple_with_weird_forms() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> {
+    let test = "test";
+    if test == "test" {
+        return Some(24i32);
+    }
+    let mut i = 0;
+    loop {
+        if i == 1 {
+            break Some(55);
+        }
+        i += 1;
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let test = "test";
+    if test == "test" {
+        return 24i32;
+    }
+    let mut i = 0;
+    loop {
+        if i == 1 {
+            break 55;
+        }
+        i += 1;
+    }
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> Option<u32$0> {
+    if the_field < 5 {
+        let mut i = 0;
+        loop {
+            if i > 5 {
+                return Some(55u32);
+            }
+            i += 3;
+        }
+        match i {
+            5 => return Some(99),
+            _ => return Some(0),
+        };
+    }
+    Some(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        loop {
+            if i > 5 {
+                return 55u32;
+            }
+            i += 3;
+        }
+        match i {
+            5 => return 99,
+            _ => return 0,
+        };
+    }
+    the_field
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> Option<u32$0> {
+    if the_field < 5 {
+        let mut i = 0;
+        match i {
+            5 => return Some(99),
+            _ => return Some(0),
+        }
+    }
+    Some(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        match i {
+            5 => return 99,
+            _ => return 0,
+        }
+    }
+    the_field
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> Option<u32$0> {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return Some(99)
+        } else {
+            return Some(0)
+        }
+    }
+    Some(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return 99
+        } else {
+            return 0
+        }
+    }
+    the_field
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> Option<u3$02> {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return Some(99);
+        } else {
+            return Some(0);
+        }
+    }
+    Some(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    the_field
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_option_return_type_nested_type() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option, result
+fn foo() -> Option<Result<i32$0, ()>> {
+    Some(Ok(42))
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ()> {
+    Ok(42)
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option, result
+fn foo() -> Option<Result<Option<i32$0>, ()>> {
+    Some(Err())
+}
+"#,
+            r#"
+fn foo() -> Result<Option<i32>, ()> {
+    Err()
+}
+"#,
+            "Unwrap Option return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: option, result, iterators
+fn foo() -> Option<impl Iterator<Item = i32>$0> {
+    Some(Some(42).into_iter())
+}
+"#,
+            r#"
+fn foo() -> impl Iterator<Item = i32> {
+    Some(42).into_iter()
+}
+"#,
+            "Unwrap Option return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i3$02> {
+    let test = "test";
+    return Ok(42i32);
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_unit_type() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<(), Box<dyn Error$0>> {
+    Ok(())
+}
+"#,
+            r#"
+fn foo() {
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        // Unformatted return type
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<(), Box<dyn Error$0>>{
+    Ok(())
+}
+"#,
+            r#"
+fn foo() {
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_ending_with_parent() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32, Box<dyn Error$0>> {
+    if true {
+        Ok(42)
+    } else {
+        foo()
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        42
+    } else {
+        foo()
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_break_split_tail() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i3$02, String> {
+    loop {
+        break if true {
+            Ok(1)
+        } else {
+            Ok(0)
+        };
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    loop {
+        break if true {
+            1
+        } else {
+            0
+        };
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_closure() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || -> Result<i32$0> {
+        let test = "test";
+        return Ok(42i32);
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> i32 {
+        let test = "test";
+        return 42i32;
+    };
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_return_type_bad_cursor() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32 {
+    let test = "test";$0
+    return 42i32;
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_return_type_bad_cursor_closure() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || -> i32 {
+        let test = "test";$0
+        return 42i32;
+    };
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_closure_non_block() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() { || -> i$032 3; }
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_return_type_already_not_result_std() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_return_type_already_not_result_closure() {
+        check_assist_not_applicable_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || -> i32$0 {
+        let test = "test";
+        return 42i32;
+    };
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_tail() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() ->$0 Result<i32> {
+    let test = "test";
+    Ok(42i32)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let test = "test";
+    42i32
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_tail_closure() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || ->$0 Result<i32, String> {
+        let test = "test";
+        Ok(42i32)
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> i32 {
+        let test = "test";
+        42i32
+    };
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_tail_only() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0> { Ok(42i32) }
+"#,
+            r#"
+fn foo() -> i32 { 42i32 }
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_tail_block_like() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32>$0 {
+    if true {
+        Ok(42i32)
+    } else {
+        Ok(24i32)
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        42i32
+    } else {
+        24i32
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_without_block_closure() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || -> Result<i32, String>$0 {
+        if true {
+            Ok(42i32)
+        } else {
+            Ok(24i32)
+        }
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> i32 {
+        if true {
+            42i32
+        } else {
+            24i32
+        }
+    };
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_nested_if() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32>$0 {
+    if true {
+        if false {
+            Ok(1)
+        } else {
+            Ok(2)
+        }
+    } else {
+        Ok(24i32)
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        if false {
+            1
+        } else {
+            2
+        }
+    } else {
+        24i32
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_await() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+async fn foo() -> Result<i$032> {
+    if true {
+        if false {
+            Ok(1.await)
+        } else {
+            Ok(2.await)
+        }
+    } else {
+        Ok(24i32.await)
+    }
+}
+"#,
+            r#"
+async fn foo() -> i32 {
+    if true {
+        if false {
+            1.await
+        } else {
+            2.await
+        }
+    } else {
+        24i32.await
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_array() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<[i32; 3]$0> { Ok([1, 2, 3]) }
+"#,
+            r#"
+fn foo() -> [i32; 3] { [1, 2, 3] }
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_cast() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -$0> Result<i32> {
+    if true {
+        if false {
+            Ok(1 as i32)
+        } else {
+            Ok(2 as i32)
+        }
+    } else {
+        Ok(24 as i32)
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    if true {
+        if false {
+            1 as i32
+        } else {
+            2 as i32
+        }
+    } else {
+        24 as i32
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_tail_block_like_match() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0> {
+    let my_var = 5;
+    match my_var {
+        5 => Ok(42i32),
+        _ => Ok(24i32),
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    match my_var {
+        5 => 42i32,
+        _ => 24i32,
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_loop_with_tail() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0> {
+    let my_var = 5;
+    loop {
+        println!("test");
+        5
+    }
+    Ok(my_var)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    loop {
+        println!("test");
+        5
+    }
+    my_var
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_loop_in_let_stmt() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0> {
+    let my_var = let x = loop {
+        break 1;
+    };
+    Ok(my_var)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = let x = loop {
+        break 1;
+    };
+    my_var
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_tail_block_like_match_return_expr() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32>$0 {
+    let my_var = 5;
+    let res = match my_var {
+        5 => 42i32,
+        _ => return Ok(24i32),
+    };
+    Ok(res)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    let res = match my_var {
+        5 => 42i32,
+        _ => return 24i32,
+    };
+    res
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0> {
+    let my_var = 5;
+    let res = if my_var == 5 {
+        42i32
+    } else {
+        return Ok(24i32);
+    };
+    Ok(res)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    let res = if my_var == 5 {
+        42i32
+    } else {
+        return 24i32;
+    };
+    res
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_tail_block_like_match_deeper() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0> {
+    let my_var = 5;
+    match my_var {
+        5 => {
+            if true {
+                Ok(42i32)
+            } else {
+                Ok(25i32)
+            }
+        },
+        _ => {
+            let test = "test";
+            if test == "test" {
+                return Ok(bar());
+            }
+            Ok(53i32)
+        },
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let my_var = 5;
+    match my_var {
+        5 => {
+            if true {
+                42i32
+            } else {
+                25i32
+            }
+        },
+        _ => {
+            let test = "test";
+            if test == "test" {
+                return bar();
+            }
+            53i32
+        },
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_tail_block_like_early_return() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0> {
+    let test = "test";
+    if test == "test" {
+        return Ok(24i32);
+    }
+    Ok(53i32)
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let test = "test";
+    if test == "test" {
+        return 24i32;
+    }
+    53i32
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_in_tail_position() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo(num: i32) -> $0Result<i32, String> {
+    return Ok(num)
+}
+"#,
+            r#"
+fn foo(num: i32) -> i32 {
+    return num
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_closure() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> Result<u32$0> {
+    let true_closure = || { return true; };
+    if the_field < 5 {
+        let mut i = 0;
+        if true_closure() {
+            return Ok(99);
+        } else {
+            return Ok(0);
+        }
+    }
+    Ok(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    let true_closure = || { return true; };
+    if the_field < 5 {
+        let mut i = 0;
+        if true_closure() {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    the_field
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> Result<u32$0> {
+    let true_closure = || {
+        return true;
+    };
+    if the_field < 5 {
+        let mut i = 0;
+
+
+        if true_closure() {
+            return Ok(99);
+        } else {
+            return Ok(0);
+        }
+    }
+    let t = None;
+
+    Ok(t.unwrap_or_else(|| the_field))
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    let true_closure = || {
+        return true;
+    };
+    if the_field < 5 {
+        let mut i = 0;
+
+
+        if true_closure() {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    let t = None;
+
+    t.unwrap_or_else(|| the_field)
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_simple_with_weird_forms() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0> {
+    let test = "test";
+    if test == "test" {
+        return Ok(24i32);
+    }
+    let mut i = 0;
+    loop {
+        if i == 1 {
+            break Ok(55);
+        }
+        i += 1;
+    }
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    let test = "test";
+    if test == "test" {
+        return 24i32;
+    }
+    let mut i = 0;
+    loop {
+        if i == 1 {
+            break 55;
+        }
+        i += 1;
+    }
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> Result<u32$0> {
+    if the_field < 5 {
+        let mut i = 0;
+        loop {
+            if i > 5 {
+                return Ok(55u32);
+            }
+            i += 3;
+        }
+        match i {
+            5 => return Ok(99),
+            _ => return Ok(0),
+        };
+    }
+    Ok(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        loop {
+            if i > 5 {
+                return 55u32;
+            }
+            i += 3;
+        }
+        match i {
+            5 => return 99,
+            _ => return 0,
+        };
+    }
+    the_field
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> Result<u32$0> {
+    if the_field < 5 {
+        let mut i = 0;
+        match i {
+            5 => return Ok(99),
+            _ => return Ok(0),
+        }
+    }
+    Ok(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        match i {
+            5 => return 99,
+            _ => return 0,
+        }
+    }
+    the_field
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> Result<u32$0> {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return Ok(99)
+        } else {
+            return Ok(0)
+        }
+    }
+    Ok(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return 99
+        } else {
+            return 0
+        }
+    }
+    the_field
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> Result<u3$02> {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return Ok(99);
+        } else {
+            return Ok(0);
+        }
+    }
+    Ok(the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    the_field
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+
+    #[test]
+    fn unwrap_result_return_type_nested_type() {
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result, option
+fn foo() -> Result<Option<i32$0>, ()> {
+    Ok(Some(42))
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    Some(42)
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result, option
+fn foo() -> Result<Option<Result<i32$0, ()>>, ()> {
+    Ok(None)
+}
+"#,
+            r#"
+fn foo() -> Option<Result<i32, ()>> {
+    None
+}
+"#,
+            "Unwrap Result return type",
+        );
+
+        check_assist_by_label(
+            unwrap_return_type,
+            r#"
+//- minicore: result, option, iterators
+fn foo() -> Result<impl Iterator<Item = i32>$0, ()> {
+    Ok(Some(42).into_iter())
+}
+"#,
+            r#"
+fn foo() -> impl Iterator<Item = i32> {
+    Some(42).into_iter()
+}
+"#,
+            "Unwrap Result return type",
+        );
+    }
+}
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
new file mode 100644
index 00000000000..2d918a5b1c1
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs
@@ -0,0 +1,2457 @@
+use std::iter;
+
+use hir::HasSource;
+use ide_db::{
+    assists::GroupLabel,
+    famous_defs::FamousDefs,
+    syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
+};
+use itertools::Itertools;
+use syntax::{
+    ast::{self, make, Expr, HasGenericParams},
+    match_ast, ted, AstNode, ToSmolStr,
+};
+
+use crate::{AssistContext, AssistId, AssistKind, Assists};
+
+// Assist: wrap_return_type_in_option
+//
+// Wrap the function's return type into Option.
+//
+// ```
+// # //- minicore: option
+// fn foo() -> i32$0 { 42i32 }
+// ```
+// ->
+// ```
+// fn foo() -> Option<i32> { Some(42i32) }
+// ```
+
+// Assist: wrap_return_type_in_result
+//
+// Wrap the function's return type into Result.
+//
+// ```
+// # //- minicore: result
+// fn foo() -> i32$0 { 42i32 }
+// ```
+// ->
+// ```
+// fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
+// ```
+
+pub(crate) fn wrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
+    let parent = ret_type.syntax().parent()?;
+    let body = match_ast! {
+        match parent {
+            ast::Fn(func) => func.body()?,
+            ast::ClosureExpr(closure) => match closure.body()? {
+                Expr::BlockExpr(block) => block,
+                // closures require a block when a return type is specified
+                _ => return None,
+            },
+            _ => return None,
+        }
+    };
+
+    let type_ref = &ret_type.ty()?;
+    let ty = ctx.sema.resolve_type(type_ref)?.as_adt();
+    let famous_defs = FamousDefs(&ctx.sema, ctx.sema.scope(type_ref.syntax())?.krate());
+
+    for kind in WrapperKind::ALL {
+        let Some(core_wrapper) = kind.core_type(&famous_defs) else {
+            continue;
+        };
+
+        if matches!(ty, Some(hir::Adt::Enum(ret_type)) if ret_type == core_wrapper) {
+            // The return type is already wrapped
+            cov_mark::hit!(wrap_return_type_simple_return_type_already_wrapped);
+            continue;
+        }
+
+        acc.add_group(
+            &GroupLabel("Wrap return type in...".into()),
+            kind.assist_id(),
+            kind.label(),
+            type_ref.syntax().text_range(),
+            |edit| {
+                let alias = wrapper_alias(ctx, &core_wrapper, type_ref, kind.symbol());
+                let new_return_ty =
+                    alias.unwrap_or_else(|| kind.wrap_type(type_ref)).clone_for_update();
+
+                let body = edit.make_mut(ast::Expr::BlockExpr(body.clone()));
+
+                let mut exprs_to_wrap = Vec::new();
+                let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_wrap, e);
+                walk_expr(&body, &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);
+                        }
+                    }
+                });
+                for_each_tail_expr(&body, tail_cb);
+
+                for ret_expr_arg in exprs_to_wrap {
+                    let happy_wrapped = make::expr_call(
+                        make::expr_path(make::ext::ident_path(kind.happy_ident())),
+                        make::arg_list(iter::once(ret_expr_arg.clone())),
+                    )
+                    .clone_for_update();
+                    ted::replace(ret_expr_arg.syntax(), happy_wrapped.syntax());
+                }
+
+                let old_return_ty = edit.make_mut(type_ref.clone());
+                ted::replace(old_return_ty.syntax(), new_return_ty.syntax());
+
+                if let WrapperKind::Result = kind {
+                    // Add a placeholder snippet at the first generic argument that doesn't equal the return type.
+                    // This is normally the error type, but that may not be the case when we inserted a type alias.
+                    let args =
+                        new_return_ty.syntax().descendants().find_map(ast::GenericArgList::cast);
+                    let error_type_arg = args.and_then(|list| {
+                        list.generic_args().find(|arg| match arg {
+                            ast::GenericArg::TypeArg(_) => {
+                                arg.syntax().text() != type_ref.syntax().text()
+                            }
+                            ast::GenericArg::LifetimeArg(_) => false,
+                            _ => true,
+                        })
+                    });
+                    if let Some(error_type_arg) = error_type_arg {
+                        if let Some(cap) = ctx.config.snippet_cap {
+                            edit.add_placeholder_snippet(cap, error_type_arg);
+                        }
+                    }
+                }
+            },
+        );
+    }
+
+    Some(())
+}
+
+enum WrapperKind {
+    Option,
+    Result,
+}
+
+impl WrapperKind {
+    const ALL: &'static [WrapperKind] = &[WrapperKind::Option, WrapperKind::Result];
+
+    fn assist_id(&self) -> AssistId {
+        let s = match self {
+            WrapperKind::Option => "wrap_return_type_in_option",
+            WrapperKind::Result => "wrap_return_type_in_result",
+        };
+
+        AssistId(s, AssistKind::RefactorRewrite)
+    }
+
+    fn label(&self) -> &'static str {
+        match self {
+            WrapperKind::Option => "Wrap return type in Option",
+            WrapperKind::Result => "Wrap return type in Result",
+        }
+    }
+
+    fn happy_ident(&self) -> &'static str {
+        match self {
+            WrapperKind::Option => "Some",
+            WrapperKind::Result => "Ok",
+        }
+    }
+
+    fn core_type(&self, famous_defs: &FamousDefs<'_, '_>) -> Option<hir::Enum> {
+        match self {
+            WrapperKind::Option => famous_defs.core_option_Option(),
+            WrapperKind::Result => famous_defs.core_result_Result(),
+        }
+    }
+
+    fn symbol(&self) -> hir::Symbol {
+        match self {
+            WrapperKind::Option => hir::sym::Option.clone(),
+            WrapperKind::Result => hir::sym::Result.clone(),
+        }
+    }
+
+    fn wrap_type(&self, type_ref: &ast::Type) -> ast::Type {
+        match self {
+            WrapperKind::Option => make::ext::ty_option(type_ref.clone()),
+            WrapperKind::Result => make::ext::ty_result(type_ref.clone(), make::ty_placeholder()),
+        }
+    }
+}
+
+// Try to find an wrapper type alias in the current scope (shadowing the default).
+fn wrapper_alias(
+    ctx: &AssistContext<'_>,
+    core_wrapper: &hir::Enum,
+    ret_type: &ast::Type,
+    wrapper: hir::Symbol,
+) -> Option<ast::Type> {
+    let wrapper_path = hir::ModPath::from_segments(
+        hir::PathKind::Plain,
+        iter::once(hir::Name::new_symbol_root(wrapper)),
+    );
+
+    ctx.sema.resolve_mod_path(ret_type.syntax(), &wrapper_path).and_then(|def| {
+        def.filter_map(|def| match def.as_module_def()? {
+            hir::ModuleDef::TypeAlias(alias) => {
+                let enum_ty = alias.ty(ctx.db()).as_adt()?.as_enum()?;
+                (&enum_ty == core_wrapper).then_some(alias)
+            }
+            _ => None,
+        })
+        .find_map(|alias| {
+            let mut inserted_ret_type = false;
+            let generic_params = alias
+                .source(ctx.db())?
+                .value
+                .generic_param_list()?
+                .generic_params()
+                .map(|param| match param {
+                    // Replace the very first type parameter with the functions return type.
+                    ast::GenericParam::TypeParam(_) if !inserted_ret_type => {
+                        inserted_ret_type = true;
+                        ret_type.to_smolstr()
+                    }
+                    ast::GenericParam::LifetimeParam(_) => make::lifetime("'_").to_smolstr(),
+                    _ => make::ty_placeholder().to_smolstr(),
+                })
+                .join(", ");
+
+            let name = alias.name(ctx.db());
+            let name = name.as_str();
+            Some(make::ty(&format!("{name}<{generic_params}>")))
+        })
+    })
+}
+
+fn tail_cb_impl(acc: &mut Vec<ast::Expr>, e: &ast::Expr) {
+    match e {
+        Expr::BreakExpr(break_expr) => {
+            if let Some(break_expr_arg) = break_expr.expr() {
+                for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(acc, e))
+            }
+        }
+        Expr::ReturnExpr(_) => {
+            // all return expressions have already been handled by the walk loop
+        }
+        e => acc.push(e.clone()),
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tests::{check_assist_by_label, check_assist_not_applicable_by_label};
+
+    use super::*;
+
+    #[test]
+    fn wrap_return_type_in_option_simple() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i3$02 {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let test = "test";
+    return Some(42i32);
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_break_split_tail() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i3$02 {
+    loop {
+        break if true {
+            1
+        } else {
+            0
+        };
+    }
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    loop {
+        break if true {
+            Some(1)
+        } else {
+            Some(0)
+        };
+    }
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_closure() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || -> i32$0 {
+        let test = "test";
+        return 42i32;
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> Option<i32> {
+        let test = "test";
+        return Some(42i32);
+    };
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_return_type_bad_cursor() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32 {
+    let test = "test";$0
+    return 42i32;
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_return_type_bad_cursor_closure() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || -> i32 {
+        let test = "test";$0
+        return 42i32;
+    };
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_closure_non_block() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() { || -> i$032 3; }
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_return_type_already_option_std() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> core::option::Option<i32$0> {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_return_type_already_option() {
+        cov_mark::check!(wrap_return_type_simple_return_type_already_wrapped);
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> Option<i32$0> {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_return_type_already_option_closure() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || -> Option<i32$0, String> {
+        let test = "test";
+        return 42i32;
+    };
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_cursor() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> $0i32 {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let test = "test";
+    return Some(42i32);
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_tail() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() ->$0 i32 {
+    let test = "test";
+    42i32
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let test = "test";
+    Some(42i32)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_tail_closure() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || ->$0 i32 {
+        let test = "test";
+        42i32
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> Option<i32> {
+        let test = "test";
+        Some(42i32)
+    };
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_tail_only() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 { 42i32 }
+"#,
+            r#"
+fn foo() -> Option<i32> { Some(42i32) }
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_tail_block_like() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    if true {
+        42i32
+    } else {
+        24i32
+    }
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    if true {
+        Some(42i32)
+    } else {
+        Some(24i32)
+    }
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_without_block_closure() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() {
+    || -> i32$0 {
+        if true {
+            42i32
+        } else {
+            24i32
+        }
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> Option<i32> {
+        if true {
+            Some(42i32)
+        } else {
+            Some(24i32)
+        }
+    };
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_nested_if() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    if true {
+        if false {
+            1
+        } else {
+            2
+        }
+    } else {
+        24i32
+    }
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    if true {
+        if false {
+            Some(1)
+        } else {
+            Some(2)
+        }
+    } else {
+        Some(24i32)
+    }
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_await() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+async fn foo() -> i$032 {
+    if true {
+        if false {
+            1.await
+        } else {
+            2.await
+        }
+    } else {
+        24i32.await
+    }
+}
+"#,
+            r#"
+async fn foo() -> Option<i32> {
+    if true {
+        if false {
+            Some(1.await)
+        } else {
+            Some(2.await)
+        }
+    } else {
+        Some(24i32.await)
+    }
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_array() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> [i32;$0 3] { [1, 2, 3] }
+"#,
+            r#"
+fn foo() -> Option<[i32; 3]> { Some([1, 2, 3]) }
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_cast() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -$0> i32 {
+    if true {
+        if false {
+            1 as i32
+        } else {
+            2 as i32
+        }
+    } else {
+        24 as i32
+    }
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    if true {
+        if false {
+            Some(1 as i32)
+        } else {
+            Some(2 as i32)
+        }
+    } else {
+        Some(24 as i32)
+    }
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_tail_block_like_match() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    let my_var = 5;
+    match my_var {
+        5 => 42i32,
+        _ => 24i32,
+    }
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let my_var = 5;
+    match my_var {
+        5 => Some(42i32),
+        _ => Some(24i32),
+    }
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_loop_with_tail() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    let my_var = 5;
+    loop {
+        println!("test");
+        5
+    }
+    my_var
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let my_var = 5;
+    loop {
+        println!("test");
+        5
+    }
+    Some(my_var)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_loop_in_let_stmt() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    let my_var = let x = loop {
+        break 1;
+    };
+    my_var
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let my_var = let x = loop {
+        break 1;
+    };
+    Some(my_var)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_tail_block_like_match_return_expr() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    let my_var = 5;
+    let res = match my_var {
+        5 => 42i32,
+        _ => return 24i32,
+    };
+    res
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let my_var = 5;
+    let res = match my_var {
+        5 => 42i32,
+        _ => return Some(24i32),
+    };
+    Some(res)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    let my_var = 5;
+    let res = if my_var == 5 {
+        42i32
+    } else {
+        return 24i32;
+    };
+    res
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let my_var = 5;
+    let res = if my_var == 5 {
+        42i32
+    } else {
+        return Some(24i32);
+    };
+    Some(res)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_tail_block_like_match_deeper() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    let my_var = 5;
+    match my_var {
+        5 => {
+            if true {
+                42i32
+            } else {
+                25i32
+            }
+        },
+        _ => {
+            let test = "test";
+            if test == "test" {
+                return bar();
+            }
+            53i32
+        },
+    }
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let my_var = 5;
+    match my_var {
+        5 => {
+            if true {
+                Some(42i32)
+            } else {
+                Some(25i32)
+            }
+        },
+        _ => {
+            let test = "test";
+            if test == "test" {
+                return Some(bar());
+            }
+            Some(53i32)
+        },
+    }
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_tail_block_like_early_return() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i$032 {
+    let test = "test";
+    if test == "test" {
+        return 24i32;
+    }
+    53i32
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let test = "test";
+    if test == "test" {
+        return Some(24i32);
+    }
+    Some(53i32)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_in_option_tail_position() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo(num: i32) -> $0i32 {
+    return num
+}
+"#,
+            r#"
+fn foo(num: i32) -> Option<i32> {
+    return Some(num)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_closure() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) ->$0 u32 {
+    let true_closure = || { return true; };
+    if the_field < 5 {
+        let mut i = 0;
+        if true_closure() {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Option<u32> {
+    let true_closure = || { return true; };
+    if the_field < 5 {
+        let mut i = 0;
+        if true_closure() {
+            return Some(99);
+        } else {
+            return Some(0);
+        }
+    }
+    Some(the_field)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> u32$0 {
+    let true_closure = || {
+        return true;
+    };
+    if the_field < 5 {
+        let mut i = 0;
+
+
+        if true_closure() {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    let t = None;
+
+    t.unwrap_or_else(|| the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Option<u32> {
+    let true_closure = || {
+        return true;
+    };
+    if the_field < 5 {
+        let mut i = 0;
+
+
+        if true_closure() {
+            return Some(99);
+        } else {
+            return Some(0);
+        }
+    }
+    let t = None;
+
+    Some(t.unwrap_or_else(|| the_field))
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_option_simple_with_weird_forms() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i32$0 {
+    let test = "test";
+    if test == "test" {
+        return 24i32;
+    }
+    let mut i = 0;
+    loop {
+        if i == 1 {
+            break 55;
+        }
+        i += 1;
+    }
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    let test = "test";
+    if test == "test" {
+        return Some(24i32);
+    }
+    let mut i = 0;
+    loop {
+        if i == 1 {
+            break Some(55);
+        }
+        i += 1;
+    }
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> u32$0 {
+    if the_field < 5 {
+        let mut i = 0;
+        loop {
+            if i > 5 {
+                return 55u32;
+            }
+            i += 3;
+        }
+        match i {
+            5 => return 99,
+            _ => return 0,
+        };
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Option<u32> {
+    if the_field < 5 {
+        let mut i = 0;
+        loop {
+            if i > 5 {
+                return Some(55u32);
+            }
+            i += 3;
+        }
+        match i {
+            5 => return Some(99),
+            _ => return Some(0),
+        };
+    }
+    Some(the_field)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> u3$02 {
+    if the_field < 5 {
+        let mut i = 0;
+        match i {
+            5 => return 99,
+            _ => return 0,
+        }
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Option<u32> {
+    if the_field < 5 {
+        let mut i = 0;
+        match i {
+            5 => return Some(99),
+            _ => return Some(0),
+        }
+    }
+    Some(the_field)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> u32$0 {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return 99
+        } else {
+            return 0
+        }
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Option<u32> {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return Some(99)
+        } else {
+            return Some(0)
+        }
+    }
+    Some(the_field)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo(the_field: u32) -> $0u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Option<u32> {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return Some(99);
+        } else {
+            return Some(0);
+        }
+    }
+    Some(the_field)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_option_type() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+type Option<T> = core::option::Option<T>;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+type Option<T> = core::option::Option<T>;
+
+fn foo() -> Option<i32> {
+    return Some(42i32);
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+type Option2<T> = core::option::Option<T>;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+type Option2<T> = core::option::Option<T>;
+
+fn foo() -> Option<i32> {
+    return Some(42i32);
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_imported_local_option_type() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+mod some_module {
+    pub type Option<T> = core::option::Option<T>;
+}
+
+use some_module::Option;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+mod some_module {
+    pub type Option<T> = core::option::Option<T>;
+}
+
+use some_module::Option;
+
+fn foo() -> Option<i32> {
+    return Some(42i32);
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+mod some_module {
+    pub type Option<T> = core::option::Option<T>;
+}
+
+use some_module::*;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+mod some_module {
+    pub type Option<T> = core::option::Option<T>;
+}
+
+use some_module::*;
+
+fn foo() -> Option<i32> {
+    return Some(42i32);
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_option_type_from_function_body() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+fn foo() -> i3$02 {
+    type Option<T> = core::option::Option<T>;
+    0
+}
+"#,
+            r#"
+fn foo() -> Option<i32> {
+    type Option<T> = core::option::Option<T>;
+    Some(0)
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_option_type_already_using_alias() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: option
+pub type Option<T> = core::option::Option<T>;
+
+fn foo() -> Option<i3$02> {
+    return Some(42i32);
+}
+"#,
+            WrapperKind::Option.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i3$02 {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let test = "test";
+    return Ok(42i32);
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_break_split_tail() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i3$02 {
+    loop {
+        break if true {
+            1
+        } else {
+            0
+        };
+    }
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    loop {
+        break if true {
+            Ok(1)
+        } else {
+            Ok(0)
+        };
+    }
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_closure() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || -> i32$0 {
+        let test = "test";
+        return 42i32;
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> Result<i32, ${0:_}> {
+        let test = "test";
+        return Ok(42i32);
+    };
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_return_type_bad_cursor() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32 {
+    let test = "test";$0
+    return 42i32;
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_return_type_bad_cursor_closure() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || -> i32 {
+        let test = "test";$0
+        return 42i32;
+    };
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_closure_non_block() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() { || -> i$032 3; }
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_return_type_already_result_std() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> core::result::Result<i32$0, String> {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_return_type_already_result() {
+        cov_mark::check!(wrap_return_type_simple_return_type_already_wrapped);
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> Result<i32$0, String> {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_return_type_already_result_closure() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || -> Result<i32$0, String> {
+        let test = "test";
+        return 42i32;
+    };
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_cursor() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> $0i32 {
+    let test = "test";
+    return 42i32;
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let test = "test";
+    return Ok(42i32);
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_tail() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() ->$0 i32 {
+    let test = "test";
+    42i32
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let test = "test";
+    Ok(42i32)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_tail_closure() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || ->$0 i32 {
+        let test = "test";
+        42i32
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> Result<i32, ${0:_}> {
+        let test = "test";
+        Ok(42i32)
+    };
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_tail_only() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 { 42i32 }
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_tail_block_like() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    if true {
+        42i32
+    } else {
+        24i32
+    }
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    if true {
+        Ok(42i32)
+    } else {
+        Ok(24i32)
+    }
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_without_block_closure() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() {
+    || -> i32$0 {
+        if true {
+            42i32
+        } else {
+            24i32
+        }
+    };
+}
+"#,
+            r#"
+fn foo() {
+    || -> Result<i32, ${0:_}> {
+        if true {
+            Ok(42i32)
+        } else {
+            Ok(24i32)
+        }
+    };
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_nested_if() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    if true {
+        if false {
+            1
+        } else {
+            2
+        }
+    } else {
+        24i32
+    }
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    if true {
+        if false {
+            Ok(1)
+        } else {
+            Ok(2)
+        }
+    } else {
+        Ok(24i32)
+    }
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_await() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+async fn foo() -> i$032 {
+    if true {
+        if false {
+            1.await
+        } else {
+            2.await
+        }
+    } else {
+        24i32.await
+    }
+}
+"#,
+            r#"
+async fn foo() -> Result<i32, ${0:_}> {
+    if true {
+        if false {
+            Ok(1.await)
+        } else {
+            Ok(2.await)
+        }
+    } else {
+        Ok(24i32.await)
+    }
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_array() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> [i32;$0 3] { [1, 2, 3] }
+"#,
+            r#"
+fn foo() -> Result<[i32; 3], ${0:_}> { Ok([1, 2, 3]) }
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_cast() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -$0> i32 {
+    if true {
+        if false {
+            1 as i32
+        } else {
+            2 as i32
+        }
+    } else {
+        24 as i32
+    }
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    if true {
+        if false {
+            Ok(1 as i32)
+        } else {
+            Ok(2 as i32)
+        }
+    } else {
+        Ok(24 as i32)
+    }
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_tail_block_like_match() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    let my_var = 5;
+    match my_var {
+        5 => 42i32,
+        _ => 24i32,
+    }
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let my_var = 5;
+    match my_var {
+        5 => Ok(42i32),
+        _ => Ok(24i32),
+    }
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_loop_with_tail() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    let my_var = 5;
+    loop {
+        println!("test");
+        5
+    }
+    my_var
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let my_var = 5;
+    loop {
+        println!("test");
+        5
+    }
+    Ok(my_var)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_loop_in_let_stmt() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    let my_var = let x = loop {
+        break 1;
+    };
+    my_var
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let my_var = let x = loop {
+        break 1;
+    };
+    Ok(my_var)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_tail_block_like_match_return_expr() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    let my_var = 5;
+    let res = match my_var {
+        5 => 42i32,
+        _ => return 24i32,
+    };
+    res
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let my_var = 5;
+    let res = match my_var {
+        5 => 42i32,
+        _ => return Ok(24i32),
+    };
+    Ok(res)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    let my_var = 5;
+    let res = if my_var == 5 {
+        42i32
+    } else {
+        return 24i32;
+    };
+    res
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let my_var = 5;
+    let res = if my_var == 5 {
+        42i32
+    } else {
+        return Ok(24i32);
+    };
+    Ok(res)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_tail_block_like_match_deeper() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    let my_var = 5;
+    match my_var {
+        5 => {
+            if true {
+                42i32
+            } else {
+                25i32
+            }
+        },
+        _ => {
+            let test = "test";
+            if test == "test" {
+                return bar();
+            }
+            53i32
+        },
+    }
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let my_var = 5;
+    match my_var {
+        5 => {
+            if true {
+                Ok(42i32)
+            } else {
+                Ok(25i32)
+            }
+        },
+        _ => {
+            let test = "test";
+            if test == "test" {
+                return Ok(bar());
+            }
+            Ok(53i32)
+        },
+    }
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_tail_block_like_early_return() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i$032 {
+    let test = "test";
+    if test == "test" {
+        return 24i32;
+    }
+    53i32
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let test = "test";
+    if test == "test" {
+        return Ok(24i32);
+    }
+    Ok(53i32)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_in_result_tail_position() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo(num: i32) -> $0i32 {
+    return num
+}
+"#,
+            r#"
+fn foo(num: i32) -> Result<i32, ${0:_}> {
+    return Ok(num)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_closure() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) ->$0 u32 {
+    let true_closure = || { return true; };
+    if the_field < 5 {
+        let mut i = 0;
+        if true_closure() {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Result<u32, ${0:_}> {
+    let true_closure = || { return true; };
+    if the_field < 5 {
+        let mut i = 0;
+        if true_closure() {
+            return Ok(99);
+        } else {
+            return Ok(0);
+        }
+    }
+    Ok(the_field)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> u32$0 {
+    let true_closure = || {
+        return true;
+    };
+    if the_field < 5 {
+        let mut i = 0;
+
+
+        if true_closure() {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    let t = None;
+
+    t.unwrap_or_else(|| the_field)
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Result<u32, ${0:_}> {
+    let true_closure = || {
+        return true;
+    };
+    if the_field < 5 {
+        let mut i = 0;
+
+
+        if true_closure() {
+            return Ok(99);
+        } else {
+            return Ok(0);
+        }
+    }
+    let t = None;
+
+    Ok(t.unwrap_or_else(|| the_field))
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_result_simple_with_weird_forms() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i32$0 {
+    let test = "test";
+    if test == "test" {
+        return 24i32;
+    }
+    let mut i = 0;
+    loop {
+        if i == 1 {
+            break 55;
+        }
+        i += 1;
+    }
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    let test = "test";
+    if test == "test" {
+        return Ok(24i32);
+    }
+    let mut i = 0;
+    loop {
+        if i == 1 {
+            break Ok(55);
+        }
+        i += 1;
+    }
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> u32$0 {
+    if the_field < 5 {
+        let mut i = 0;
+        loop {
+            if i > 5 {
+                return 55u32;
+            }
+            i += 3;
+        }
+        match i {
+            5 => return 99,
+            _ => return 0,
+        };
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Result<u32, ${0:_}> {
+    if the_field < 5 {
+        let mut i = 0;
+        loop {
+            if i > 5 {
+                return Ok(55u32);
+            }
+            i += 3;
+        }
+        match i {
+            5 => return Ok(99),
+            _ => return Ok(0),
+        };
+    }
+    Ok(the_field)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> u3$02 {
+    if the_field < 5 {
+        let mut i = 0;
+        match i {
+            5 => return 99,
+            _ => return 0,
+        }
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Result<u32, ${0:_}> {
+    if the_field < 5 {
+        let mut i = 0;
+        match i {
+            5 => return Ok(99),
+            _ => return Ok(0),
+        }
+    }
+    Ok(the_field)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> u32$0 {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return 99
+        } else {
+            return 0
+        }
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Result<u32, ${0:_}> {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return Ok(99)
+        } else {
+            return Ok(0)
+        }
+    }
+    Ok(the_field)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo(the_field: u32) -> $0u32 {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return 99;
+        } else {
+            return 0;
+        }
+    }
+    the_field
+}
+"#,
+            r#"
+fn foo(the_field: u32) -> Result<u32, ${0:_}> {
+    if the_field < 5 {
+        let mut i = 0;
+        if i == 5 {
+            return Ok(99);
+        } else {
+            return Ok(0);
+        }
+    }
+    Ok(the_field)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_result_type() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+type Result<T> = core::result::Result<T, ()>;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+type Result<T> = core::result::Result<T, ()>;
+
+fn foo() -> Result<i32> {
+    return Ok(42i32);
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+type Result2<T> = core::result::Result<T, ()>;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+type Result2<T> = core::result::Result<T, ()>;
+
+fn foo() -> Result<i32, ${0:_}> {
+    return Ok(42i32);
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_imported_local_result_type() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+mod some_module {
+    pub type Result<T> = core::result::Result<T, ()>;
+}
+
+use some_module::Result;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+mod some_module {
+    pub type Result<T> = core::result::Result<T, ()>;
+}
+
+use some_module::Result;
+
+fn foo() -> Result<i32> {
+    return Ok(42i32);
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+mod some_module {
+    pub type Result<T> = core::result::Result<T, ()>;
+}
+
+use some_module::*;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+mod some_module {
+    pub type Result<T> = core::result::Result<T, ()>;
+}
+
+use some_module::*;
+
+fn foo() -> Result<i32> {
+    return Ok(42i32);
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_result_type_from_function_body() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+fn foo() -> i3$02 {
+    type Result<T> = core::result::Result<T, ()>;
+    0
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    type Result<T> = core::result::Result<T, ()>;
+    Ok(0)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_result_type_already_using_alias() {
+        check_assist_not_applicable_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+pub type Result<T> = core::result::Result<T, ()>;
+
+fn foo() -> Result<i3$02> {
+    return Ok(42i32);
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_result_type_multiple_generics() {
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+type Result<T, E> = core::result::Result<T, E>;
+
+fn foo() -> i3$02 {
+    0
+}
+"#,
+            r#"
+type Result<T, E> = core::result::Result<T, E>;
+
+fn foo() -> Result<i32, ${0:_}> {
+    Ok(0)
+}
+"#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+type Result<T, E> = core::result::Result<Foo<T, E>, ()>;
+
+fn foo() -> i3$02 {
+    0
+}
+            "#,
+            r#"
+type Result<T, E> = core::result::Result<Foo<T, E>, ()>;
+
+fn foo() -> Result<i32, ${0:_}> {
+    Ok(0)
+}
+            "#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+type Result<'a, T, E> = core::result::Result<Foo<T, E>, &'a ()>;
+
+fn foo() -> i3$02 {
+    0
+}
+            "#,
+            r#"
+type Result<'a, T, E> = core::result::Result<Foo<T, E>, &'a ()>;
+
+fn foo() -> Result<'_, i32, ${0:_}> {
+    Ok(0)
+}
+            "#,
+            WrapperKind::Result.label(),
+        );
+
+        check_assist_by_label(
+            wrap_return_type,
+            r#"
+//- minicore: result
+type Result<T, const N: usize> = core::result::Result<Foo<T>, Bar<N>>;
+
+fn foo() -> i3$02 {
+    0
+}
+            "#,
+            r#"
+type Result<T, const N: usize> = core::result::Result<Foo<T>, Bar<N>>;
+
+fn foo() -> Result<i32, ${0:_}> {
+    Ok(0)
+}
+            "#,
+            WrapperKind::Result.label(),
+        );
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
deleted file mode 100644
index 8f0e9b4fe09..00000000000
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
+++ /dev/null
@@ -1,1268 +0,0 @@
-use std::iter;
-
-use hir::HasSource;
-use ide_db::{
-    famous_defs::FamousDefs,
-    syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
-};
-use itertools::Itertools;
-use syntax::{
-    ast::{self, make, Expr, HasGenericParams},
-    match_ast, ted, AstNode, ToSmolStr,
-};
-
-use crate::{AssistContext, AssistId, AssistKind, Assists};
-
-// Assist: wrap_return_type_in_result
-//
-// Wrap the function's return type into Result.
-//
-// ```
-// # //- minicore: result
-// fn foo() -> i32$0 { 42i32 }
-// ```
-// ->
-// ```
-// fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
-// ```
-pub(crate) fn wrap_return_type_in_result(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
-    let parent = ret_type.syntax().parent()?;
-    let body = match_ast! {
-        match parent {
-            ast::Fn(func) => func.body()?,
-            ast::ClosureExpr(closure) => match closure.body()? {
-                Expr::BlockExpr(block) => block,
-                // closures require a block when a return type is specified
-                _ => return None,
-            },
-            _ => return None,
-        }
-    };
-
-    let type_ref = &ret_type.ty()?;
-    let core_result =
-        FamousDefs(&ctx.sema, ctx.sema.scope(type_ref.syntax())?.krate()).core_result_Result()?;
-
-    let ty = ctx.sema.resolve_type(type_ref)?.as_adt();
-    if matches!(ty, Some(hir::Adt::Enum(ret_type)) if ret_type == core_result) {
-        // The return type is already wrapped in a Result
-        cov_mark::hit!(wrap_return_type_in_result_simple_return_type_already_result);
-        return None;
-    }
-
-    acc.add(
-        AssistId("wrap_return_type_in_result", AssistKind::RefactorRewrite),
-        "Wrap return type in Result",
-        type_ref.syntax().text_range(),
-        |edit| {
-            let new_result_ty = result_type(ctx, &core_result, type_ref).clone_for_update();
-            let body = edit.make_mut(ast::Expr::BlockExpr(body));
-
-            let mut exprs_to_wrap = Vec::new();
-            let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_wrap, e);
-            walk_expr(&body, &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);
-                    }
-                }
-            });
-            for_each_tail_expr(&body, tail_cb);
-
-            for ret_expr_arg in exprs_to_wrap {
-                let ok_wrapped = make::expr_call(
-                    make::expr_path(make::ext::ident_path("Ok")),
-                    make::arg_list(iter::once(ret_expr_arg.clone())),
-                )
-                .clone_for_update();
-                ted::replace(ret_expr_arg.syntax(), ok_wrapped.syntax());
-            }
-
-            let old_result_ty = edit.make_mut(type_ref.clone());
-            ted::replace(old_result_ty.syntax(), new_result_ty.syntax());
-
-            // Add a placeholder snippet at the first generic argument that doesn't equal the return type.
-            // This is normally the error type, but that may not be the case when we inserted a type alias.
-            let args = new_result_ty.syntax().descendants().find_map(ast::GenericArgList::cast);
-            let error_type_arg = args.and_then(|list| {
-                list.generic_args().find(|arg| match arg {
-                    ast::GenericArg::TypeArg(_) => arg.syntax().text() != type_ref.syntax().text(),
-                    ast::GenericArg::LifetimeArg(_) => false,
-                    _ => true,
-                })
-            });
-            if let Some(error_type_arg) = error_type_arg {
-                if let Some(cap) = ctx.config.snippet_cap {
-                    edit.add_placeholder_snippet(cap, error_type_arg);
-                }
-            }
-        },
-    )
-}
-
-fn result_type(
-    ctx: &AssistContext<'_>,
-    core_result: &hir::Enum,
-    ret_type: &ast::Type,
-) -> ast::Type {
-    // Try to find a Result<T, ...> type alias in the current scope (shadowing the default).
-    let result_path = hir::ModPath::from_segments(
-        hir::PathKind::Plain,
-        iter::once(hir::Name::new_symbol_root(hir::sym::Result.clone())),
-    );
-    let alias = ctx.sema.resolve_mod_path(ret_type.syntax(), &result_path).and_then(|def| {
-        def.filter_map(|def| match def.as_module_def()? {
-            hir::ModuleDef::TypeAlias(alias) => {
-                let enum_ty = alias.ty(ctx.db()).as_adt()?.as_enum()?;
-                (&enum_ty == core_result).then_some(alias)
-            }
-            _ => None,
-        })
-        .find_map(|alias| {
-            let mut inserted_ret_type = false;
-            let generic_params = alias
-                .source(ctx.db())?
-                .value
-                .generic_param_list()?
-                .generic_params()
-                .map(|param| match param {
-                    // Replace the very first type parameter with the functions return type.
-                    ast::GenericParam::TypeParam(_) if !inserted_ret_type => {
-                        inserted_ret_type = true;
-                        ret_type.to_smolstr()
-                    }
-                    ast::GenericParam::LifetimeParam(_) => make::lifetime("'_").to_smolstr(),
-                    _ => make::ty_placeholder().to_smolstr(),
-                })
-                .join(", ");
-
-            let name = alias.name(ctx.db());
-            let name = name.as_str();
-            Some(make::ty(&format!("{name}<{generic_params}>")))
-        })
-    });
-    // If there is no applicable alias in scope use the default Result type.
-    alias.unwrap_or_else(|| make::ext::ty_result(ret_type.clone(), make::ty_placeholder()))
-}
-
-fn tail_cb_impl(acc: &mut Vec<ast::Expr>, e: &ast::Expr) {
-    match e {
-        Expr::BreakExpr(break_expr) => {
-            if let Some(break_expr_arg) = break_expr.expr() {
-                for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(acc, e))
-            }
-        }
-        Expr::ReturnExpr(_) => {
-            // all return expressions have already been handled by the walk loop
-        }
-        e => acc.push(e.clone()),
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable};
-
-    use super::*;
-
-    #[test]
-    fn wrap_return_type_in_result_simple() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i3$02 {
-    let test = "test";
-    return 42i32;
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let test = "test";
-    return Ok(42i32);
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_break_split_tail() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i3$02 {
-    loop {
-        break if true {
-            1
-        } else {
-            0
-        };
-    }
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    loop {
-        break if true {
-            Ok(1)
-        } else {
-            Ok(0)
-        };
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_closure() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() {
-    || -> i32$0 {
-        let test = "test";
-        return 42i32;
-    };
-}
-"#,
-            r#"
-fn foo() {
-    || -> Result<i32, ${0:_}> {
-        let test = "test";
-        return Ok(42i32);
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_return_type_bad_cursor() {
-        check_assist_not_applicable(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32 {
-    let test = "test";$0
-    return 42i32;
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_return_type_bad_cursor_closure() {
-        check_assist_not_applicable(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() {
-    || -> i32 {
-        let test = "test";$0
-        return 42i32;
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_closure_non_block() {
-        check_assist_not_applicable(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() { || -> i$032 3; }
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_return_type_already_result_std() {
-        check_assist_not_applicable(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> core::result::Result<i32$0, String> {
-    let test = "test";
-    return 42i32;
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_return_type_already_result() {
-        cov_mark::check!(wrap_return_type_in_result_simple_return_type_already_result);
-        check_assist_not_applicable(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> Result<i32$0, String> {
-    let test = "test";
-    return 42i32;
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_return_type_already_result_closure() {
-        check_assist_not_applicable(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() {
-    || -> Result<i32$0, String> {
-        let test = "test";
-        return 42i32;
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_cursor() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> $0i32 {
-    let test = "test";
-    return 42i32;
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let test = "test";
-    return Ok(42i32);
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_tail() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() ->$0 i32 {
-    let test = "test";
-    42i32
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let test = "test";
-    Ok(42i32)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_tail_closure() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() {
-    || ->$0 i32 {
-        let test = "test";
-        42i32
-    };
-}
-"#,
-            r#"
-fn foo() {
-    || -> Result<i32, ${0:_}> {
-        let test = "test";
-        Ok(42i32)
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_tail_only() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 { 42i32 }
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_tail_block_like() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    if true {
-        42i32
-    } else {
-        24i32
-    }
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    if true {
-        Ok(42i32)
-    } else {
-        Ok(24i32)
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_without_block_closure() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() {
-    || -> i32$0 {
-        if true {
-            42i32
-        } else {
-            24i32
-        }
-    };
-}
-"#,
-            r#"
-fn foo() {
-    || -> Result<i32, ${0:_}> {
-        if true {
-            Ok(42i32)
-        } else {
-            Ok(24i32)
-        }
-    };
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_nested_if() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    if true {
-        if false {
-            1
-        } else {
-            2
-        }
-    } else {
-        24i32
-    }
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    if true {
-        if false {
-            Ok(1)
-        } else {
-            Ok(2)
-        }
-    } else {
-        Ok(24i32)
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_await() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-async fn foo() -> i$032 {
-    if true {
-        if false {
-            1.await
-        } else {
-            2.await
-        }
-    } else {
-        24i32.await
-    }
-}
-"#,
-            r#"
-async fn foo() -> Result<i32, ${0:_}> {
-    if true {
-        if false {
-            Ok(1.await)
-        } else {
-            Ok(2.await)
-        }
-    } else {
-        Ok(24i32.await)
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_array() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> [i32;$0 3] { [1, 2, 3] }
-"#,
-            r#"
-fn foo() -> Result<[i32; 3], ${0:_}> { Ok([1, 2, 3]) }
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_cast() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -$0> i32 {
-    if true {
-        if false {
-            1 as i32
-        } else {
-            2 as i32
-        }
-    } else {
-        24 as i32
-    }
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    if true {
-        if false {
-            Ok(1 as i32)
-        } else {
-            Ok(2 as i32)
-        }
-    } else {
-        Ok(24 as i32)
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_tail_block_like_match() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    let my_var = 5;
-    match my_var {
-        5 => 42i32,
-        _ => 24i32,
-    }
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let my_var = 5;
-    match my_var {
-        5 => Ok(42i32),
-        _ => Ok(24i32),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_loop_with_tail() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    let my_var = 5;
-    loop {
-        println!("test");
-        5
-    }
-    my_var
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let my_var = 5;
-    loop {
-        println!("test");
-        5
-    }
-    Ok(my_var)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_loop_in_let_stmt() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    let my_var = let x = loop {
-        break 1;
-    };
-    my_var
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let my_var = let x = loop {
-        break 1;
-    };
-    Ok(my_var)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_tail_block_like_match_return_expr() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    let my_var = 5;
-    let res = match my_var {
-        5 => 42i32,
-        _ => return 24i32,
-    };
-    res
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let my_var = 5;
-    let res = match my_var {
-        5 => 42i32,
-        _ => return Ok(24i32),
-    };
-    Ok(res)
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    let my_var = 5;
-    let res = if my_var == 5 {
-        42i32
-    } else {
-        return 24i32;
-    };
-    res
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let my_var = 5;
-    let res = if my_var == 5 {
-        42i32
-    } else {
-        return Ok(24i32);
-    };
-    Ok(res)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_tail_block_like_match_deeper() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    let my_var = 5;
-    match my_var {
-        5 => {
-            if true {
-                42i32
-            } else {
-                25i32
-            }
-        },
-        _ => {
-            let test = "test";
-            if test == "test" {
-                return bar();
-            }
-            53i32
-        },
-    }
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let my_var = 5;
-    match my_var {
-        5 => {
-            if true {
-                Ok(42i32)
-            } else {
-                Ok(25i32)
-            }
-        },
-        _ => {
-            let test = "test";
-            if test == "test" {
-                return Ok(bar());
-            }
-            Ok(53i32)
-        },
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_tail_block_like_early_return() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i$032 {
-    let test = "test";
-    if test == "test" {
-        return 24i32;
-    }
-    53i32
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let test = "test";
-    if test == "test" {
-        return Ok(24i32);
-    }
-    Ok(53i32)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_in_tail_position() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo(num: i32) -> $0i32 {
-    return num
-}
-"#,
-            r#"
-fn foo(num: i32) -> Result<i32, ${0:_}> {
-    return Ok(num)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_closure() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) ->$0 u32 {
-    let true_closure = || { return true; };
-    if the_field < 5 {
-        let mut i = 0;
-        if true_closure() {
-            return 99;
-        } else {
-            return 0;
-        }
-    }
-    the_field
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> Result<u32, ${0:_}> {
-    let true_closure = || { return true; };
-    if the_field < 5 {
-        let mut i = 0;
-        if true_closure() {
-            return Ok(99);
-        } else {
-            return Ok(0);
-        }
-    }
-    Ok(the_field)
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> u32$0 {
-    let true_closure = || {
-        return true;
-    };
-    if the_field < 5 {
-        let mut i = 0;
-
-
-        if true_closure() {
-            return 99;
-        } else {
-            return 0;
-        }
-    }
-    let t = None;
-
-    t.unwrap_or_else(|| the_field)
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> Result<u32, ${0:_}> {
-    let true_closure = || {
-        return true;
-    };
-    if the_field < 5 {
-        let mut i = 0;
-
-
-        if true_closure() {
-            return Ok(99);
-        } else {
-            return Ok(0);
-        }
-    }
-    let t = None;
-
-    Ok(t.unwrap_or_else(|| the_field))
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_result_simple_with_weird_forms() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i32$0 {
-    let test = "test";
-    if test == "test" {
-        return 24i32;
-    }
-    let mut i = 0;
-    loop {
-        if i == 1 {
-            break 55;
-        }
-        i += 1;
-    }
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    let test = "test";
-    if test == "test" {
-        return Ok(24i32);
-    }
-    let mut i = 0;
-    loop {
-        if i == 1 {
-            break Ok(55);
-        }
-        i += 1;
-    }
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> u32$0 {
-    if the_field < 5 {
-        let mut i = 0;
-        loop {
-            if i > 5 {
-                return 55u32;
-            }
-            i += 3;
-        }
-        match i {
-            5 => return 99,
-            _ => return 0,
-        };
-    }
-    the_field
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> Result<u32, ${0:_}> {
-    if the_field < 5 {
-        let mut i = 0;
-        loop {
-            if i > 5 {
-                return Ok(55u32);
-            }
-            i += 3;
-        }
-        match i {
-            5 => return Ok(99),
-            _ => return Ok(0),
-        };
-    }
-    Ok(the_field)
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> u3$02 {
-    if the_field < 5 {
-        let mut i = 0;
-        match i {
-            5 => return 99,
-            _ => return 0,
-        }
-    }
-    the_field
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> Result<u32, ${0:_}> {
-    if the_field < 5 {
-        let mut i = 0;
-        match i {
-            5 => return Ok(99),
-            _ => return Ok(0),
-        }
-    }
-    Ok(the_field)
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> u32$0 {
-    if the_field < 5 {
-        let mut i = 0;
-        if i == 5 {
-            return 99
-        } else {
-            return 0
-        }
-    }
-    the_field
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> Result<u32, ${0:_}> {
-    if the_field < 5 {
-        let mut i = 0;
-        if i == 5 {
-            return Ok(99)
-        } else {
-            return Ok(0)
-        }
-    }
-    Ok(the_field)
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo(the_field: u32) -> $0u32 {
-    if the_field < 5 {
-        let mut i = 0;
-        if i == 5 {
-            return 99;
-        } else {
-            return 0;
-        }
-    }
-    the_field
-}
-"#,
-            r#"
-fn foo(the_field: u32) -> Result<u32, ${0:_}> {
-    if the_field < 5 {
-        let mut i = 0;
-        if i == 5 {
-            return Ok(99);
-        } else {
-            return Ok(0);
-        }
-    }
-    Ok(the_field)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_local_result_type() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-type Result<T> = core::result::Result<T, ()>;
-
-fn foo() -> i3$02 {
-    return 42i32;
-}
-"#,
-            r#"
-type Result<T> = core::result::Result<T, ()>;
-
-fn foo() -> Result<i32> {
-    return Ok(42i32);
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-type Result2<T> = core::result::Result<T, ()>;
-
-fn foo() -> i3$02 {
-    return 42i32;
-}
-"#,
-            r#"
-type Result2<T> = core::result::Result<T, ()>;
-
-fn foo() -> Result<i32, ${0:_}> {
-    return Ok(42i32);
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_imported_local_result_type() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-mod some_module {
-    pub type Result<T> = core::result::Result<T, ()>;
-}
-
-use some_module::Result;
-
-fn foo() -> i3$02 {
-    return 42i32;
-}
-"#,
-            r#"
-mod some_module {
-    pub type Result<T> = core::result::Result<T, ()>;
-}
-
-use some_module::Result;
-
-fn foo() -> Result<i32> {
-    return Ok(42i32);
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-mod some_module {
-    pub type Result<T> = core::result::Result<T, ()>;
-}
-
-use some_module::*;
-
-fn foo() -> i3$02 {
-    return 42i32;
-}
-"#,
-            r#"
-mod some_module {
-    pub type Result<T> = core::result::Result<T, ()>;
-}
-
-use some_module::*;
-
-fn foo() -> Result<i32> {
-    return Ok(42i32);
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_local_result_type_from_function_body() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-fn foo() -> i3$02 {
-    type Result<T> = core::result::Result<T, ()>;
-    0
-}
-"#,
-            r#"
-fn foo() -> Result<i32, ${0:_}> {
-    type Result<T> = core::result::Result<T, ()>;
-    Ok(0)
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_local_result_type_already_using_alias() {
-        check_assist_not_applicable(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-pub type Result<T> = core::result::Result<T, ()>;
-
-fn foo() -> Result<i3$02> {
-    return Ok(42i32);
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn wrap_return_type_in_local_result_type_multiple_generics() {
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-type Result<T, E> = core::result::Result<T, E>;
-
-fn foo() -> i3$02 {
-    0
-}
-"#,
-            r#"
-type Result<T, E> = core::result::Result<T, E>;
-
-fn foo() -> Result<i32, ${0:_}> {
-    Ok(0)
-}
-"#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-type Result<T, E> = core::result::Result<Foo<T, E>, ()>;
-
-fn foo() -> i3$02 {
-    0
-}
-            "#,
-            r#"
-type Result<T, E> = core::result::Result<Foo<T, E>, ()>;
-
-fn foo() -> Result<i32, ${0:_}> {
-    Ok(0)
-}
-            "#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-type Result<'a, T, E> = core::result::Result<Foo<T, E>, &'a ()>;
-
-fn foo() -> i3$02 {
-    0
-}
-            "#,
-            r#"
-type Result<'a, T, E> = core::result::Result<Foo<T, E>, &'a ()>;
-
-fn foo() -> Result<'_, i32, ${0:_}> {
-    Ok(0)
-}
-            "#,
-        );
-
-        check_assist(
-            wrap_return_type_in_result,
-            r#"
-//- minicore: result
-type Result<T, const N: usize> = core::result::Result<Foo<T>, Bar<N>>;
-
-fn foo() -> i3$02 {
-    0
-}
-            "#,
-            r#"
-type Result<T, const N: usize> = core::result::Result<Foo<T>, Bar<N>>;
-
-fn foo() -> Result<i32, ${0:_}> {
-    Ok(0)
-}
-            "#,
-        );
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
index c98655b4230..22620816d50 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
@@ -223,9 +223,9 @@ mod handlers {
     mod unnecessary_async;
     mod unqualify_method_call;
     mod unwrap_block;
-    mod unwrap_result_return_type;
+    mod unwrap_return_type;
     mod unwrap_tuple;
-    mod wrap_return_type_in_result;
+    mod wrap_return_type;
     mod wrap_unwrap_cfg_attr;
 
     pub(crate) fn all() -> &'static [Handler] {
@@ -355,10 +355,10 @@ mod handlers {
             unmerge_use::unmerge_use,
             unnecessary_async::unnecessary_async,
             unwrap_block::unwrap_block,
-            unwrap_result_return_type::unwrap_result_return_type,
+            unwrap_return_type::unwrap_return_type,
             unwrap_tuple::unwrap_tuple,
             unqualify_method_call::unqualify_method_call,
-            wrap_return_type_in_result::wrap_return_type_in_result,
+            wrap_return_type::wrap_return_type,
             wrap_unwrap_cfg_attr::wrap_unwrap_cfg_attr,
 
             // These are manually sorted for better priorities. By default,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 48e12a81073..933d45d7508 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -3265,6 +3265,20 @@ fn foo() {
 }
 
 #[test]
+fn doctest_unwrap_option_return_type() {
+    check_doc_test(
+        "unwrap_option_return_type",
+        r#####"
+//- minicore: option
+fn foo() -> Option<i32>$0 { Some(42i32) }
+"#####,
+        r#####"
+fn foo() -> i32 { 42i32 }
+"#####,
+    )
+}
+
+#[test]
 fn doctest_unwrap_result_return_type() {
     check_doc_test(
         "unwrap_result_return_type",
@@ -3298,6 +3312,20 @@ fn main() {
 }
 
 #[test]
+fn doctest_wrap_return_type_in_option() {
+    check_doc_test(
+        "wrap_return_type_in_option",
+        r#####"
+//- minicore: option
+fn foo() -> i32$0 { 42i32 }
+"#####,
+        r#####"
+fn foo() -> Option<i32> { Some(42i32) }
+"#####,
+    )
+}
+
+#[test]
 fn doctest_wrap_return_type_in_result() {
     check_doc_test(
         "wrap_return_type_in_result",
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs
index 18833774083..3ab341e4ede 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs
@@ -29,7 +29,9 @@ pub(crate) fn complete_item_list(
     kind: &ItemListKind,
 ) {
     let _p = tracing::info_span!("complete_item_list").entered();
-    if path_ctx.is_trivial_path() {
+
+    // We handle completions for trait-impls in [`item_list::trait_impl`]
+    if path_ctx.is_trivial_path() && !matches!(kind, ItemListKind::TraitImpl(_)) {
         add_keywords(acc, ctx, Some(kind));
     }
 
@@ -75,73 +77,95 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
 
     let in_item_list = matches!(kind, Some(ItemListKind::SourceFile | ItemListKind::Module) | None);
     let in_assoc_non_trait_impl = matches!(kind, Some(ItemListKind::Impl | ItemListKind::Trait));
-    let in_extern_block = matches!(kind, Some(ItemListKind::ExternBlock));
+
+    let in_extern_block = matches!(kind, Some(ItemListKind::ExternBlock { .. }));
+    let in_unsafe_extern_block =
+        matches!(kind, Some(ItemListKind::ExternBlock { is_unsafe: true }));
+
     let in_trait = matches!(kind, Some(ItemListKind::Trait));
-    let in_trait_impl = matches!(kind, Some(ItemListKind::TraitImpl(_)));
     let in_inherent_impl = matches!(kind, Some(ItemListKind::Impl));
-    let no_vis_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
     let in_block = kind.is_none();
 
-    let missing_qualifiers = [
-        ctx.qualifier_ctx.unsafe_tok.is_none().then_some(("unsafe", "unsafe $0")),
-        ctx.qualifier_ctx.async_tok.is_none().then_some(("async", "async $0")),
-    ];
-
-    if !in_trait_impl {
-        // handle qualifier tokens
-        if missing_qualifiers.iter().any(Option::is_none) {
-            // only complete missing qualifiers
-            missing_qualifiers.iter().filter_map(|x| *x).for_each(|(kw, snippet)| {
-                add_keyword(kw, snippet);
-            });
-
-            if in_item_list || in_assoc_non_trait_impl {
-                add_keyword("fn", "fn $1($2) {\n    $0\n}");
-            }
+    let no_vis_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
+    let has_unsafe_kw = ctx.qualifier_ctx.unsafe_tok.is_some();
+    let has_async_kw = ctx.qualifier_ctx.async_tok.is_some();
+    let has_safe_kw = ctx.qualifier_ctx.safe_tok.is_some();
+
+    // Some keywords are invalid after non-vis qualifiers, so we handle them first.
+    if (has_unsafe_kw || has_safe_kw) && in_extern_block {
+        add_keyword("fn", "fn $1($2);");
+        add_keyword("static", "static $1: $2;");
+        return;
+    }
 
-            if ctx.qualifier_ctx.unsafe_tok.is_some() && in_item_list {
-                add_keyword("trait", "trait $1 {\n    $0\n}");
-                if no_vis_qualifiers {
-                    add_keyword("impl", "impl $1 {\n    $0\n}");
-                }
-            }
+    if has_unsafe_kw || has_async_kw {
+        if !has_unsafe_kw {
+            add_keyword("unsafe", "unsafe $0");
+        }
+        if !has_async_kw {
+            add_keyword("async", "async $0");
+        }
 
-            return;
+        if in_item_list || in_assoc_non_trait_impl {
+            add_keyword("fn", "fn $1($2) {\n    $0\n}");
         }
 
-        if in_item_list {
-            add_keyword("enum", "enum $1 {\n    $0\n}");
-            add_keyword("mod", "mod $0");
-            add_keyword("static", "static $0");
-            add_keyword("struct", "struct $0");
+        if has_unsafe_kw && in_item_list {
             add_keyword("trait", "trait $1 {\n    $0\n}");
-            add_keyword("union", "union $1 {\n    $0\n}");
-            add_keyword("use", "use $0");
             if no_vis_qualifiers {
                 add_keyword("impl", "impl $1 {\n    $0\n}");
             }
         }
 
-        if !in_trait && !in_block && no_vis_qualifiers {
-            add_keyword("pub(crate)", "pub(crate) $0");
-            add_keyword("pub(super)", "pub(super) $0");
-            add_keyword("pub", "pub $0");
+        if !has_async_kw && no_vis_qualifiers && in_item_list {
+            add_keyword("extern", "extern $0");
         }
 
-        if in_extern_block {
-            add_keyword("fn", "fn $1($2);");
-        } else {
-            if !in_inherent_impl {
-                if !in_trait {
-                    add_keyword("extern", "extern $0");
-                }
-                add_keyword("type", "type $0");
-            }
+        return;
+    }
 
-            add_keyword("fn", "fn $1($2) {\n    $0\n}");
-            add_keyword("unsafe", "unsafe $0");
-            add_keyword("const", "const $0");
-            add_keyword("async", "async $0");
+    // ...and the rest deals with cases without any non-vis qualifiers.
+
+    // Visibility qualifiers
+    if !in_trait && !in_block && no_vis_qualifiers {
+        add_keyword("pub(crate)", "pub(crate) $0");
+        add_keyword("pub(super)", "pub(super) $0");
+        add_keyword("pub", "pub $0");
+    }
+
+    // Keywords that are valid in `item_list`
+    if in_item_list {
+        add_keyword("enum", "enum $1 {\n    $0\n}");
+        add_keyword("mod", "mod $0");
+        add_keyword("static", "static $0");
+        add_keyword("struct", "struct $0");
+        add_keyword("trait", "trait $1 {\n    $0\n}");
+        add_keyword("union", "union $1 {\n    $0\n}");
+        add_keyword("use", "use $0");
+        if no_vis_qualifiers {
+            add_keyword("impl", "impl $1 {\n    $0\n}");
+        }
+    }
+
+    if in_extern_block {
+        add_keyword("unsafe", "unsafe $0");
+        if in_unsafe_extern_block {
+            add_keyword("safe", "safe $0");
         }
+
+        add_keyword("fn", "fn $1($2);");
+        add_keyword("static", "static $1: $2;");
+    } else {
+        if !in_inherent_impl {
+            if !in_trait {
+                add_keyword("extern", "extern $0");
+            }
+            add_keyword("type", "type $0");
+        }
+
+        add_keyword("fn", "fn $1($2) {\n    $0\n}");
+        add_keyword("unsafe", "unsafe $0");
+        add_keyword("const", "const $0");
+        add_keyword("async", "async $0");
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
index 0acb87872f5..71ca6e99494 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
@@ -58,6 +58,7 @@ mod tests {
             r"fn my_fn() { unsafe $0 }",
             expect![[r#"
                 kw async
+                kw extern
                 kw fn
                 kw impl
                 kw trait
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
index e49a9e3b064..0e1302ff2ef 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -48,12 +48,16 @@ pub(crate) struct QualifierCtx {
     // TODO: Add try_tok and default_tok
     pub(crate) async_tok: Option<SyntaxToken>,
     pub(crate) unsafe_tok: Option<SyntaxToken>,
+    pub(crate) safe_tok: Option<SyntaxToken>,
     pub(crate) vis_node: Option<ast::Visibility>,
 }
 
 impl QualifierCtx {
     pub(crate) fn none(&self) -> bool {
-        self.async_tok.is_none() && self.unsafe_tok.is_none() && self.vis_node.is_none()
+        self.async_tok.is_none()
+            && self.unsafe_tok.is_none()
+            && self.safe_tok.is_none()
+            && self.vis_node.is_none()
     }
 }
 
@@ -229,7 +233,7 @@ pub(crate) enum ItemListKind {
     Impl,
     TraitImpl(Option<ast::Impl>),
     Trait,
-    ExternBlock,
+    ExternBlock { is_unsafe: bool },
 }
 
 #[derive(Debug)]
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 1f9e3edf625..468ad81ad2f 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
@@ -1108,7 +1108,14 @@ fn classify_name_ref(
                     },
                     None => return None,
                 } },
-                ast::ExternItemList(_) => PathKind::Item { kind: ItemListKind::ExternBlock },
+                ast::ExternItemList(it) => {
+                    let exn_blk = it.syntax().parent().and_then(ast::ExternBlock::cast);
+                    PathKind::Item {
+                        kind: ItemListKind::ExternBlock {
+                            is_unsafe: exn_blk.and_then(|it| it.unsafe_token()).is_some(),
+                        }
+                    }
+                },
                 ast::SourceFile(_) => PathKind::Item { kind: ItemListKind::SourceFile },
                 _ => return None,
             }
@@ -1310,6 +1317,7 @@ fn classify_name_ref(
                         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),
                             _ => {}
                         }
                     }
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 f2e9de9382c..4dd171142f9 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -1853,8 +1853,8 @@ fn f() { A { bar: b$0 }; }
             expect![[r#"
                 fn bar() [type+name]
                 fn baz() [type]
-                ex baz() [type]
                 ex bar() [type]
+                ex baz() [type]
                 st A []
                 fn f() []
             "#]],
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
index 532d4928eff..dfef8fa472d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
@@ -124,6 +124,7 @@ fn after_unsafe_token() {
         r#"unsafe $0"#,
         expect![[r#"
             kw async
+            kw extern
             kw fn
             kw impl
             kw trait
@@ -495,3 +496,57 @@ type O = $0;
 ",
     )
 }
+
+#[test]
+fn inside_extern_blocks() {
+    // Should suggest `fn`, `static`, `unsafe`
+    check(
+        r#"extern { $0 }"#,
+        expect![[r#"
+            ma makro!(…)  macro_rules! makro
+            md module
+            kw crate::
+            kw fn
+            kw pub
+            kw pub(crate)
+            kw pub(super)
+            kw self::
+            kw static
+            kw unsafe
+        "#]],
+    );
+
+    // Should suggest `fn`, `static`, `safe`, `unsafe`
+    check(
+        r#"unsafe extern { $0 }"#,
+        expect![[r#"
+            ma makro!(…)  macro_rules! makro
+            md module
+            kw crate::
+            kw fn
+            kw pub
+            kw pub(crate)
+            kw pub(super)
+            kw safe
+            kw self::
+            kw static
+            kw unsafe
+        "#]],
+    );
+
+    check(
+        r#"unsafe extern { pub safe $0 }"#,
+        expect![[r#"
+            kw fn
+            kw static
+        "#]],
+    );
+
+    check(
+        r#"unsafe extern { pub unsafe $0 }"#,
+        expect![[r#"
+            kw fn
+            kw static
+        "#]],
+    )
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs
index bd3e7c72bcd..a5eb0369b14 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs
@@ -923,3 +923,21 @@ fn foo() {
         "#]],
     );
 }
+
+#[test]
+fn private_item_in_module_in_function_body() {
+    check_empty(
+        r#"
+fn main() {
+    mod foo {
+        struct Private;
+        pub struct Public;
+    }
+    foo::$0
+}
+"#,
+        expect![[r#"
+            st Public Public
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
index 5b43f4b2af3..44be53b87ca 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
@@ -595,4 +595,39 @@ unsafe fn foo(p: *mut i32) {
             "#,
         )
     }
+
+    #[test]
+    fn no_unsafe_diagnostic_with_safe_kw() {
+        check_diagnostics(
+            r#"
+unsafe extern {
+    pub safe fn f();
+
+    pub unsafe fn g();
+
+    pub fn h();
+
+    pub safe static S1: i32;
+
+    pub unsafe static S2: i32;
+
+    pub static S3: i32;
+}
+
+fn main() {
+    f();
+    g();
+  //^^^💡 error: this operation is unsafe and requires an unsafe function or block
+    h();
+  //^^^💡 error: this operation is unsafe and requires an unsafe function or block
+
+    let _ = S1;
+    let _ = S2;
+          //^^💡 error: this operation is unsafe and requires an unsafe function or block
+    let _ = S3;
+          //^^💡 error: this operation is unsafe and requires an unsafe function or block
+}
+"#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
index 8e0166a4a76..121a463c9f1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
@@ -288,6 +288,20 @@ fn main() {
                     },
                     Annotation {
                         range: 53..57,
+                        kind: HasReferences {
+                            pos: FilePositionWrapper {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                offset: 53,
+                            },
+                            data: Some(
+                                [],
+                            ),
+                        },
+                    },
+                    Annotation {
+                        range: 53..57,
                         kind: Runnable(
                             Runnable {
                                 use_name_in_title: false,
@@ -305,20 +319,6 @@ fn main() {
                             },
                         ),
                     },
-                    Annotation {
-                        range: 53..57,
-                        kind: HasReferences {
-                            pos: FilePositionWrapper {
-                                file_id: FileId(
-                                    0,
-                                ),
-                                offset: 53,
-                            },
-                            data: Some(
-                                [],
-                            ),
-                        },
-                    },
                 ]
             "#]],
         );
@@ -338,6 +338,20 @@ fn main() {
                 [
                     Annotation {
                         range: 7..11,
+                        kind: HasImpls {
+                            pos: FilePositionWrapper {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                offset: 7,
+                            },
+                            data: Some(
+                                [],
+                            ),
+                        },
+                    },
+                    Annotation {
+                        range: 7..11,
                         kind: HasReferences {
                             pos: FilePositionWrapper {
                                 file_id: FileId(
@@ -358,13 +372,13 @@ fn main() {
                         },
                     },
                     Annotation {
-                        range: 7..11,
-                        kind: HasImpls {
+                        range: 17..21,
+                        kind: HasReferences {
                             pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
-                                offset: 7,
+                                offset: 17,
                             },
                             data: Some(
                                 [],
@@ -390,20 +404,6 @@ fn main() {
                             },
                         ),
                     },
-                    Annotation {
-                        range: 17..21,
-                        kind: HasReferences {
-                            pos: FilePositionWrapper {
-                                file_id: FileId(
-                                    0,
-                                ),
-                                offset: 17,
-                            },
-                            data: Some(
-                                [],
-                            ),
-                        },
-                    },
                 ]
             "#]],
         );
@@ -427,7 +427,7 @@ fn main() {
                 [
                     Annotation {
                         range: 7..11,
-                        kind: HasReferences {
+                        kind: HasImpls {
                             pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
@@ -436,17 +436,14 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 57..61,
-                                    },
-                                    FileRangeWrapper {
+                                    NavigationTarget {
                                         file_id: FileId(
                                             0,
                                         ),
-                                        range: 93..97,
+                                        full_range: 36..64,
+                                        focus_range: 57..61,
+                                        name: "impl",
+                                        kind: Impl,
                                     },
                                 ],
                             ),
@@ -454,7 +451,7 @@ fn main() {
                     },
                     Annotation {
                         range: 7..11,
-                        kind: HasImpls {
+                        kind: HasReferences {
                             pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
@@ -463,14 +460,17 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    NavigationTarget {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
-                                        full_range: 36..64,
-                                        focus_range: 57..61,
-                                        name: "impl",
-                                        kind: Impl,
+                                        range: 57..61,
+                                    },
+                                    FileRangeWrapper {
+                                        file_id: FileId(
+                                            0,
+                                        ),
+                                        range: 93..97,
                                     },
                                 ],
                             ),
@@ -523,20 +523,6 @@ fn main() {
                     },
                     Annotation {
                         range: 69..73,
-                        kind: HasReferences {
-                            pos: FilePositionWrapper {
-                                file_id: FileId(
-                                    0,
-                                ),
-                                offset: 69,
-                            },
-                            data: Some(
-                                [],
-                            ),
-                        },
-                    },
-                    Annotation {
-                        range: 69..73,
                         kind: Runnable(
                             Runnable {
                                 use_name_in_title: false,
@@ -554,6 +540,20 @@ fn main() {
                             },
                         ),
                     },
+                    Annotation {
+                        range: 69..73,
+                        kind: HasReferences {
+                            pos: FilePositionWrapper {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                offset: 69,
+                            },
+                            data: Some(
+                                [],
+                            ),
+                        },
+                    },
                 ]
             "#]],
         );
@@ -569,6 +569,20 @@ fn main() {}
                 [
                     Annotation {
                         range: 3..7,
+                        kind: HasReferences {
+                            pos: FilePositionWrapper {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                offset: 3,
+                            },
+                            data: Some(
+                                [],
+                            ),
+                        },
+                    },
+                    Annotation {
+                        range: 3..7,
                         kind: Runnable(
                             Runnable {
                                 use_name_in_title: false,
@@ -586,20 +600,6 @@ fn main() {}
                             },
                         ),
                     },
-                    Annotation {
-                        range: 3..7,
-                        kind: HasReferences {
-                            pos: FilePositionWrapper {
-                                file_id: FileId(
-                                    0,
-                                ),
-                                offset: 3,
-                            },
-                            data: Some(
-                                [],
-                            ),
-                        },
-                    },
                 ]
             "#]],
         );
@@ -623,7 +623,7 @@ fn main() {
                 [
                     Annotation {
                         range: 7..11,
-                        kind: HasReferences {
+                        kind: HasImpls {
                             pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
@@ -632,17 +632,14 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 19..23,
-                                    },
-                                    FileRangeWrapper {
+                                    NavigationTarget {
                                         file_id: FileId(
                                             0,
                                         ),
-                                        range: 74..78,
+                                        full_range: 14..56,
+                                        focus_range: 19..23,
+                                        name: "impl",
+                                        kind: Impl,
                                     },
                                 ],
                             ),
@@ -650,7 +647,7 @@ fn main() {
                     },
                     Annotation {
                         range: 7..11,
-                        kind: HasImpls {
+                        kind: HasReferences {
                             pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
@@ -659,14 +656,17 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    NavigationTarget {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
-                                        full_range: 14..56,
-                                        focus_range: 19..23,
-                                        name: "impl",
-                                        kind: Impl,
+                                        range: 19..23,
+                                    },
+                                    FileRangeWrapper {
+                                        file_id: FileId(
+                                            0,
+                                        ),
+                                        range: 74..78,
                                     },
                                 ],
                             ),
@@ -695,20 +695,6 @@ fn main() {
                     },
                     Annotation {
                         range: 61..65,
-                        kind: HasReferences {
-                            pos: FilePositionWrapper {
-                                file_id: FileId(
-                                    0,
-                                ),
-                                offset: 61,
-                            },
-                            data: Some(
-                                [],
-                            ),
-                        },
-                    },
-                    Annotation {
-                        range: 61..65,
                         kind: Runnable(
                             Runnable {
                                 use_name_in_title: false,
@@ -726,6 +712,20 @@ fn main() {
                             },
                         ),
                     },
+                    Annotation {
+                        range: 61..65,
+                        kind: HasReferences {
+                            pos: FilePositionWrapper {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                offset: 61,
+                            },
+                            data: Some(
+                                [],
+                            ),
+                        },
+                    },
                 ]
             "#]],
         );
@@ -746,20 +746,6 @@ mod tests {
                 [
                     Annotation {
                         range: 3..7,
-                        kind: HasReferences {
-                            pos: FilePositionWrapper {
-                                file_id: FileId(
-                                    0,
-                                ),
-                                offset: 3,
-                            },
-                            data: Some(
-                                [],
-                            ),
-                        },
-                    },
-                    Annotation {
-                        range: 3..7,
                         kind: Runnable(
                             Runnable {
                                 use_name_in_title: false,
@@ -778,6 +764,20 @@ mod tests {
                         ),
                     },
                     Annotation {
+                        range: 3..7,
+                        kind: HasReferences {
+                            pos: FilePositionWrapper {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                offset: 3,
+                            },
+                            data: Some(
+                                [],
+                            ),
+                        },
+                    },
+                    Annotation {
                         range: 18..23,
                         kind: Runnable(
                             Runnable {
@@ -876,7 +876,7 @@ struct Foo;
                 [
                     Annotation {
                         range: 0..71,
-                        kind: HasReferences {
+                        kind: HasImpls {
                             pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
@@ -890,7 +890,7 @@ struct Foo;
                     },
                     Annotation {
                         range: 0..71,
-                        kind: HasImpls {
+                        kind: HasReferences {
                             pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
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 c61b2ba84f2..4cbcb6ed050 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -505,6 +505,44 @@ fn foo() {
     }
 
     #[test]
+    fn goto_def_in_included_file_inside_mod() {
+        check(
+            r#"
+//- minicore:include
+//- /main.rs
+mod a {
+    include!("b.rs");
+}
+//- /b.rs
+fn func_in_include() {
+ //^^^^^^^^^^^^^^^
+}
+fn foo() {
+    func_in_include$0();
+}
+"#,
+        );
+
+        check(
+            r#"
+//- minicore:include
+//- /main.rs
+mod a {
+    include!("a.rs");
+}
+//- /a.rs
+fn func_in_include() {
+ //^^^^^^^^^^^^^^^
+}
+
+fn foo() {
+    func_in_include$0();
+}
+"#,
+        );
+    }
+
+    #[test]
     fn goto_def_if_items_same_name() {
         check(
             r#"
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs
index 64d717f88dd..e7cb8a253f4 100644
--- a/src/tools/rust-analyzer/crates/ide/src/references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -2750,4 +2750,25 @@ impl Foo {
             "#]],
         );
     }
+
+    #[test]
+    fn goto_ref_on_included_file() {
+        check(
+            r#"
+//- minicore:include
+//- /lib.rs
+include!("foo.rs");
+fn howdy() {
+    let _ = FOO;
+}
+//- /foo.rs
+const FOO$0: i32 = 0;
+"#,
+            expect![[r#"
+                FOO Const FileId(1) 0..19 6..9
+
+                FileId(0) 45..48
+            "#]],
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
index 38dc522789d..3bbbd36c1b1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -1350,18 +1350,18 @@ mod tests {
                         file_id: FileId(
                             0,
                         ),
-                        full_range: 121..185,
-                        focus_range: 136..145,
-                        name: "foo2_test",
+                        full_range: 52..115,
+                        focus_range: 67..75,
+                        name: "foo_test",
                         kind: Function,
                     },
                     NavigationTarget {
                         file_id: FileId(
                             0,
                         ),
-                        full_range: 52..115,
-                        focus_range: 67..75,
-                        name: "foo_test",
+                        full_range: 121..185,
+                        focus_range: 136..145,
+                        name: "foo2_test",
                         kind: Function,
                     },
                 ]
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
index 5d51b149789..a4449b5d8d8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
@@ -46,14 +46,14 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 </style>
 <pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
-    <span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="8384512769119783714" style="color: hsl(59,93%,58%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>
-    <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="17360984456076382725" style="color: hsl(95,79%,86%);">x</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="8384512769119783714" style="color: hsl(59,93%,58%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
-    <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="17186414787327620935" style="color: hsl(196,64%,89%);">y</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="8384512769119783714" style="color: hsl(59,93%,58%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="16711699953829236520" style="color: hsl(345,54%,46%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="10753541418856619067" style="color: hsl(51,52%,47%);">x</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="16711699953829236520" style="color: hsl(345,54%,46%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="9865812862466303869" style="color: hsl(329,86%,55%);">y</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="16711699953829236520" style="color: hsl(345,54%,46%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
-    <span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="4786021388930833562" style="color: hsl(137,61%,87%);">x</span> <span class="operator">=</span> <span class="string_literal">"other color please!"</span><span class="semicolon">;</span>
-    <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="18017815841345165192" style="color: hsl(39,76%,89%);">y</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="4786021388930833562" style="color: hsl(137,61%,87%);">x</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="4890670724659097491" style="color: hsl(330,46%,45%);">x</span> <span class="operator">=</span> <span class="string_literal">"other color please!"</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="4002942168268782293" style="color: hsl(114,87%,67%);">y</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="4890670724659097491" style="color: hsl(330,46%,45%);">x</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
 <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
-    <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable reference" data-binding-hash="8384512769119783714" style="color: hsl(59,93%,58%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable reference" data-binding-hash="16711699953829236520" style="color: hsl(345,54%,46%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>
 <span class="brace">}</span></code></pre>
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs
index 9e4ef140740..270bc05a4ee 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs
@@ -3,6 +3,7 @@
 use intern::Symbol;
 use rustc_hash::FxHashMap;
 use span::{Edition, Span};
+use stdx::itertools::Itertools;
 use syntax::{
     ast::{self, HasName},
     AstNode,
@@ -27,9 +28,10 @@ fn benchmark_parse_macro_rules() {
     let hash: usize = {
         let _pt = bench("mbe parse macro rules");
         rules
-            .values()
-            .map(|it| {
-                DeclarativeMacro::parse_macro_rules(it, |_| span::Edition::CURRENT).rules.len()
+            .into_iter()
+            .sorted_by_key(|(id, _)| id.clone())
+            .map(|(_, it)| {
+                DeclarativeMacro::parse_macro_rules(&it, |_| span::Edition::CURRENT).rules.len()
             })
             .sum()
     };
@@ -55,12 +57,13 @@ fn benchmark_expand_macro_rules() {
             })
             .sum()
     };
-    assert_eq!(hash, 69413);
+    assert_eq!(hash, 65720);
 }
 
 fn macro_rules_fixtures() -> FxHashMap<String, DeclarativeMacro> {
     macro_rules_fixtures_tt()
         .into_iter()
+        .sorted_by_key(|(id, _)| id.clone())
         .map(|(id, tt)| (id, DeclarativeMacro::parse_macro_rules(&tt, |_| span::Edition::CURRENT)))
         .collect()
 }
@@ -93,7 +96,7 @@ fn invocation_fixtures(
     let mut seed = 123456789;
     let mut res = Vec::new();
 
-    for (name, it) in rules {
+    for (name, it) in rules.iter().sorted_by_key(|&(id, _)| id) {
         for rule in it.rules.iter() {
             // Generate twice
             for _ in 0..2 {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
index 4e2a50d7a1f..c4dce0daa5b 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
@@ -135,6 +135,11 @@ pub(super) fn opt_item(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> {
         has_mods = true;
     }
 
+    if p.at_contextual_kw(T![safe]) {
+        p.eat_contextual_kw(T![safe]);
+        has_mods = true;
+    }
+
     if p.at(T![extern]) {
         has_extern = true;
         has_mods = true;
@@ -189,6 +194,7 @@ pub(super) fn opt_item(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> {
         T![fn] => fn_(p, m),
 
         T![const] if p.nth(1) != T!['{'] => consts::konst(p, m),
+        T![static] if matches!(p.nth(1), IDENT | T![_] | T![mut]) => consts::static_(p, m),
 
         T![trait] => traits::trait_(p, m),
         T![impl] => traits::impl_(p, m),
diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
index 288a07ef44d..8da338c0a2c 100644
--- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
@@ -136,6 +136,7 @@ pub enum SyntaxKind {
     PURE_KW,
     RAW_KW,
     READONLY_KW,
+    SAFE_KW,
     SYM_KW,
     TRY_KW,
     UNION_KW,
@@ -416,6 +417,7 @@ impl SyntaxKind {
             PURE_KW => true,
             RAW_KW => true,
             READONLY_KW => true,
+            SAFE_KW => true,
             SYM_KW => true,
             UNION_KW => true,
             YEET_KW => true,
@@ -503,6 +505,7 @@ impl SyntaxKind {
             PURE_KW => true,
             RAW_KW => true,
             READONLY_KW => true,
+            SAFE_KW => true,
             SYM_KW => true,
             UNION_KW => true,
             YEET_KW => true,
@@ -664,6 +667,7 @@ impl SyntaxKind {
             "pure" => PURE_KW,
             "raw" => RAW_KW,
             "readonly" => READONLY_KW,
+            "safe" => SAFE_KW,
             "sym" => SYM_KW,
             "union" => UNION_KW,
             "yeet" => YEET_KW,
@@ -707,4 +711,4 @@ impl SyntaxKind {
     }
 }
 #[macro_export]
-macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
+macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [safe] => { $ crate :: SyntaxKind :: SAFE_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rast
new file mode 100644
index 00000000000..b3d9e558067
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rast
@@ -0,0 +1,208 @@
+SOURCE_FILE
+  EXTERN_BLOCK
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    ABI
+      EXTERN_KW "extern"
+    WHITESPACE " "
+    EXTERN_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        COMMENT "// sqrt (from libm) may be called with any `f64`"
+        WHITESPACE "\n    "
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        SAFE_KW "safe"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "sqrt"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "x"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "f64"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "f64"
+        SEMICOLON ";"
+      WHITESPACE "\n\n    "
+      FN
+        COMMENT "// strlen (from libc) requires a valid pointer,"
+        WHITESPACE "\n    "
+        COMMENT "// so we mark it as being an unsafe fn"
+        WHITESPACE "\n    "
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        UNSAFE_KW "unsafe"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "strlen"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "p"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              CONST_KW "const"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "c_char"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "usize"
+        SEMICOLON ";"
+      WHITESPACE "\n\n    "
+      FN
+        COMMENT "// this function doesn't say safe or unsafe, so it defaults to unsafe"
+        WHITESPACE "\n    "
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "free"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "p"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "core"
+                    COLON2 "::"
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "ffi"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "c_void"
+          R_PAREN ")"
+        SEMICOLON ";"
+      WHITESPACE "\n\n    "
+      STATIC
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        SAFE_KW "safe"
+        WHITESPACE " "
+        STATIC_KW "static"
+        WHITESPACE " "
+        MUT_KW "mut"
+        WHITESPACE " "
+        NAME
+          IDENT "COUNTER"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "i32"
+        SEMICOLON ";"
+      WHITESPACE "\n\n    "
+      STATIC
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        UNSAFE_KW "unsafe"
+        WHITESPACE " "
+        STATIC_KW "static"
+        WHITESPACE " "
+        NAME
+          IDENT "IMPORTANT_BYTES"
+        COLON ":"
+        WHITESPACE " "
+        ARRAY_TYPE
+          L_BRACK "["
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "u8"
+          SEMICOLON ";"
+          WHITESPACE " "
+          CONST_ARG
+            LITERAL
+              INT_NUMBER "256"
+          R_BRACK "]"
+        SEMICOLON ";"
+      WHITESPACE "\n\n    "
+      STATIC
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        SAFE_KW "safe"
+        WHITESPACE " "
+        STATIC_KW "static"
+        WHITESPACE " "
+        NAME
+          IDENT "LINES"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "SyncUnsafeCell"
+              GENERIC_ARG_LIST
+                L_ANGLE "<"
+                TYPE_ARG
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "i32"
+                R_ANGLE ">"
+        SEMICOLON ";"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rs
new file mode 100644
index 00000000000..267a128649c
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rs
@@ -0,0 +1,17 @@
+unsafe extern {
+    // sqrt (from libm) may be called with any `f64`
+    pub safe fn sqrt(x: f64) -> f64;
+
+    // strlen (from libc) requires a valid pointer,
+    // so we mark it as being an unsafe fn
+    pub unsafe fn strlen(p: *const c_char) -> usize;
+
+    // this function doesn't say safe or unsafe, so it defaults to unsafe
+    pub fn free(p: *mut core::ffi::c_void);
+
+    pub safe static mut COUNTER: i32;
+
+    pub unsafe static IMPORTANT_BYTES: [u8; 256];
+
+    pub safe static LINES: SyncUnsafeCell<i32>;
+}
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
index 5099697a696..ef115494a88 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -222,8 +222,6 @@ fn rust_project_is_proc_macro_has_proc_macro_dep() {
 }
 
 #[test]
-// FIXME Remove the ignore
-#[ignore = "requires nightly until the sysroot ships a cargo workspace for library on stable"]
 fn smoke_test_real_sysroot_cargo() {
     let file_map = &mut FxHashMap::<AbsPathBuf, FileId>::default();
     let meta: Metadata = get_test_json_file("hello-world-metadata.json");
@@ -235,7 +233,6 @@ fn smoke_test_real_sysroot_cargo() {
         &Default::default(),
     );
     assert!(matches!(sysroot.mode(), SysrootMode::Workspace(_)));
-
     let project_workspace = ProjectWorkspace {
         kind: ProjectWorkspaceKind::Cargo {
             cargo: cargo_workspace,
diff --git a/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml b/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml
index b81e780337f..f8a3156fe40 100644
--- a/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml
@@ -17,7 +17,7 @@ indexmap = "2.1.0"
 lock_api = "0.4"
 tracing = "0.1"
 parking_lot = "0.12.1"
-rustc-hash = "1.0"
+rustc-hash = "2.0.0"
 smallvec = "1.0.0"
 oorandom = "11"
 triomphe = "0.1.11"
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 c2164614274..51c81a0d1a6 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
@@ -6,6 +6,7 @@ use std::{
     time::{SystemTime, UNIX_EPOCH},
 };
 
+use cfg::{CfgAtom, CfgDiff};
 use hir::{
     db::{DefDatabase, ExpandDatabase, HirDatabase},
     Adt, AssocItem, Crate, DefWithBody, HasSource, HirDisplay, HirFileIdExt, ImportPathConfig,
@@ -31,7 +32,7 @@ use itertools::Itertools;
 use load_cargo::{load_workspace, LoadCargoConfig, ProcMacroServerChoice};
 use oorandom::Rand32;
 use profile::{Bytes, StopWatch};
-use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, RustLibSource};
+use project_model::{CargoConfig, CfgOverrides, ProjectManifest, ProjectWorkspace, RustLibSource};
 use rayon::prelude::*;
 use rustc_hash::{FxHashMap, FxHashSet};
 use syntax::{AstNode, SyntaxNode};
@@ -65,7 +66,11 @@ impl flags::AnalysisStats {
                 false => Some(RustLibSource::Discover),
             },
             all_targets: true,
-            set_test: true,
+            set_test: !self.no_test,
+            cfg_overrides: CfgOverrides {
+                global: CfgDiff::new(vec![CfgAtom::Flag(hir::sym::miri.clone())], vec![]).unwrap(),
+                selective: Default::default(),
+            },
             ..Default::default()
         };
         let no_progress = &|_| ();
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
index 60d621b214a..ff24602144a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
@@ -71,6 +71,8 @@ xflags::xflags! {
             optional --with-deps
             /// Don't load sysroot crates (`std`, `core` & friends).
             optional --no-sysroot
+            /// Don't set #[cfg(test)].
+            optional --no-test
 
             /// Don't run build scripts or load `OUT_DIR` values by running `cargo check` before analysis.
             optional --disable-build-scripts
@@ -233,6 +235,7 @@ pub struct AnalysisStats {
     pub only: Option<String>,
     pub with_deps: bool,
     pub no_sysroot: bool,
+    pub no_test: bool,
     pub disable_build_scripts: bool,
     pub disable_proc_macros: bool,
     pub proc_macro_srv: Option<PathBuf>,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs
index 1f4544887f0..47e9961cf13 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs
@@ -35,10 +35,18 @@ pub(crate) fn offset(
                 .ok_or_else(|| format_err!("Invalid wide col offset"))?
         }
     };
-    let text_size = line_index.index.offset(line_col).ok_or_else(|| {
+    let line_range = line_index.index.line(line_col.line).ok_or_else(|| {
         format_err!("Invalid offset {line_col:?} (line index length: {:?})", line_index.index.len())
     })?;
-    Ok(text_size)
+    let col = TextSize::from(line_col.col);
+    let clamped_len = col.min(line_range.len());
+    if clamped_len < col {
+        tracing::error!(
+            "Position {line_col:?} column exceeds line length {}, clamping it",
+            u32::from(line_range.len()),
+        );
+    }
+    Ok(line_range.start() + clamped_len)
 }
 
 pub(crate) fn text_range(
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index 52ad439e4de..90441c27f62 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -190,7 +190,7 @@ UseTreeList =
 
 Fn =
  Attr* Visibility?
- 'default'? 'const'? 'async'? 'gen'? 'unsafe'? Abi?
+ 'default'? 'const'? 'async'? 'gen'? 'unsafe'? 'safe'? Abi?
  'fn' Name GenericParamList? ParamList RetType? WhereClause?
  (body:BlockExpr | ';')
 
@@ -284,6 +284,7 @@ Const =
 
 Static =
   Attr* Visibility?
+  'unsafe'? 'safe'?
   'static' 'mut'? Name ':' Type
   ('=' body:Expr)? ';'
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
index c81a19f3bda..4f8bff489cf 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -668,6 +668,8 @@ impl Fn {
     #[inline]
     pub fn gen_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![gen]) }
     #[inline]
+    pub fn safe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![safe]) }
+    #[inline]
     pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
 }
 
@@ -1761,7 +1763,11 @@ impl Static {
     #[inline]
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
     #[inline]
+    pub fn safe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![safe]) }
+    #[inline]
     pub fn static_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![static]) }
+    #[inline]
+    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ptr.rs b/src/tools/rust-analyzer/crates/syntax/src/ptr.rs
index ed4894f9b9c..11b79e4e0ed 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ptr.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ptr.rs
@@ -27,7 +27,7 @@ pub struct AstPtr<N: AstNode> {
     _ty: PhantomData<fn() -> N>,
 }
 
-impl<N: AstNode + std::fmt::Debug> std::fmt::Debug for AstPtr<N> {
+impl<N: AstNode> std::fmt::Debug for AstPtr<N> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_tuple("AstPtr").field(&self.raw).finish()
     }
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index babeb4272be..463718835b9 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -95,8 +95,8 @@ avoid checking unnecessary things.
 Default:
 ----
 {
-  "debug_assertions": null,
-  "miri": null
+  "miri": null,
+  "debug_assertions": null
 }
 ----
 List of cfg options to enable with the given values.
@@ -321,18 +321,10 @@ Enables completions of private items and fields that are defined in the current
 Default:
 ----
 {
-  "Arc::new": {
-    "postfix": "arc",
-    "body": "Arc::new(${receiver})",
-    "requires": "std::sync::Arc",
-    "description": "Put the expression into an `Arc`",
-    "scope": "expr"
-  },
-  "Rc::new": {
-    "postfix": "rc",
-    "body": "Rc::new(${receiver})",
-    "requires": "std::rc::Rc",
-    "description": "Put the expression into an `Rc`",
+  "Ok": {
+    "postfix": "ok",
+    "body": "Ok(${receiver})",
+    "description": "Wrap the expression in a `Result::Ok`",
     "scope": "expr"
   },
   "Box::pin": {
@@ -342,10 +334,11 @@ Default:
     "description": "Put the expression into a pinned `Box`",
     "scope": "expr"
   },
-  "Err": {
-    "postfix": "err",
-    "body": "Err(${receiver})",
-    "description": "Wrap the expression in a `Result::Err`",
+  "Arc::new": {
+    "postfix": "arc",
+    "body": "Arc::new(${receiver})",
+    "requires": "std::sync::Arc",
+    "description": "Put the expression into an `Arc`",
     "scope": "expr"
   },
   "Some": {
@@ -354,10 +347,17 @@ Default:
     "description": "Wrap the expression in an `Option::Some`",
     "scope": "expr"
   },
-  "Ok": {
-    "postfix": "ok",
-    "body": "Ok(${receiver})",
-    "description": "Wrap the expression in a `Result::Ok`",
+  "Err": {
+    "postfix": "err",
+    "body": "Err(${receiver})",
+    "description": "Wrap the expression in a `Result::Err`",
+    "scope": "expr"
+  },
+  "Rc::new": {
+    "postfix": "rc",
+    "body": "Rc::new(${receiver})",
+    "requires": "std::rc::Rc",
+    "description": "Put the expression into an `Rc`",
     "scope": "expr"
   }
 }
diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json
index 7de75763177..10b633511d3 100644
--- a/src/tools/rust-analyzer/editors/code/package-lock.json
+++ b/src/tools/rust-analyzer/editors/code/package-lock.json
@@ -22,14 +22,14 @@
                 "@typescript-eslint/eslint-plugin": "^6.0.0",
                 "@typescript-eslint/parser": "^6.0.0",
                 "@vscode/test-electron": "^2.3.8",
-                "@vscode/vsce": "^2.19.0",
+                "@vscode/vsce": "^3.0.0",
                 "esbuild": "^0.18.12",
                 "eslint": "^8.44.0",
                 "eslint-config-prettier": "^8.8.0",
                 "ovsx": "^0.8.2",
                 "prettier": "^3.0.0",
                 "tslib": "^2.6.0",
-                "typescript": "^5.1.6"
+                "typescript": "^5.6.0"
             },
             "engines": {
                 "vscode": "^1.78.0"
@@ -44,6 +44,218 @@
                 "node": ">=0.10.0"
             }
         },
+        "node_modules/@azure/abort-controller": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+            "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "tslib": "^2.6.2"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/@azure/core-auth": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz",
+            "integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@azure/abort-controller": "^2.0.0",
+                "@azure/core-util": "^1.11.0",
+                "tslib": "^2.6.2"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/@azure/core-client": {
+            "version": "1.9.2",
+            "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz",
+            "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@azure/abort-controller": "^2.0.0",
+                "@azure/core-auth": "^1.4.0",
+                "@azure/core-rest-pipeline": "^1.9.1",
+                "@azure/core-tracing": "^1.0.0",
+                "@azure/core-util": "^1.6.1",
+                "@azure/logger": "^1.0.0",
+                "tslib": "^2.6.2"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/@azure/core-rest-pipeline": {
+            "version": "1.17.0",
+            "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.17.0.tgz",
+            "integrity": "sha512-62Vv8nC+uPId3j86XJ0WI+sBf0jlqTqPUFCBNrGtlaUeQUIXWV/D8GE5A1d+Qx8H7OQojn2WguC8kChD6v0shA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@azure/abort-controller": "^2.0.0",
+                "@azure/core-auth": "^1.8.0",
+                "@azure/core-tracing": "^1.0.1",
+                "@azure/core-util": "^1.9.0",
+                "@azure/logger": "^1.0.0",
+                "http-proxy-agent": "^7.0.0",
+                "https-proxy-agent": "^7.0.0",
+                "tslib": "^2.6.2"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/@azure/core-rest-pipeline/node_modules/agent-base": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+            "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^4.3.4"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/@azure/core-rest-pipeline/node_modules/http-proxy-agent": {
+            "version": "7.0.2",
+            "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+            "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "^7.1.0",
+                "debug": "^4.3.4"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/@azure/core-rest-pipeline/node_modules/https-proxy-agent": {
+            "version": "7.0.5",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
+            "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "^7.0.2",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/@azure/core-tracing": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz",
+            "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "tslib": "^2.6.2"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/@azure/core-util": {
+            "version": "1.11.0",
+            "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz",
+            "integrity": "sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@azure/abort-controller": "^2.0.0",
+                "tslib": "^2.6.2"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/@azure/identity": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.5.0.tgz",
+            "integrity": "sha512-EknvVmtBuSIic47xkOqyNabAme0RYTw52BTMz8eBgU1ysTyMrD1uOoM+JdS0J/4Yfp98IBT3osqq3BfwSaNaGQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@azure/abort-controller": "^2.0.0",
+                "@azure/core-auth": "^1.9.0",
+                "@azure/core-client": "^1.9.2",
+                "@azure/core-rest-pipeline": "^1.17.0",
+                "@azure/core-tracing": "^1.0.0",
+                "@azure/core-util": "^1.11.0",
+                "@azure/logger": "^1.0.0",
+                "@azure/msal-browser": "^3.26.1",
+                "@azure/msal-node": "^2.15.0",
+                "events": "^3.0.0",
+                "jws": "^4.0.0",
+                "open": "^8.0.0",
+                "stoppable": "^1.1.0",
+                "tslib": "^2.2.0"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/@azure/logger": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz",
+            "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "tslib": "^2.6.2"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/@azure/msal-browser": {
+            "version": "3.26.1",
+            "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.26.1.tgz",
+            "integrity": "sha512-y78sr9g61aCAH9fcLO1um+oHFXc1/5Ap88RIsUSuzkm0BHzFnN+PXGaQeuM1h5Qf5dTnWNOd6JqkskkMPAhh7Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@azure/msal-common": "14.15.0"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/@azure/msal-common": {
+            "version": "14.15.0",
+            "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.15.0.tgz",
+            "integrity": "sha512-ImAQHxmpMneJ/4S8BRFhjt1MZ3bppmpRPYYNyzeQPeFN288YKbb8TmmISQEbtfkQ1BPASvYZU5doIZOPBAqENQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/@azure/msal-node": {
+            "version": "2.15.0",
+            "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.15.0.tgz",
+            "integrity": "sha512-gVPW8YLz92ZeCibQH2QUw96odJoiM3k/ZPH3f2HxptozmH6+OnyyvKXo/Egg39HAM230akarQKHf0W74UHlh0Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@azure/msal-common": "14.15.0",
+                "jsonwebtoken": "^9.0.0",
+                "uuid": "^8.3.0"
+            },
+            "engines": {
+                "node": ">=16"
+            }
+        },
         "node_modules/@esbuild/android-arm": {
             "version": "0.18.12",
             "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.12.tgz",
@@ -496,6 +708,109 @@
             "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
             "dev": true
         },
+        "node_modules/@isaacs/cliui": {
+            "version": "8.0.2",
+            "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+            "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "string-width": "^5.1.2",
+                "string-width-cjs": "npm:string-width@^4.2.0",
+                "strip-ansi": "^7.0.1",
+                "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+                "wrap-ansi": "^8.1.0",
+                "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+            "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+            }
+        },
+        "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+            "version": "6.2.1",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+            "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+            }
+        },
+        "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+            "version": "9.2.2",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+            "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@isaacs/cliui/node_modules/string-width": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+            "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "eastasianwidth": "^0.2.0",
+                "emoji-regex": "^9.2.2",
+                "strip-ansi": "^7.0.1"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+            "version": "7.1.0",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+            "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-regex": "^6.0.1"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+            }
+        },
+        "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+            "version": "8.1.0",
+            "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+            "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^6.1.0",
+                "string-width": "^5.0.1",
+                "strip-ansi": "^7.0.1"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+            }
+        },
         "node_modules/@nodelib/fs.scandir": {
             "version": "2.1.5",
             "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -778,26 +1093,31 @@
             }
         },
         "node_modules/@vscode/vsce": {
-            "version": "2.19.0",
-            "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.19.0.tgz",
-            "integrity": "sha512-dAlILxC5ggOutcvJY24jxz913wimGiUrHaPkk16Gm9/PGFbz1YezWtrXsTKUtJws4fIlpX2UIlVlVESWq8lkfQ==",
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.1.1.tgz",
+            "integrity": "sha512-N62Ca9ElRPLUUzf7l9CeEBlLrYzFPRQq7huKk4pVW+LjIOSXfFIPudixn5QvZcz+yXDOh15IopI3K2o3y9666Q==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "azure-devops-node-api": "^11.0.1",
+                "@azure/identity": "^4.1.0",
+                "@vscode/vsce-sign": "^2.0.0",
+                "azure-devops-node-api": "^12.5.0",
                 "chalk": "^2.4.2",
                 "cheerio": "^1.0.0-rc.9",
-                "commander": "^6.1.0",
-                "glob": "^7.0.6",
+                "cockatiel": "^3.1.2",
+                "commander": "^6.2.1",
+                "form-data": "^4.0.0",
+                "glob": "^11.0.0",
                 "hosted-git-info": "^4.0.2",
                 "jsonc-parser": "^3.2.0",
                 "leven": "^3.1.0",
-                "markdown-it": "^12.3.2",
+                "markdown-it": "^14.1.0",
                 "mime": "^1.3.4",
                 "minimatch": "^3.0.3",
                 "parse-semver": "^1.1.1",
                 "read": "^1.0.7",
-                "semver": "^5.1.0",
-                "tmp": "^0.2.1",
+                "semver": "^7.5.2",
+                "tmp": "^0.2.3",
                 "typed-rest-client": "^1.8.4",
                 "url-join": "^4.0.1",
                 "xml2js": "^0.5.0",
@@ -808,12 +1128,157 @@
                 "vsce": "vsce"
             },
             "engines": {
-                "node": ">= 14"
+                "node": ">= 20"
             },
             "optionalDependencies": {
                 "keytar": "^7.7.0"
             }
         },
+        "node_modules/@vscode/vsce-sign": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.4.tgz",
+            "integrity": "sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==",
+            "dev": true,
+            "hasInstallScript": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optionalDependencies": {
+                "@vscode/vsce-sign-alpine-arm64": "2.0.2",
+                "@vscode/vsce-sign-alpine-x64": "2.0.2",
+                "@vscode/vsce-sign-darwin-arm64": "2.0.2",
+                "@vscode/vsce-sign-darwin-x64": "2.0.2",
+                "@vscode/vsce-sign-linux-arm": "2.0.2",
+                "@vscode/vsce-sign-linux-arm64": "2.0.2",
+                "@vscode/vsce-sign-linux-x64": "2.0.2",
+                "@vscode/vsce-sign-win32-arm64": "2.0.2",
+                "@vscode/vsce-sign-win32-x64": "2.0.2"
+            }
+        },
+        "node_modules/@vscode/vsce-sign-alpine-arm64": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.2.tgz",
+            "integrity": "sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "alpine"
+            ]
+        },
+        "node_modules/@vscode/vsce-sign-alpine-x64": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.2.tgz",
+            "integrity": "sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "alpine"
+            ]
+        },
+        "node_modules/@vscode/vsce-sign-darwin-arm64": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.2.tgz",
+            "integrity": "sha512-rz8F4pMcxPj8fjKAJIfkUT8ycG9CjIp888VY/6pq6cuI2qEzQ0+b5p3xb74CJnBbSC0p2eRVoe+WgNCAxCLtzQ==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "darwin"
+            ]
+        },
+        "node_modules/@vscode/vsce-sign-darwin-x64": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.2.tgz",
+            "integrity": "sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "darwin"
+            ]
+        },
+        "node_modules/@vscode/vsce-sign-linux-arm": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.2.tgz",
+            "integrity": "sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==",
+            "cpu": [
+                "arm"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "linux"
+            ]
+        },
+        "node_modules/@vscode/vsce-sign-linux-arm64": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.2.tgz",
+            "integrity": "sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "linux"
+            ]
+        },
+        "node_modules/@vscode/vsce-sign-linux-x64": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.2.tgz",
+            "integrity": "sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "linux"
+            ]
+        },
+        "node_modules/@vscode/vsce-sign-win32-arm64": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.2.tgz",
+            "integrity": "sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "win32"
+            ]
+        },
+        "node_modules/@vscode/vsce-sign-win32-x64": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.2.tgz",
+            "integrity": "sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "license": "SEE LICENSE IN LICENSE.txt",
+            "optional": true,
+            "os": [
+                "win32"
+            ]
+        },
         "node_modules/@vscode/vsce/node_modules/ansi-styles": {
             "version": "3.2.1",
             "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
@@ -826,6 +1291,16 @@
                 "node": ">=4"
             }
         },
+        "node_modules/@vscode/vsce/node_modules/brace-expansion": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+            "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "balanced-match": "^1.0.0"
+            }
+        },
         "node_modules/@vscode/vsce/node_modules/chalk": {
             "version": "2.4.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -873,6 +1348,46 @@
                 "node": ">=0.8.0"
             }
         },
+        "node_modules/@vscode/vsce/node_modules/glob": {
+            "version": "11.0.0",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz",
+            "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "foreground-child": "^3.1.0",
+                "jackspeak": "^4.0.1",
+                "minimatch": "^10.0.0",
+                "minipass": "^7.1.2",
+                "package-json-from-dist": "^1.0.0",
+                "path-scurry": "^2.0.0"
+            },
+            "bin": {
+                "glob": "dist/esm/bin.mjs"
+            },
+            "engines": {
+                "node": "20 || >=22"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": {
+            "version": "10.0.1",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
+            "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "brace-expansion": "^2.0.1"
+            },
+            "engines": {
+                "node": "20 || >=22"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
         "node_modules/@vscode/vsce/node_modules/has-flag": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -882,15 +1397,6 @@
                 "node": ">=4"
             }
         },
-        "node_modules/@vscode/vsce/node_modules/semver": {
-            "version": "5.7.2",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
-            "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
-            "dev": true,
-            "bin": {
-                "semver": "bin/semver"
-            }
-        },
         "node_modules/@vscode/vsce/node_modules/supports-color": {
             "version": "5.5.0",
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -903,19 +1409,6 @@
                 "node": ">=4"
             }
         },
-        "node_modules/@vscode/vsce/node_modules/xml2js": {
-            "version": "0.5.0",
-            "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
-            "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
-            "dev": true,
-            "dependencies": {
-                "sax": ">=0.6.0",
-                "xmlbuilder": "~11.0.0"
-            },
-            "engines": {
-                "node": ">=4.0.0"
-            }
-        },
         "node_modules/acorn": {
             "version": "8.10.0",
             "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
@@ -1007,11 +1500,19 @@
                 "node": ">=8"
             }
         },
+        "node_modules/asynckit": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+            "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/azure-devops-node-api": {
-            "version": "11.2.0",
-            "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz",
-            "integrity": "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==",
+            "version": "12.5.0",
+            "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz",
+            "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "tunnel": "0.0.6",
                 "typed-rest-client": "^1.8.4"
@@ -1132,14 +1633,28 @@
                 "node": "*"
             }
         },
+        "node_modules/buffer-equal-constant-time": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+            "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+            "dev": true,
+            "license": "BSD-3-Clause"
+        },
         "node_modules/call-bind": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
-            "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+            "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "function-bind": "^1.1.1",
-                "get-intrinsic": "^1.0.2"
+                "es-define-property": "^1.0.0",
+                "es-errors": "^1.3.0",
+                "function-bind": "^1.1.2",
+                "get-intrinsic": "^1.2.4",
+                "set-function-length": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
             },
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
@@ -1234,6 +1749,16 @@
                 "node": ">=12"
             }
         },
+        "node_modules/cockatiel": {
+            "version": "3.2.1",
+            "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.2.1.tgz",
+            "integrity": "sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=16"
+            }
+        },
         "node_modules/color-convert": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -1250,6 +1775,19 @@
             "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
             "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
         },
+        "node_modules/combined-stream": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+            "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "delayed-stream": "~1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
         "node_modules/commander": {
             "version": "7.2.0",
             "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
@@ -1780,6 +2318,34 @@
             "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
             "dev": true
         },
+        "node_modules/define-data-property": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+            "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "es-define-property": "^1.0.0",
+                "es-errors": "^1.3.0",
+                "gopd": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/define-lazy-prop": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+            "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
         "node_modules/delaunator": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
@@ -1788,6 +2354,16 @@
                 "robust-predicates": "^3.0.0"
             }
         },
+        "node_modules/delayed-stream": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+            "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
         "node_modules/detect-libc": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
@@ -1877,6 +2453,23 @@
                 "url": "https://github.com/fb55/domutils?sponsor=1"
             }
         },
+        "node_modules/eastasianwidth": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+            "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/ecdsa-sig-formatter": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+            "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            }
+        },
         "node_modules/emoji-regex": {
             "version": "8.0.0",
             "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -1904,6 +2497,29 @@
                 "url": "https://github.com/fb55/entities?sponsor=1"
             }
         },
+        "node_modules/es-define-property": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+            "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "get-intrinsic": "^1.2.4"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es-errors": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+            "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/esbuild": {
             "version": "0.18.12",
             "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.12.tgz",
@@ -2156,6 +2772,16 @@
                 "node": ">=0.10.0"
             }
         },
+        "node_modules/events": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+            "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8.x"
+            }
+        },
         "node_modules/expand-template": {
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -2309,6 +2935,38 @@
                 }
             }
         },
+        "node_modules/foreground-child": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+            "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "cross-spawn": "^7.0.0",
+                "signal-exit": "^4.0.1"
+            },
+            "engines": {
+                "node": ">=14"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/form-data": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+            "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "asynckit": "^0.4.0",
+                "combined-stream": "^1.0.8",
+                "mime-types": "^2.1.12"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
         "node_modules/fs-constants": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -2323,10 +2981,14 @@
             "dev": true
         },
         "node_modules/function-bind": {
-            "version": "1.1.1",
-            "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-            "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-            "dev": true
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+            "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+            "dev": true,
+            "license": "MIT",
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
         },
         "node_modules/get-caller-file": {
             "version": "2.0.5",
@@ -2337,14 +2999,20 @@
             }
         },
         "node_modules/get-intrinsic": {
-            "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
-            "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+            "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "function-bind": "^1.1.1",
-                "has": "^1.0.3",
-                "has-symbols": "^1.0.3"
+                "es-errors": "^1.3.0",
+                "function-bind": "^1.1.2",
+                "has-proto": "^1.0.1",
+                "has-symbols": "^1.0.3",
+                "hasown": "^2.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
             },
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
@@ -2424,6 +3092,19 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/gopd": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+            "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "get-intrinsic": "^1.1.3"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/grapheme-splitter": {
             "version": "1.0.4",
             "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
@@ -2436,18 +3117,6 @@
             "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
             "dev": true
         },
-        "node_modules/has": {
-            "version": "1.0.3",
-            "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-            "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-            "dev": true,
-            "dependencies": {
-                "function-bind": "^1.1.1"
-            },
-            "engines": {
-                "node": ">= 0.4.0"
-            }
-        },
         "node_modules/has-flag": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -2457,11 +3126,38 @@
                 "node": ">=8"
             }
         },
+        "node_modules/has-property-descriptors": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+            "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "es-define-property": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/has-proto": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+            "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/has-symbols": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
             "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">= 0.4"
             },
@@ -2469,6 +3165,19 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/hasown": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+            "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "function-bind": "^1.1.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/hosted-git-info": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@@ -2642,6 +3351,22 @@
                 "is-ci": "bin.js"
             }
         },
+        "node_modules/is-docker": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+            "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "is-docker": "cli.js"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
         "node_modules/is-extglob": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -2689,6 +3414,19 @@
                 "node": ">=8"
             }
         },
+        "node_modules/is-wsl": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+            "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-docker": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
         "node_modules/isarray": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -2701,6 +3439,22 @@
             "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
             "dev": true
         },
+        "node_modules/jackspeak": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz",
+            "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
+            "dev": true,
+            "license": "BlueOak-1.0.0",
+            "dependencies": {
+                "@isaacs/cliui": "^8.0.2"
+            },
+            "engines": {
+                "node": "20 || >=22"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
         "node_modules/js-yaml": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -2731,6 +3485,52 @@
             "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
             "dev": true
         },
+        "node_modules/jsonwebtoken": {
+            "version": "9.0.2",
+            "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+            "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "jws": "^3.2.2",
+                "lodash.includes": "^4.3.0",
+                "lodash.isboolean": "^3.0.3",
+                "lodash.isinteger": "^4.0.4",
+                "lodash.isnumber": "^3.0.3",
+                "lodash.isplainobject": "^4.0.6",
+                "lodash.isstring": "^4.0.1",
+                "lodash.once": "^4.0.0",
+                "ms": "^2.1.1",
+                "semver": "^7.5.4"
+            },
+            "engines": {
+                "node": ">=12",
+                "npm": ">=6"
+            }
+        },
+        "node_modules/jsonwebtoken/node_modules/jwa": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+            "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "buffer-equal-constant-time": "1.0.1",
+                "ecdsa-sig-formatter": "1.0.11",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/jsonwebtoken/node_modules/jws": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+            "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "jwa": "^1.4.1",
+                "safe-buffer": "^5.0.1"
+            }
+        },
         "node_modules/jszip": {
             "version": "3.10.1",
             "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
@@ -2743,6 +3543,29 @@
                 "setimmediate": "^1.0.5"
             }
         },
+        "node_modules/jwa": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
+            "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "buffer-equal-constant-time": "1.0.1",
+                "ecdsa-sig-formatter": "1.0.11",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/jws": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
+            "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "jwa": "^2.0.0",
+                "safe-buffer": "^5.0.1"
+            }
+        },
         "node_modules/keytar": {
             "version": "7.9.0",
             "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
@@ -2787,12 +3610,13 @@
             }
         },
         "node_modules/linkify-it": {
-            "version": "3.0.3",
-            "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
-            "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+            "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "uc.micro": "^1.0.1"
+                "uc.micro": "^2.0.0"
             }
         },
         "node_modules/locate-path": {
@@ -2810,12 +3634,61 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/lodash.includes": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+            "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/lodash.isboolean": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+            "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/lodash.isinteger": {
+            "version": "4.0.4",
+            "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+            "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/lodash.isnumber": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+            "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/lodash.isplainobject": {
+            "version": "4.0.6",
+            "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+            "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/lodash.isstring": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+            "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/lodash.merge": {
             "version": "4.6.2",
             "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
             "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
             "dev": true
         },
+        "node_modules/lodash.once": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+            "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/lru-cache": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -2828,35 +3701,29 @@
             }
         },
         "node_modules/markdown-it": {
-            "version": "12.3.2",
-            "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
-            "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+            "version": "14.1.0",
+            "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
+            "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "argparse": "^2.0.1",
-                "entities": "~2.1.0",
-                "linkify-it": "^3.0.1",
-                "mdurl": "^1.0.1",
-                "uc.micro": "^1.0.5"
+                "entities": "^4.4.0",
+                "linkify-it": "^5.0.0",
+                "mdurl": "^2.0.0",
+                "punycode.js": "^2.3.1",
+                "uc.micro": "^2.1.0"
             },
             "bin": {
-                "markdown-it": "bin/markdown-it.js"
-            }
-        },
-        "node_modules/markdown-it/node_modules/entities": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
-            "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
-            "dev": true,
-            "funding": {
-                "url": "https://github.com/fb55/entities?sponsor=1"
+                "markdown-it": "bin/markdown-it.mjs"
             }
         },
         "node_modules/mdurl": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
-            "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
-            "dev": true
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+            "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/merge2": {
             "version": "1.4.1",
@@ -2868,12 +3735,13 @@
             }
         },
         "node_modules/micromatch": {
-            "version": "4.0.5",
-            "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-            "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+            "version": "4.0.8",
+            "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+            "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "braces": "^3.0.2",
+                "braces": "^3.0.3",
                 "picomatch": "^2.3.1"
             },
             "engines": {
@@ -2892,6 +3760,29 @@
                 "node": ">=4"
             }
         },
+        "node_modules/mime-db": {
+            "version": "1.52.0",
+            "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+            "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/mime-types": {
+            "version": "2.1.35",
+            "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+            "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "mime-db": "1.52.0"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
         "node_modules/mimic-response": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
@@ -2927,6 +3818,16 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/minipass": {
+            "version": "7.1.2",
+            "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+            "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+            "dev": true,
+            "license": "ISC",
+            "engines": {
+                "node": ">=16 || 14 >=14.17"
+            }
+        },
         "node_modules/mkdirp-classic": {
             "version": "0.5.3",
             "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
@@ -2998,10 +3899,14 @@
             }
         },
         "node_modules/object-inspect": {
-            "version": "1.12.3",
-            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
-            "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+            "version": "1.13.2",
+            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
+            "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
             "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            },
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
             }
@@ -3015,6 +3920,24 @@
                 "wrappy": "1"
             }
         },
+        "node_modules/open": {
+            "version": "8.4.2",
+            "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+            "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "define-lazy-prop": "^2.0.0",
+                "is-docker": "^2.1.1",
+                "is-wsl": "^2.2.0"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
         "node_modules/optionator": {
             "version": "0.9.3",
             "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
@@ -3053,6 +3976,93 @@
                 "node": ">= 14"
             }
         },
+        "node_modules/ovsx/node_modules/@vscode/vsce": {
+            "version": "2.32.0",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.32.0.tgz",
+            "integrity": "sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@azure/identity": "^4.1.0",
+                "@vscode/vsce-sign": "^2.0.0",
+                "azure-devops-node-api": "^12.5.0",
+                "chalk": "^2.4.2",
+                "cheerio": "^1.0.0-rc.9",
+                "cockatiel": "^3.1.2",
+                "commander": "^6.2.1",
+                "form-data": "^4.0.0",
+                "glob": "^7.0.6",
+                "hosted-git-info": "^4.0.2",
+                "jsonc-parser": "^3.2.0",
+                "leven": "^3.1.0",
+                "markdown-it": "^12.3.2",
+                "mime": "^1.3.4",
+                "minimatch": "^3.0.3",
+                "parse-semver": "^1.1.1",
+                "read": "^1.0.7",
+                "semver": "^7.5.2",
+                "tmp": "^0.2.1",
+                "typed-rest-client": "^1.8.4",
+                "url-join": "^4.0.1",
+                "xml2js": "^0.5.0",
+                "yauzl": "^2.3.1",
+                "yazl": "^2.2.2"
+            },
+            "bin": {
+                "vsce": "vsce"
+            },
+            "engines": {
+                "node": ">= 16"
+            },
+            "optionalDependencies": {
+                "keytar": "^7.7.0"
+            }
+        },
+        "node_modules/ovsx/node_modules/ansi-styles": {
+            "version": "3.2.1",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+            "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "color-convert": "^1.9.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/ovsx/node_modules/chalk": {
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+            "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/ovsx/node_modules/color-convert": {
+            "version": "1.9.3",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+            "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "color-name": "1.1.3"
+            }
+        },
+        "node_modules/ovsx/node_modules/color-name": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+            "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/ovsx/node_modules/commander": {
             "version": "6.2.1",
             "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
@@ -3062,6 +4072,90 @@
                 "node": ">= 6"
             }
         },
+        "node_modules/ovsx/node_modules/entities": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+            "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
+        "node_modules/ovsx/node_modules/escape-string-regexp": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+            "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/ovsx/node_modules/has-flag": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+            "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/ovsx/node_modules/linkify-it": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+            "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "uc.micro": "^1.0.1"
+            }
+        },
+        "node_modules/ovsx/node_modules/markdown-it": {
+            "version": "12.3.2",
+            "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+            "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "argparse": "^2.0.1",
+                "entities": "~2.1.0",
+                "linkify-it": "^3.0.1",
+                "mdurl": "^1.0.1",
+                "uc.micro": "^1.0.5"
+            },
+            "bin": {
+                "markdown-it": "bin/markdown-it.js"
+            }
+        },
+        "node_modules/ovsx/node_modules/mdurl": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+            "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/ovsx/node_modules/supports-color": {
+            "version": "5.5.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+            "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/ovsx/node_modules/uc.micro": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+            "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/p-limit": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -3092,6 +4186,13 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/package-json-from-dist": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+            "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+            "dev": true,
+            "license": "BlueOak-1.0.0"
+        },
         "node_modules/pako": {
             "version": "1.0.11",
             "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -3180,6 +4281,33 @@
                 "node": ">=8"
             }
         },
+        "node_modules/path-scurry": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
+            "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
+            "dev": true,
+            "license": "BlueOak-1.0.0",
+            "dependencies": {
+                "lru-cache": "^11.0.0",
+                "minipass": "^7.1.2"
+            },
+            "engines": {
+                "node": "20 || >=22"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/path-scurry/node_modules/lru-cache": {
+            "version": "11.0.1",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz",
+            "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==",
+            "dev": true,
+            "license": "ISC",
+            "engines": {
+                "node": "20 || >=22"
+            }
+        },
         "node_modules/path-type": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -3284,13 +4412,24 @@
                 "node": ">=6"
             }
         },
+        "node_modules/punycode.js": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+            "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
         "node_modules/qs": {
-            "version": "6.11.0",
-            "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
-            "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+            "version": "6.13.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+            "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
             "dev": true,
+            "license": "BSD-3-Clause",
             "dependencies": {
-                "side-channel": "^1.0.4"
+                "side-channel": "^1.0.6"
             },
             "engines": {
                 "node": ">=0.6"
@@ -3478,6 +4617,24 @@
                 "node": ">=10"
             }
         },
+        "node_modules/set-function-length": {
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+            "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "define-data-property": "^1.1.4",
+                "es-errors": "^1.3.0",
+                "function-bind": "^1.1.2",
+                "get-intrinsic": "^1.2.4",
+                "gopd": "^1.0.1",
+                "has-property-descriptors": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/setimmediate": {
             "version": "1.0.5",
             "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -3506,19 +4663,37 @@
             }
         },
         "node_modules/side-channel": {
-            "version": "1.0.4",
-            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
-            "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+            "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "call-bind": "^1.0.0",
-                "get-intrinsic": "^1.0.2",
-                "object-inspect": "^1.9.0"
+                "call-bind": "^1.0.7",
+                "es-errors": "^1.3.0",
+                "get-intrinsic": "^1.2.4",
+                "object-inspect": "^1.13.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
             },
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/signal-exit": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+            "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+            "dev": true,
+            "license": "ISC",
+            "engines": {
+                "node": ">=14"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
         "node_modules/simple-concat": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
@@ -3575,6 +4750,17 @@
                 "node": ">=8"
             }
         },
+        "node_modules/stoppable": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
+            "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4",
+                "npm": ">=6"
+            }
+        },
         "node_modules/string_decoder": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -3597,6 +4783,22 @@
                 "node": ">=8"
             }
         },
+        "node_modules/string-width-cjs": {
+            "name": "string-width",
+            "version": "4.2.3",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+            "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "emoji-regex": "^8.0.0",
+                "is-fullwidth-code-point": "^3.0.0",
+                "strip-ansi": "^6.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
         "node_modules/strip-ansi": {
             "version": "6.0.1",
             "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -3608,6 +4810,20 @@
                 "node": ">=8"
             }
         },
+        "node_modules/strip-ansi-cjs": {
+            "name": "strip-ansi",
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+            "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-regex": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
         "node_modules/strip-json-comments": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -3684,15 +4900,13 @@
             "dev": true
         },
         "node_modules/tmp": {
-            "version": "0.2.1",
-            "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
-            "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+            "version": "0.2.3",
+            "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
+            "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
             "dev": true,
-            "dependencies": {
-                "rimraf": "^3.0.0"
-            },
+            "license": "MIT",
             "engines": {
-                "node": ">=8.17.0"
+                "node": ">=14.14"
             }
         },
         "node_modules/to-regex-range": {
@@ -3720,16 +4934,18 @@
             }
         },
         "node_modules/tslib": {
-            "version": "2.6.0",
-            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
-            "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==",
-            "dev": true
+            "version": "2.8.0",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
+            "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==",
+            "dev": true,
+            "license": "0BSD"
         },
         "node_modules/tunnel": {
             "version": "0.0.6",
             "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
             "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
             }
@@ -3772,10 +4988,11 @@
             }
         },
         "node_modules/typed-rest-client": {
-            "version": "1.8.9",
-            "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.9.tgz",
-            "integrity": "sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g==",
+            "version": "1.8.11",
+            "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz",
+            "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "qs": "^6.9.1",
                 "tunnel": "0.0.6",
@@ -3783,10 +5000,11 @@
             }
         },
         "node_modules/typescript": {
-            "version": "5.1.6",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
-            "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
+            "version": "5.6.3",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
+            "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
             "dev": true,
+            "license": "Apache-2.0",
             "bin": {
                 "tsc": "bin/tsc",
                 "tsserver": "bin/tsserver"
@@ -3796,16 +5014,18 @@
             }
         },
         "node_modules/uc.micro": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
-            "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
-            "dev": true
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+            "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/underscore": {
-            "version": "1.13.6",
-            "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
-            "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
-            "dev": true
+            "version": "1.13.7",
+            "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz",
+            "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/uri-js": {
             "version": "4.4.1",
@@ -3828,6 +5048,16 @@
             "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
             "dev": true
         },
+        "node_modules/uuid": {
+            "version": "8.3.2",
+            "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+            "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "uuid": "dist/bin/uuid"
+            }
+        },
         "node_modules/vscode-jsonrpc": {
             "version": "8.1.0",
             "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz",
@@ -3913,12 +5143,45 @@
                 "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
             }
         },
+        "node_modules/wrap-ansi-cjs": {
+            "name": "wrap-ansi",
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+            "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^4.0.0",
+                "string-width": "^4.1.0",
+                "strip-ansi": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+            }
+        },
         "node_modules/wrappy": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
             "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
             "dev": true
         },
+        "node_modules/xml2js": {
+            "version": "0.5.0",
+            "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
+            "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "sax": ">=0.6.0",
+                "xmlbuilder": "~11.0.0"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
         "node_modules/xmlbuilder": {
             "version": "11.0.1",
             "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index a52b3d1ec5c..e55eceff781 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -58,14 +58,14 @@
         "@typescript-eslint/eslint-plugin": "^6.0.0",
         "@typescript-eslint/parser": "^6.0.0",
         "@vscode/test-electron": "^2.3.8",
-        "@vscode/vsce": "^2.19.0",
+        "@vscode/vsce": "^3.0.0",
         "esbuild": "^0.18.12",
         "eslint": "^8.44.0",
         "eslint-config-prettier": "^8.8.0",
         "ovsx": "^0.8.2",
         "prettier": "^3.0.0",
         "tslib": "^2.6.0",
-        "typescript": "^5.1.6"
+        "typescript": "^5.6.0"
     },
     "activationEvents": [
         "workspaceContains:Cargo.toml",
@@ -349,6 +349,11 @@
                         "markdownDescription": "Whether to show the test explorer.",
                         "default": false,
                         "type": "boolean"
+                    },
+                    "rust-analyzer.initializeStopped": {
+                        "markdownDescription": "Do not start rust-analyzer server when the extension is activated.",
+                        "default": false,
+                        "type": "boolean"
                     }
                 }
             },
@@ -728,8 +733,8 @@
                     "rust-analyzer.cargo.cfgs": {
                         "markdownDescription": "List of cfg options to enable with the given values.",
                         "default": {
-                            "debug_assertions": null,
-                            "miri": null
+                            "miri": null,
+                            "debug_assertions": null
                         },
                         "type": "object"
                     }
@@ -1152,18 +1157,10 @@
                     "rust-analyzer.completion.snippets.custom": {
                         "markdownDescription": "Custom completion snippets.",
                         "default": {
-                            "Arc::new": {
-                                "postfix": "arc",
-                                "body": "Arc::new(${receiver})",
-                                "requires": "std::sync::Arc",
-                                "description": "Put the expression into an `Arc`",
-                                "scope": "expr"
-                            },
-                            "Rc::new": {
-                                "postfix": "rc",
-                                "body": "Rc::new(${receiver})",
-                                "requires": "std::rc::Rc",
-                                "description": "Put the expression into an `Rc`",
+                            "Ok": {
+                                "postfix": "ok",
+                                "body": "Ok(${receiver})",
+                                "description": "Wrap the expression in a `Result::Ok`",
                                 "scope": "expr"
                             },
                             "Box::pin": {
@@ -1173,10 +1170,11 @@
                                 "description": "Put the expression into a pinned `Box`",
                                 "scope": "expr"
                             },
-                            "Err": {
-                                "postfix": "err",
-                                "body": "Err(${receiver})",
-                                "description": "Wrap the expression in a `Result::Err`",
+                            "Arc::new": {
+                                "postfix": "arc",
+                                "body": "Arc::new(${receiver})",
+                                "requires": "std::sync::Arc",
+                                "description": "Put the expression into an `Arc`",
                                 "scope": "expr"
                             },
                             "Some": {
@@ -1185,10 +1183,17 @@
                                 "description": "Wrap the expression in an `Option::Some`",
                                 "scope": "expr"
                             },
-                            "Ok": {
-                                "postfix": "ok",
-                                "body": "Ok(${receiver})",
-                                "description": "Wrap the expression in a `Result::Ok`",
+                            "Err": {
+                                "postfix": "err",
+                                "body": "Err(${receiver})",
+                                "description": "Wrap the expression in a `Result::Err`",
+                                "scope": "expr"
+                            },
+                            "Rc::new": {
+                                "postfix": "rc",
+                                "body": "Rc::new(${receiver})",
+                                "requires": "std::rc::Rc",
+                                "description": "Put the expression into an `Rc`",
                                 "scope": "expr"
                             }
                         },
diff --git a/src/tools/rust-analyzer/editors/code/src/config.ts b/src/tools/rust-analyzer/editors/code/src/config.ts
index abb4099f9f5..67bc72f1e12 100644
--- a/src/tools/rust-analyzer/editors/code/src/config.ts
+++ b/src/tools/rust-analyzer/editors/code/src/config.ts
@@ -330,6 +330,10 @@ export class Config {
     get statusBarClickAction() {
         return this.get<string>("statusBar.clickAction");
     }
+
+    get initializeStopped() {
+        return this.get<boolean>("initializeStopped");
+    }
 }
 
 export function prepareVSCodeConfig<T>(resp: T): T {
diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts
index 77ab44f24ce..9e2e3d2185b 100644
--- a/src/tools/rust-analyzer/editors/code/src/debug.ts
+++ b/src/tools/rust-analyzer/editors/code/src/debug.ts
@@ -6,7 +6,6 @@ import type * as ra from "./lsp_ext";
 import { Cargo } from "./toolchain";
 import type { Ctx } from "./ctx";
 import { createTaskFromRunnable, prepareEnv } from "./run";
-import { execSync } from "node:child_process";
 import { execute, isCargoRunnableArgs, unwrapUndefinable } from "./util";
 import type { Config } from "./config";
 
@@ -152,9 +151,24 @@ async function getDebugConfiguration(
     const env = prepareEnv(inheritEnv, runnable.label, runnableArgs, config.runnablesExtraEnv);
     const executable = await getDebugExecutable(runnableArgs, env);
     let sourceFileMap = debugOptions.sourceFileMap;
+
     if (sourceFileMap === "auto") {
         sourceFileMap = {};
-        await discoverSourceFileMap(sourceFileMap, env, wsFolder);
+        const computedSourceFileMap = await discoverSourceFileMap(env, wsFolder);
+
+        if (computedSourceFileMap) {
+            // lldb-dap requires passing the source map as an array of two element arrays.
+            // the two element array contains a source and destination pathname.
+            // TODO: remove lldb-dap-specific post-processing once
+            // https://github.com/llvm/llvm-project/pull/106919/ is released in the extension.
+            if (provider.type === "lldb-dap") {
+                provider.additional["sourceMap"] = [
+                    [computedSourceFileMap?.source, computedSourceFileMap?.destination],
+                ];
+            } else {
+                sourceFileMap[computedSourceFileMap.source] = computedSourceFileMap.destination;
+            }
+        }
     }
 
     const debugConfig = getDebugConfig(
@@ -189,11 +203,15 @@ async function getDebugConfiguration(
     return debugConfig;
 }
 
+type SourceFileMap = {
+    source: string;
+    destination: string;
+};
+
 async function discoverSourceFileMap(
-    sourceFileMap: Record<string, string>,
     env: Record<string, string>,
     cwd: string,
-) {
+): Promise<SourceFileMap | undefined> {
     const sysroot = env["RUSTC_TOOLCHAIN"];
     if (sysroot) {
         // let's try to use the default toolchain
@@ -203,9 +221,11 @@ async function discoverSourceFileMap(
         const commitHash = rx.exec(data)?.[1];
         if (commitHash) {
             const rustlib = path.normalize(sysroot + "/lib/rustlib/src/rust");
-            sourceFileMap[`/rustc/${commitHash}/`] = rustlib;
+            return { source: rustlib, destination: rustlib };
         }
     }
+
+    return;
 }
 
 type PropertyFetcher<Config, Input, Key extends keyof Config> = (
@@ -218,7 +238,7 @@ type DebugConfigProvider<Type extends string, DebugConfig extends BaseDebugConfi
     runnableArgsProperty: PropertyFetcher<DebugConfig, ra.CargoRunnableArgs, keyof DebugConfig>;
     sourceFileMapProperty?: keyof DebugConfig;
     type: Type;
-    additional?: Record<string, unknown>;
+    additional: Record<string, unknown>;
 };
 
 type KnownEnginesType = (typeof knownEngines)[keyof typeof knownEngines];
@@ -236,16 +256,7 @@ const knownEngines: {
             "args",
             runnableArgs.executableArgs,
         ],
-        additional: {
-            sourceMap: [
-                [
-                    `/rustc/${/commit-hash:\s(.*)$/m.exec(
-                        execSync("rustc -V -v", {}).toString(),
-                    )?.[1]}/library`,
-                    "${config:rust-analyzer.cargo.sysroot}/lib/rustlib/src/rust/library",
-                ],
-            ],
-        },
+        additional: {},
     },
     "vadimcn.vscode-lldb": {
         type: "lldb",
diff --git a/src/tools/rust-analyzer/editors/code/src/main.ts b/src/tools/rust-analyzer/editors/code/src/main.ts
index 0ddc5619e99..fdf43f66f94 100644
--- a/src/tools/rust-analyzer/editors/code/src/main.ts
+++ b/src/tools/rust-analyzer/editors/code/src/main.ts
@@ -107,7 +107,14 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
         initializeDebugSessionTrackingAndRebuild(ctx);
     }
 
-    await ctx.start();
+    if (ctx.config.initializeStopped) {
+        ctx.setServerStatus({
+            health: "stopped",
+        });
+    } else {
+        await ctx.start();
+    }
+
     return ctx;
 }
 
diff --git a/src/tools/rust-analyzer/lib/line-index/Cargo.toml b/src/tools/rust-analyzer/lib/line-index/Cargo.toml
index 8ae4954dd0d..14196ba3d09 100644
--- a/src/tools/rust-analyzer/lib/line-index/Cargo.toml
+++ b/src/tools/rust-analyzer/lib/line-index/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "line-index"
-version = "0.1.1"
+version = "0.1.2"
 description = "Maps flat `TextSize` offsets to/from `(line, column)` representation."
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/line-index"
diff --git a/src/tools/rust-analyzer/lib/line-index/src/lib.rs b/src/tools/rust-analyzer/lib/line-index/src/lib.rs
index 66875e25242..6f0455ee98b 100644
--- a/src/tools/rust-analyzer/lib/line-index/src/lib.rs
+++ b/src/tools/rust-analyzer/lib/line-index/src/lib.rs
@@ -177,6 +177,14 @@ impl LineIndex {
         Some(LineCol { line: line_col.line, col })
     }
 
+    /// Returns the given line's range.
+    pub fn line(&self, line: u32) -> Option<TextRange> {
+        let start = self.start_offset(line as usize)?;
+        let next_newline = self.newlines.get(line as usize).copied().unwrap_or(self.len);
+        let line_length = next_newline - start;
+        Some(TextRange::new(start, start + line_length))
+    }
+
     /// Given a range [start, end), returns a sorted iterator of non-empty ranges [start, x1), [x1,
     /// x2), ..., [xn, end) where all the xi, which are positions of newlines, are inside the range
     /// [start, end).
diff --git a/src/tools/rust-analyzer/lib/line-index/src/tests.rs b/src/tools/rust-analyzer/lib/line-index/src/tests.rs
index 57fad1dfc05..f2bb04aec32 100644
--- a/src/tools/rust-analyzer/lib/line-index/src/tests.rs
+++ b/src/tools/rust-analyzer/lib/line-index/src/tests.rs
@@ -195,3 +195,26 @@ fn test_every_chars() {
         }
     }
 }
+
+#[test]
+fn test_line() {
+    use text_size::TextRange;
+
+    macro_rules! validate {
+        ($text:expr, $line:expr, $expected_start:literal .. $expected_end:literal) => {
+            let line_index = LineIndex::new($text);
+            assert_eq!(
+                line_index.line($line),
+                Some(TextRange::new(
+                    TextSize::from($expected_start),
+                    TextSize::from($expected_end)
+                ))
+            );
+        };
+    }
+
+    validate!("", 0, 0..0);
+    validate!("\n", 1, 1..1);
+    validate!("\nabc", 1, 1..4);
+    validate!("\nabc\ndef", 1, 1..5);
+}
diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version
index d0f9fa7ac42..bc324402a96 100644
--- a/src/tools/rust-analyzer/rust-version
+++ b/src/tools/rust-analyzer/rust-version
@@ -1 +1 @@
-dd5127615ad626741a1116d022cf784637ac05df
+1de57a5ce952c722f7053aeacfc6c90bc139b678
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs
index f1a96e0c6a2..9269d154235 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs
@@ -111,7 +111,7 @@ const RESERVED: &[&str] = &[
 // keywords that are keywords only in specific parse contexts
 #[doc(alias = "WEAK_KEYWORDS")]
 const CONTEXTUAL_KEYWORDS: &[&str] =
-    &["macro_rules", "union", "default", "raw", "dyn", "auto", "yeet"];
+    &["macro_rules", "union", "default", "raw", "dyn", "auto", "yeet", "safe"];
 // keywords we use for special macro expansions
 const CONTEXTUAL_BUILTIN_KEYWORDS: &[&str] = &[
     "asm",
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 928867be64f..42e608ff5ce 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -13,7 +13,7 @@ walkdir = "2"
 ignore = "0.4.18"
 semver = "1.0"
 termcolor = "1.1.3"
-rustc-hash = "1.1.0"
+rustc-hash = "2.0.0"
 fluent-syntax = "0.11.1"
 similar = "2.5.0"
 
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 22126674c15..94f8d23c158 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -2758,7 +2758,6 @@ ui/lint/issue-63364.rs
 ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
 ui/lint/issue-79546-fuel-ice.rs
 ui/lint/issue-79744.rs
-ui/lint/issue-80988.rs
 ui/lint/issue-81218.rs
 ui/lint/issue-83477.rs
 ui/lint/issue-87274-paren-parent.rs
@@ -3721,16 +3720,6 @@ ui/rfcs/rfc-2497-if-let-chains/issue-99938.rs
 ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs
 ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs
 ui/rfcs/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs
-ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs
-ui/rfcs/rfc-2632-const-trait-impl/issue-102156.rs
-ui/rfcs/rfc-2632-const-trait-impl/issue-102985.rs
-ui/rfcs/rfc-2632-const-trait-impl/issue-103677.rs
-ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs
-ui/rfcs/rfc-2632-const-trait-impl/issue-88155.rs
-ui/rfcs/rfc-2632-const-trait-impl/issue-92111.rs
-ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs
-ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
-ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
 ui/rust-2018/issue-51008-1.rs
 ui/rust-2018/issue-51008.rs
 ui/rust-2018/issue-52202-use-suggestions.rs
@@ -3984,6 +3973,16 @@ ui/traits/alias/issue-75983.rs
 ui/traits/alias/issue-83613.rs
 ui/traits/associated_type_bound/issue-51446.rs
 ui/traits/auxiliary/issue_89119_intercrate_caching.rs
+ui/traits/const-traits/issue-100222.rs
+ui/traits/const-traits/issue-102156.rs
+ui/traits/const-traits/issue-102985.rs
+ui/traits/const-traits/issue-103677.rs
+ui/traits/const-traits/issue-79450.rs
+ui/traits/const-traits/issue-88155.rs
+ui/traits/const-traits/issue-92111.rs
+ui/traits/const-traits/issue-92230-wf-super-trait-env.rs
+ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs
+ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs
 ui/traits/issue-103563.rs
 ui/traits/issue-104322.rs
 ui/traits/issue-105231.rs
diff --git a/src/tools/unicode-table-generator/Cargo.toml b/src/tools/unicode-table-generator/Cargo.toml
index ef01877c0b9..f8a500922d0 100644
--- a/src/tools/unicode-table-generator/Cargo.toml
+++ b/src/tools/unicode-table-generator/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-name = "unicode-bdd"
+name = "unicode-table-generator"
 version = "0.1.0"
 edition = "2021"
 
diff --git a/src/tools/unicode-table-generator/src/range_search.rs b/src/tools/unicode-table-generator/src/range_search.rs
index 3a5b869f72f..221e5d75ef5 100644
--- a/src/tools/unicode-table-generator/src/range_search.rs
+++ b/src/tools/unicode-table-generator/src/range_search.rs
@@ -16,16 +16,14 @@ const fn bitset_search<
     let bucket_idx = (needle / 64) as usize;
     let chunk_map_idx = bucket_idx / CHUNK_SIZE;
     let chunk_piece = bucket_idx % CHUNK_SIZE;
-    // FIXME: const-hack: Revert to `slice::get` after `const_slice_index`
-    // feature stabilizes.
+    // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const.
     let chunk_idx = if chunk_map_idx < chunk_idx_map.len() {
         chunk_idx_map[chunk_map_idx]
     } else {
         return false;
     };
     let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize;
-    // FIXME: const-hack: Revert to `slice::get` after `const_slice_index`
-    // feature stabilizes.
+    // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const.
     let word = if idx < bitset_canonical.len() {
         bitset_canonical[idx]
     } else {
diff --git a/tests/assembly/riscv-soft-abi-with-float-features.rs b/tests/assembly/riscv-soft-abi-with-float-features.rs
new file mode 100644
index 00000000000..733137f5700
--- /dev/null
+++ b/tests/assembly/riscv-soft-abi-with-float-features.rs
@@ -0,0 +1,46 @@
+//@ assembly-output: emit-asm
+//@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d
+//@ needs-llvm-components: riscv
+
+#![feature(no_core, lang_items, f16)]
+#![crate_type = "lib"]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+impl Copy for f16 {}
+impl Copy for f32 {}
+impl Copy for f64 {}
+
+// This test checks that the floats are all returned in `a0` as required by the `lp64` ABI.
+
+// CHECK-LABEL: read_f16
+#[no_mangle]
+pub extern "C" fn read_f16(x: &f16) -> f16 {
+    // CHECK: lh a0, 0(a0)
+    // CHECK-NEXT: lui a1, 1048560
+    // CHECK-NEXT: or a0, a0, a1
+    // CHECK-NEXT: ret
+    *x
+}
+
+// CHECK-LABEL: read_f32
+#[no_mangle]
+pub extern "C" fn read_f32(x: &f32) -> f32 {
+    // CHECK: flw fa5, 0(a0)
+    // CHECK-NEXT: fmv.x.w a0, fa5
+    // CHECK-NEXT: ret
+    *x
+}
+
+// CHECK-LABEL: read_f64
+#[no_mangle]
+pub extern "C" fn read_f64(x: &f64) -> f64 {
+    // CHECK: ld a0, 0(a0)
+    // CHECK-NEXT: ret
+    *x
+}
diff --git a/tests/codegen/atomicptr.rs b/tests/codegen/atomicptr.rs
index ea8b382c8fc..e8c5e6a6749 100644
--- a/tests/codegen/atomicptr.rs
+++ b/tests/codegen/atomicptr.rs
@@ -6,7 +6,6 @@
 
 //@ compile-flags: -O -Cno-prepopulate-passes
 #![crate_type = "lib"]
-#![feature(strict_provenance)]
 #![feature(strict_provenance_atomic_ptr)]
 
 use std::ptr::without_provenance_mut;
diff --git a/tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs b/tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs
index d4a74b3d782..122f02fbbc5 100644
--- a/tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs
+++ b/tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -O -C debug-assertions=yes
 
 #![crate_type = "lib"]
-#![feature(strict_provenance)]
 
 #[no_mangle]
 pub fn test(src: *const u8, dst: *const u8) -> usize {
diff --git a/tests/codegen/regparm-inreg.rs b/tests/codegen/regparm-inreg.rs
new file mode 100644
index 00000000000..c8c647bcc87
--- /dev/null
+++ b/tests/codegen/regparm-inreg.rs
@@ -0,0 +1,125 @@
+// Checks how `regparm` flag works with different calling conventions:
+// marks function arguments as "inreg" like the C/C++ compilers for the platforms.
+// x86 only.
+
+//@ compile-flags: --target i686-unknown-linux-gnu -O -C no-prepopulate-passes
+//@ needs-llvm-components: x86
+
+//@ revisions:regparm0 regparm1 regparm2 regparm3
+//@[regparm0] compile-flags: -Zregparm=0
+//@[regparm1] compile-flags: -Zregparm=1
+//@[regparm2] compile-flags: -Zregparm=2
+//@[regparm3] compile-flags: -Zregparm=3
+
+#![crate_type = "lib"]
+#![no_core]
+#![feature(no_core, lang_items, repr_simd)]
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+pub mod tests {
+    // regparm doesn't work for "fastcall" calling conv (only 2 inregs)
+    // CHECK: @f1(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 noundef %_3)
+    #[no_mangle]
+    pub extern "fastcall" fn f1(_: i32, _: i32, _: i32) {}
+
+    // regparm0: @f3(i32 noundef %_1, i32 noundef %_2, i32 noundef %_3)
+    // regparm1: @f3(i32 inreg noundef %_1, i32 noundef %_2, i32 noundef %_3)
+    // regparm2: @f3(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 noundef %_3)
+    // regparm3: @f3(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 inreg noundef %_3)
+    #[no_mangle]
+    pub extern "C" fn f3(_: i32, _: i32, _: i32) {}
+
+    // regparm0: @f4(i32 noundef %_1, i32 noundef %_2, i32 noundef %_3)
+    // regparm1: @f4(i32 inreg noundef %_1, i32 noundef %_2, i32 noundef %_3)
+    // regparm2: @f4(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 noundef %_3)
+    // regparm3: @f4(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 inreg noundef %_3)
+    #[no_mangle]
+    pub extern "cdecl" fn f4(_: i32, _: i32, _: i32) {}
+
+    // regparm0: @f5(i32 noundef %_1, i32 noundef %_2, i32 noundef %_3)
+    // regparm1: @f5(i32 inreg noundef %_1, i32 noundef %_2, i32 noundef %_3)
+    // regparm2: @f5(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 noundef %_3)
+    // regparm3: @f5(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 inreg noundef %_3)
+    #[no_mangle]
+    pub extern "stdcall" fn f5(_: i32, _: i32, _: i32) {}
+
+    // regparm doesn't work for thiscall
+    // CHECK: @f6(i32 noundef %_1, i32 noundef %_2, i32 noundef %_3)
+    #[no_mangle]
+    pub extern "thiscall" fn f6(_: i32, _: i32, _: i32) {}
+
+    struct S1 {
+        x1: i32,
+    }
+    // regparm0: @f7(i32 noundef %_1, i32 noundef %_2, i32 noundef %_3, i32 noundef %_4)
+    // regparm1: @f7(i32 inreg noundef %_1, i32 noundef %_2, i32 noundef %_3, i32 noundef %_4)
+    // regparm2: @f7(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 noundef %_3, i32 noundef %_4)
+    // regparm3: @f7(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 inreg noundef %_3,
+    // regparm3-SAME: i32 noundef %_4)
+    #[no_mangle]
+    pub extern "C" fn f7(_: i32, _: i32, _: S1, _: i32) {}
+
+    #[repr(C)]
+    struct S2 {
+        x1: i32,
+        x2: i32,
+    }
+    // regparm0: @f8(i32 noundef %_1, i32 noundef %_2, ptr {{.*}} %_3, i32 noundef %_4)
+    // regparm1: @f8(i32 inreg noundef %_1, i32 noundef %_2, ptr {{.*}} %_3, i32 noundef %_4)
+    // regparm2: @f8(i32 inreg noundef %_1, i32 inreg noundef %_2, ptr {{.*}} %_3, i32 noundef %_4)
+    // regparm3: @f8(i32 inreg noundef %_1, i32 inreg noundef %_2, ptr {{.*}} %_3,
+    // regparm3-SAME: i32 inreg noundef %_4)
+    #[no_mangle]
+    pub extern "C" fn f8(_: i32, _: i32, _: S2, _: i32) {}
+
+    // regparm0: @f9(i1 noundef zeroext %_1, i16 noundef signext %_2, i64 noundef %_3,
+    // regparm0-SAME: i128 noundef %_4)
+    // regparm1: @f9(i1 inreg noundef zeroext %_1, i16 noundef signext %_2, i64 noundef %_3,
+    // regparm1-SAME: i128 noundef %_4)
+    // regparm2: @f9(i1 inreg noundef zeroext %_1, i16 inreg noundef signext %_2, i64 noundef %_3,
+    // regparm2-SAME: i128 noundef %_4)
+    // regparm3: @f9(i1 inreg noundef zeroext %_1, i16 inreg noundef signext %_2, i64 noundef %_3,
+    // regparm3-SAME: i128 noundef %_4)
+    #[no_mangle]
+    pub extern "C" fn f9(_: bool, _: i16, _: i64, _: u128) {}
+
+    // regparm0: @f10(float noundef %_1, double noundef %_2, i1 noundef zeroext %_3,
+    // regparm0-SAME: i16 noundef signext %_4)
+    // regparm1: @f10(float noundef %_1, double noundef %_2, i1 inreg noundef zeroext %_3,
+    // regparm1-SAME: i16 noundef signext %_4)
+    // regparm2: @f10(float noundef %_1, double noundef %_2, i1 inreg noundef zeroext %_3,
+    // regparm2-SAME: i16 inreg noundef signext %_4)
+    // regparm3: @f10(float noundef %_1, double noundef %_2, i1 inreg noundef zeroext %_3,
+    // regparm3-SAME: i16 inreg noundef signext %_4)
+    #[no_mangle]
+    pub extern "C" fn f10(_: f32, _: f64, _: bool, _: i16) {}
+
+    #[allow(non_camel_case_types)]
+    #[repr(simd)]
+    pub struct __m128([f32; 4]);
+
+    // regparm0: @f11(i32 noundef %_1, <4 x float> %_2, i32 noundef %_3, i32 noundef %_4)
+    // regparm1: @f11(i32 inreg noundef %_1, <4 x float> %_2, i32 noundef %_3, i32 noundef %_4)
+    // regparm2: @f11(i32 inreg noundef %_1, <4 x float> %_2, i32 inreg noundef %_3,
+    // regparm2-SAME: i32 noundef %_4)
+    // regparm3: @f11(i32 inreg noundef %_1, <4 x float> %_2, i32 inreg noundef %_3,
+    // regparm3-SAME: i32 inreg noundef %_4)
+    #[no_mangle]
+    pub extern "C" fn f11(_: i32, _: __m128, _: i32, _: i32) {}
+
+    #[allow(non_camel_case_types)]
+    #[repr(simd)]
+    pub struct __m256([f32; 8]);
+
+    // regparm0: @f12(i32 noundef %_1, <8 x float> %_2, i32 noundef %_3, i32 noundef %_4)
+    // regparm1: @f12(i32 inreg noundef %_1, <8 x float> %_2, i32 noundef %_3, i32 noundef %_4)
+    // regparm2: @f12(i32 inreg noundef %_1, <8 x float> %_2, i32 inreg noundef %_3,
+    // regparm2-SAME: i32 noundef %_4)
+    // regparm3: @f12(i32 inreg noundef %_1, <8 x float> %_2, i32 inreg noundef %_3,
+    // regparm3-SAME: i32 inreg noundef %_4)
+    #[no_mangle]
+    pub extern "C" fn f12(_: i32, _: __m256, _: i32, _: i32) {}
+}
diff --git a/tests/codegen/riscv-target-abi.rs b/tests/codegen/riscv-target-abi.rs
index 5d545af9c76..88da4ece7ba 100644
--- a/tests/codegen/riscv-target-abi.rs
+++ b/tests/codegen/riscv-target-abi.rs
@@ -10,7 +10,7 @@
 
 //@[riscv32imac] compile-flags: --target=riscv32imac-unknown-none-elf
 //@[riscv32imac] needs-llvm-components: riscv
-// riscv32imac-NOT: !"target-abi"
+// riscv32imac: !{i32 1, !"target-abi", !"ilp32"}
 
 #![feature(no_core, lang_items)]
 #![crate_type = "lib"]
diff --git a/tests/crashes/131637.rs b/tests/crashes/131637.rs
new file mode 100644
index 00000000000..7d328384a74
--- /dev/null
+++ b/tests/crashes/131637.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #121637
+#![feature(non_lifetime_binders)]
+trait Trait<Type> {
+    type Type;
+
+    fn method(&self) -> impl for<T> Trait<impl Trait<T>>;
+}
diff --git a/tests/crashes/131648.rs b/tests/crashes/131648.rs
new file mode 100644
index 00000000000..68046ce2a1f
--- /dev/null
+++ b/tests/crashes/131648.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #131648
+#![feature(return_type_notation)]
+
+trait IntFactory {
+    fn stream(self) -> impl IntFactory<stream(..): Send>;
+}
+fn main() {}
diff --git a/tests/crashes/131668.rs b/tests/crashes/131668.rs
new file mode 100644
index 00000000000..90aa4494425
--- /dev/null
+++ b/tests/crashes/131668.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #131668
+
+#![feature(generic_associated_types_extended)]
+trait B {
+    type Y<const N: i16>;
+}
+
+struct Erase<T: B>(T);
+
+fn make_static() {
+    Erase::<dyn for<'c> B<&'c ()>>(());
+}
diff --git a/tests/crashes/131758.rs b/tests/crashes/131758.rs
new file mode 100644
index 00000000000..942c5fd7a50
--- /dev/null
+++ b/tests/crashes/131758.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #131758
+#![feature(unboxed_closures)]
+trait Foo {}
+
+impl<T: Fn<(i32,)>> Foo for T {}
+
+fn baz<T: Foo>(_: T) {}
+
+fn main() {
+    baz(|x| ());
+}
diff --git a/tests/crashes/131762.rs b/tests/crashes/131762.rs
new file mode 100644
index 00000000000..85cb9c8f20a
--- /dev/null
+++ b/tests/crashes/131762.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #131762
+// ignore-tidy-linelength
+
+#![feature(generic_assert)]
+struct FloatWrapper(f64);
+
+fn main() {
+    assert!((0.0 / 0.0 >= 0.0) == (FloatWrapper(0.0 / 0.0) >= FloatWrapper(size_of::<u8>, size_of::<u16>, size_of::<usize> as fn() -> usize)))
+}
diff --git a/tests/crashes/131787.rs b/tests/crashes/131787.rs
new file mode 100644
index 00000000000..5c24ff8c143
--- /dev/null
+++ b/tests/crashes/131787.rs
@@ -0,0 +1,5 @@
+//@ known-bug: #131787
+#[track_caller]
+static no_mangle: u32 = {
+    unimplemented!();
+};
diff --git a/tests/crashes/131886.rs b/tests/crashes/131886.rs
new file mode 100644
index 00000000000..c31c2d6aa8b
--- /dev/null
+++ b/tests/crashes/131886.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #131886
+//@ compile-flags: -Zvalidate-mir --crate-type=lib
+#![feature(trait_upcasting, type_alias_impl_trait)]
+
+type Tait = impl Sized;
+
+trait Foo<'a>: Bar<'a, 'a, Tait> {}
+trait Bar<'a, 'b, T> {}
+
+fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) {
+    let _ = x as &dyn Bar<'_, '_, ()>;
+}
diff --git a/tests/crashes/131915.rs b/tests/crashes/131915.rs
new file mode 100644
index 00000000000..58d45adcb3b
--- /dev/null
+++ b/tests/crashes/131915.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #131915
+
+macro_rules! y {
+    ( $($matcher:tt)*) => {
+        x
+    };
+}
+
+const _: A<
+    {
+        y! { test.tou8 }
+    },
+>;
diff --git a/tests/debuginfo/constant-ordering-prologue.rs b/tests/debuginfo/constant-ordering-prologue.rs
index f2d4fd37ce3..3136aff238a 100644
--- a/tests/debuginfo/constant-ordering-prologue.rs
+++ b/tests/debuginfo/constant-ordering-prologue.rs
@@ -20,11 +20,11 @@
 // lldb-command:run
 
 // lldb-command:print a
-// lldb-check: = 19
+// lldb-check: 19
 // lldb-command:print b
-// lldb-check: = 20
+// lldb-check: 20
 // lldb-command:print c
-// lldb-check: = 21.5
+// lldb-check: 21.5
 
 fn binding(a: i64, b: u64, c: f64) {
     let x = 0;
diff --git a/tests/mir-opt/dest-prop/union.rs b/tests/mir-opt/dest-prop/union.rs
index 4e6fb71bf75..85eded09980 100644
--- a/tests/mir-opt/dest-prop/union.rs
+++ b/tests/mir-opt/dest-prop/union.rs
@@ -1,4 +1,3 @@
-// skip-filecheck
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 //! Tests that we can propagate into places that are projections into unions
 //@ compile-flags: -Zunsound-mir-opts -C debuginfo=full
@@ -8,7 +7,7 @@ fn val() -> u32 {
 
 // EMIT_MIR union.main.DestinationPropagation.diff
 fn main() {
-    // CHECK-LABEL: fn args(
+    // CHECK-LABEL: fn main(
     // CHECK: {{_.*}} = Un { us: const 1_u32 };
     union Un {
         us: u32,
diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.rs b/tests/mir-opt/gvn_ptr_eq_with_constant.rs
index d8025072ee3..05445208e07 100644
--- a/tests/mir-opt/gvn_ptr_eq_with_constant.rs
+++ b/tests/mir-opt/gvn_ptr_eq_with_constant.rs
@@ -5,8 +5,6 @@
 
 // Regression for <https://github.com/rust-lang/rust/issues/127089>
 
-#![feature(strict_provenance)]
-
 struct Foo<T>(std::marker::PhantomData<T>);
 
 impl<T> Foo<T> {
diff --git a/tests/mir-opt/issues/issue_59352.rs b/tests/mir-opt/issues/issue_59352.rs
index 5c06b7e56f7..9024dc976e4 100644
--- a/tests/mir-opt/issues/issue_59352.rs
+++ b/tests/mir-opt/issues/issue_59352.rs
@@ -1,4 +1,3 @@
-// skip-filecheck
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 // This test is a mirror of codegen/issue-59352.rs.
 // The LLVM inliner doesn't inline `char::method::is_digit()` and so it doesn't recognize this case
diff --git a/tests/run-make/import-macro-verbatim/include/include.txt b/tests/run-make/import-macro-verbatim/include/include.txt
new file mode 100644
index 00000000000..63d71b14c1d
--- /dev/null
+++ b/tests/run-make/import-macro-verbatim/include/include.txt
@@ -0,0 +1 @@
+static TEST: &str = "Hello World!";
diff --git a/tests/run-make/import-macro-verbatim/rmake.rs b/tests/run-make/import-macro-verbatim/rmake.rs
new file mode 100644
index 00000000000..d2bf626e0aa
--- /dev/null
+++ b/tests/run-make/import-macro-verbatim/rmake.rs
@@ -0,0 +1,8 @@
+//@ only-windows other platforms do not have Windows verbatim paths
+use run_make_support::rustc;
+fn main() {
+    // Canonicalizing the path ensures that it's verbatim (i.e. starts with `\\?\`)
+    let mut path = std::fs::canonicalize(file!()).unwrap();
+    path.pop();
+    rustc().input("verbatim.rs").env("VERBATIM_DIR", path).run();
+}
diff --git a/tests/run-make/import-macro-verbatim/verbatim.rs b/tests/run-make/import-macro-verbatim/verbatim.rs
new file mode 100644
index 00000000000..56a83673c1f
--- /dev/null
+++ b/tests/run-make/import-macro-verbatim/verbatim.rs
@@ -0,0 +1,12 @@
+//! Include a file by concating the verbatim path using `/` instead of `\`
+
+include!(concat!(env!("VERBATIM_DIR"), "/include/include.txt"));
+fn main() {
+    assert_eq!(TEST, "Hello World!");
+
+    let s = include_str!(concat!(env!("VERBATIM_DIR"), "/include/include.txt"));
+    assert_eq!(s, "static TEST: &str = \"Hello World!\";\n");
+
+    let b = include_bytes!(concat!(env!("VERBATIM_DIR"), "/include/include.txt"));
+    assert_eq!(b, b"static TEST: &str = \"Hello World!\";\n");
+}
diff --git a/tests/run-make/rustc-crates-on-stable/rmake.rs b/tests/run-make/rustc-crates-on-stable/rmake.rs
index 81cc775c919..9fbc675cc9a 100644
--- a/tests/run-make/rustc-crates-on-stable/rmake.rs
+++ b/tests/run-make/rustc-crates-on-stable/rmake.rs
@@ -31,6 +31,10 @@ fn main() {
             "rustc_pattern_analysis",
             "-p",
             "rustc_lexer",
+            "-p",
+            "rustc_abi",
+            "-p",
+            "rustc_parse_format",
         ])
         .run();
 }
diff --git a/tests/rustdoc-ui/deprecated-attrs.rs b/tests/rustdoc-ui/deprecated-attrs.rs
index e4802ee2518..3b59e05a012 100644
--- a/tests/rustdoc-ui/deprecated-attrs.rs
+++ b/tests/rustdoc-ui/deprecated-attrs.rs
@@ -1,16 +1,21 @@
-//@ check-pass
 //@ compile-flags: --passes unknown-pass
 //@ error-pattern: the `passes` flag no longer functions
 
 #![doc(no_default_passes)]
-//~^ WARNING attribute is deprecated
+//~^ ERROR unknown `doc` attribute `no_default_passes`
+//~| NOTE no longer functions
 //~| NOTE see issue #44136
-//~| HELP no longer functions; you may want to use `#![doc(document_private_items)]`
+//~| HELP you may want to use `doc(document_private_items)`
+//~| NOTE `doc(no_default_passes)` is now a no-op
+//~| NOTE `#[deny(invalid_doc_attributes)]` on by default
 #![doc(passes = "collapse-docs unindent-comments")]
-//~^ WARNING attribute is deprecated
+//~^ ERROR unknown `doc` attribute `passes`
+//~| NOTE no longer functions
 //~| NOTE see issue #44136
-//~| HELP no longer functions; you may want to use `#![doc(document_private_items)]`
+//~| HELP you may want to use `doc(document_private_items)`
+//~| NOTE `doc(passes)` is now a no-op
 #![doc(plugins = "xxx")]
-//~^ WARNING attribute is deprecated
+//~^ ERROR unknown `doc` attribute `plugins`
 //~| NOTE see issue #44136
-//~| WARNING no longer functions; see CVE
+//~| NOTE no longer functions
+//~| NOTE `doc(plugins)` is now a no-op
diff --git a/tests/rustdoc-ui/deprecated-attrs.stderr b/tests/rustdoc-ui/deprecated-attrs.stderr
index 45b20ce70ef..a30523e7329 100644
--- a/tests/rustdoc-ui/deprecated-attrs.stderr
+++ b/tests/rustdoc-ui/deprecated-attrs.stderr
@@ -3,32 +3,35 @@ warning: the `passes` flag no longer functions
    = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information
    = help: you may want to use --document-private-items
 
-warning: the `#![doc(no_default_passes)]` attribute is deprecated
-  --> $DIR/deprecated-attrs.rs:5:8
+error: unknown `doc` attribute `no_default_passes`
+  --> $DIR/deprecated-attrs.rs:4:8
    |
 LL | #![doc(no_default_passes)]
-   |        ^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^ no longer functions
    |
-   = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information
-   = help: `#![doc(no_default_passes)]` no longer functions; you may want to use `#![doc(document_private_items)]`
+   = note: `doc` attribute `no_default_passes` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136>
+   = help: you may want to use `doc(document_private_items)`
+   = note: `doc(no_default_passes)` is now a no-op
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
-warning: the `#![doc(passes = "...")]` attribute is deprecated
-  --> $DIR/deprecated-attrs.rs:9:8
+error: unknown `doc` attribute `passes`
+  --> $DIR/deprecated-attrs.rs:11:8
    |
 LL | #![doc(passes = "collapse-docs unindent-comments")]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no longer functions
    |
-   = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information
-   = help: `#![doc(passes = "...")]` no longer functions; you may want to use `#![doc(document_private_items)]`
+   = note: `doc` attribute `passes` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136>
+   = help: you may want to use `doc(document_private_items)`
+   = note: `doc(passes)` is now a no-op
 
-warning: the `#![doc(plugins = "...")]` attribute is deprecated
-  --> $DIR/deprecated-attrs.rs:13:8
+error: unknown `doc` attribute `plugins`
+  --> $DIR/deprecated-attrs.rs:17:8
    |
 LL | #![doc(plugins = "xxx")]
-   |        ^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^ no longer functions
    |
-   = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information
-   = warning: `#![doc(plugins = "...")]` no longer functions; see CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622>
+   = note: `doc` attribute `plugins` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136> and CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622>
+   = note: `doc(plugins)` is now a no-op
 
-warning: 3 warnings emitted
+error: aborting due to 3 previous errors
 
diff --git a/tests/rustdoc-ui/rustc-check-passes.stderr b/tests/rustdoc-ui/rustc-check-passes.stderr
index 58d61c0213e..5b20d1128c5 100644
--- a/tests/rustdoc-ui/rustc-check-passes.stderr
+++ b/tests/rustdoc-ui/rustc-check-passes.stderr
@@ -1,4 +1,4 @@
-error[E0636]: the feature `rustdoc_internals` has already been declared
+error[E0636]: the feature `rustdoc_internals` has already been enabled
   --> $DIR/rustc-check-passes.rs:2:12
    |
 LL | #![feature(rustdoc_internals)]
diff --git a/tests/rustdoc/impossible-default.rs b/tests/rustdoc/impossible-default.rs
index fad64068010..c9444004d5c 100644
--- a/tests/rustdoc/impossible-default.rs
+++ b/tests/rustdoc/impossible-default.rs
@@ -18,3 +18,11 @@ pub trait Foo {
 pub struct Bar([u8]);
 
 impl Foo for Bar {}
+
+//@ has foo/struct.Generic.html '//*[@id="method.needs_sized"]//h4[@class="code-header"]' \
+// "fn needs_sized"
+//@ has foo/struct.Generic.html '//*[@id="method.no_needs_sized"]//h4[@class="code-header"]' \
+// "fn no_needs_sized"
+pub struct Generic<T: ?Sized>(T);
+
+impl<T: ?Sized> Foo for Generic<T> {}
diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr
index 82908ef88a8..81aa200012f 100644
--- a/tests/ui/abi/unsupported.aarch64.stderr
+++ b/tests/ui/abi/unsupported.aarch64.stderr
@@ -105,7 +105,7 @@ LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:170:19
+  --> $DIR/unsupported.rs:165:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -113,18 +113,14 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:183:1
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:178:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:195:21
+  --> $DIR/unsupported.rs:185:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +129,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:203:22
+  --> $DIR/unsupported.rs:193:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -142,7 +138,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:208:1
+  --> $DIR/unsupported.rs:198:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,21 +185,18 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
   --> $DIR/unsupported.rs:159:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:201:1
+  --> $DIR/unsupported.rs:191:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 16 previous errors; 12 warnings emitted
+error: aborting due to 18 previous errors; 10 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr
index 39ec5d16fcd..8e758ee451f 100644
--- a/tests/ui/abi/unsupported.arm.stderr
+++ b/tests/ui/abi/unsupported.arm.stderr
@@ -90,7 +90,7 @@ LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:170:19
+  --> $DIR/unsupported.rs:165:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -98,18 +98,14 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:183:1
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:178:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:195:21
+  --> $DIR/unsupported.rs:185:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,7 +114,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:203:22
+  --> $DIR/unsupported.rs:193:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +123,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:208:1
+  --> $DIR/unsupported.rs:198:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,21 +164,18 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
   --> $DIR/unsupported.rs:159:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:201:1
+  --> $DIR/unsupported.rs:191:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 14 previous errors; 11 warnings emitted
+error: aborting due to 16 previous errors; 9 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr
index 1dc01a66aab..b3c74ad6353 100644
--- a/tests/ui/abi/unsupported.i686.stderr
+++ b/tests/ui/abi/unsupported.i686.stderr
@@ -75,7 +75,7 @@ LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:195:21
+  --> $DIR/unsupported.rs:185:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +84,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:203:22
+  --> $DIR/unsupported.rs:193:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -93,7 +93,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:208:1
+  --> $DIR/unsupported.rs:198:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,7 +129,7 @@ LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:201:1
+  --> $DIR/unsupported.rs:191:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr
index e7d5197feeb..92728b1df18 100644
--- a/tests/ui/abi/unsupported.riscv32.stderr
+++ b/tests/ui/abi/unsupported.riscv32.stderr
@@ -90,7 +90,7 @@ LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:170:19
+  --> $DIR/unsupported.rs:165:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -98,18 +98,14 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:183:1
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:178:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:195:21
+  --> $DIR/unsupported.rs:185:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,7 +114,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:203:22
+  --> $DIR/unsupported.rs:193:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +123,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:208:1
+  --> $DIR/unsupported.rs:198:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,21 +164,18 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
   --> $DIR/unsupported.rs:159:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:201:1
+  --> $DIR/unsupported.rs:191:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 14 previous errors; 11 warnings emitted
+error: aborting due to 16 previous errors; 9 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr
index e7d5197feeb..92728b1df18 100644
--- a/tests/ui/abi/unsupported.riscv64.stderr
+++ b/tests/ui/abi/unsupported.riscv64.stderr
@@ -90,7 +90,7 @@ LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:170:19
+  --> $DIR/unsupported.rs:165:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -98,18 +98,14 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:183:1
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:178:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:195:21
+  --> $DIR/unsupported.rs:185:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,7 +114,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:203:22
+  --> $DIR/unsupported.rs:193:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +123,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:208:1
+  --> $DIR/unsupported.rs:198:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,21 +164,18 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
   --> $DIR/unsupported.rs:159:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:201:1
+  --> $DIR/unsupported.rs:191:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 14 previous errors; 11 warnings emitted
+error: aborting due to 16 previous errors; 9 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs
index 0eb039269a3..a56f001ef95 100644
--- a/tests/ui/abi/unsupported.rs
+++ b/tests/ui/abi/unsupported.rs
@@ -157,16 +157,11 @@ extern "thiscall" {}
 //[riscv64]~^^^^^ ERROR is not a supported ABI
 
 extern "stdcall" fn stdcall() {}
-//[x64]~^ WARN use of calling convention not supported
-//[x64]~^^ WARN this was previously accepted
-//[arm]~^^^ WARN use of calling convention not supported
-//[arm]~^^^^ WARN this was previously accepted
-//[aarch64]~^^^^^ WARN use of calling convention not supported
-//[aarch64]~^^^^^^ WARN this was previously accepted
-//[riscv32]~^^^^^^^ WARN use of calling convention not supported
-//[riscv32]~^^^^^^^^ WARN this was previously accepted
-//[riscv64]~^^^^^^^^^ WARN use of calling convention not supported
-//[riscv64]~^^^^^^^^^^ WARN this was previously accepted
+//[x64]~^ ERROR is not a supported ABI
+//[arm]~^^ ERROR is not a supported ABI
+//[aarch64]~^^^ ERROR is not a supported ABI
+//[riscv32]~^^^^ ERROR is not a supported ABI
+//[riscv64]~^^^^^ ERROR is not a supported ABI
 fn stdcall_ptr(f: extern "stdcall" fn()) {
     //[x64]~^ WARN unsupported_fn_ptr_calling_conventions
     //[x64]~^^ WARN this was previously accepted
@@ -181,16 +176,11 @@ fn stdcall_ptr(f: extern "stdcall" fn()) {
     f()
 }
 extern "stdcall" {}
-//[x64]~^ WARN use of calling convention not supported
-//[x64]~^^ WARN this was previously accepted
-//[arm]~^^^ WARN use of calling convention not supported
-//[arm]~^^^^ WARN this was previously accepted
-//[aarch64]~^^^^^ WARN use of calling convention not supported
-//[aarch64]~^^^^^^ WARN this was previously accepted
-//[riscv32]~^^^^^^^ WARN use of calling convention not supported
-//[riscv32]~^^^^^^^^ WARN this was previously accepted
-//[riscv64]~^^^^^^^^^ WARN use of calling convention not supported
-//[riscv64]~^^^^^^^^^^ WARN this was previously accepted
+//[x64]~^ ERROR is not a supported ABI
+//[arm]~^^ ERROR is not a supported ABI
+//[aarch64]~^^^ ERROR is not a supported ABI
+//[riscv32]~^^^^ ERROR is not a supported ABI
+//[riscv64]~^^^^^ ERROR is not a supported ABI
 
 fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
     //~^ WARN unsupported_fn_ptr_calling_conventions
diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr
index bbca754dd41..27a4f1f532c 100644
--- a/tests/ui/abi/unsupported.x64.stderr
+++ b/tests/ui/abi/unsupported.x64.stderr
@@ -90,7 +90,7 @@ LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:170:19
+  --> $DIR/unsupported.rs:165:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -98,18 +98,14 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:183:1
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:178:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:195:21
+  --> $DIR/unsupported.rs:185:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,7 +114,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:203:22
+  --> $DIR/unsupported.rs:193:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +123,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:208:1
+  --> $DIR/unsupported.rs:198:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,21 +164,18 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target
+error[E0570]: `"stdcall"` is not a supported ABI for the current target
   --> $DIR/unsupported.rs:159:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:201:1
+  --> $DIR/unsupported.rs:191:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 14 previous errors; 11 warnings emitted
+error: aborting due to 16 previous errors; 9 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/argument-suggestions/issue-109425.fixed b/tests/ui/argument-suggestions/issue-109425.fixed
index 5d96f457c88..4b3aaa46d86 100644
--- a/tests/ui/argument-suggestions/issue-109425.fixed
+++ b/tests/ui/argument-suggestions/issue-109425.fixed
@@ -15,6 +15,10 @@ fn main() {
     //~^ error: this function takes 1 argument but 3 arguments were supplied
     is(0, ""); // is(0, "")
     //~^ error: this function takes 2 arguments but 4 arguments were supplied
+    is(1, "");
+    //~^ error: this function takes 2 arguments but 4 arguments were supplied
+    is(1, "");
+    //~^ error: this function takes 2 arguments but 4 arguments were supplied
     s("");     // s("")
     //~^ error: this function takes 1 argument but 3 arguments were supplied
 }
diff --git a/tests/ui/argument-suggestions/issue-109425.rs b/tests/ui/argument-suggestions/issue-109425.rs
index bb9d37ee0ff..56816681337 100644
--- a/tests/ui/argument-suggestions/issue-109425.rs
+++ b/tests/ui/argument-suggestions/issue-109425.rs
@@ -15,6 +15,10 @@ fn main() {
     //~^ error: this function takes 1 argument but 3 arguments were supplied
     is(0, 1, 2, ""); // is(0, "")
     //~^ error: this function takes 2 arguments but 4 arguments were supplied
+    is((), 1, "", ());
+    //~^ error: this function takes 2 arguments but 4 arguments were supplied
+    is(1, (), "", ());
+    //~^ error: this function takes 2 arguments but 4 arguments were supplied
     s(0, 1, "");     // s("")
     //~^ error: this function takes 1 argument but 3 arguments were supplied
 }
diff --git a/tests/ui/argument-suggestions/issue-109425.stderr b/tests/ui/argument-suggestions/issue-109425.stderr
index bfe007793d4..2cd53ed528e 100644
--- a/tests/ui/argument-suggestions/issue-109425.stderr
+++ b/tests/ui/argument-suggestions/issue-109425.stderr
@@ -74,9 +74,47 @@ LL -     is(0, 1, 2, ""); // is(0, "")
 LL +     is(0, ""); // is(0, "")
    |
 
-error[E0061]: this function takes 1 argument but 3 arguments were supplied
+error[E0061]: this function takes 2 arguments but 4 arguments were supplied
   --> $DIR/issue-109425.rs:18:5
    |
+LL |     is((), 1, "", ());
+   |     ^^ --         -- unexpected argument #4 of type `()`
+   |        |
+   |        unexpected argument #1 of type `()`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:5:4
+   |
+LL | fn is(_: u32, _: &str) {}
+   |    ^^ ------  -------
+help: remove the extra arguments
+   |
+LL -     is((), 1, "", ());
+LL +     is(1, "");
+   |
+
+error[E0061]: this function takes 2 arguments but 4 arguments were supplied
+  --> $DIR/issue-109425.rs:20:5
+   |
+LL |     is(1, (), "", ());
+   |     ^^    --      -- unexpected argument #4 of type `()`
+   |           |
+   |           unexpected argument #2 of type `()`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:5:4
+   |
+LL | fn is(_: u32, _: &str) {}
+   |    ^^ ------  -------
+help: remove the extra arguments
+   |
+LL -     is(1, (), "", ());
+LL +     is(1, "");
+   |
+
+error[E0061]: this function takes 1 argument but 3 arguments were supplied
+  --> $DIR/issue-109425.rs:22:5
+   |
 LL |     s(0, 1, "");     // s("")
    |     ^ -  - unexpected argument #2 of type `{integer}`
    |       |
@@ -93,6 +131,6 @@ LL -     s(0, 1, "");     // s("")
 LL +     s("");     // s("")
    |
 
-error: aborting due to 5 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0061`.
diff --git a/tests/ui/argument-suggestions/issue-112507.stderr b/tests/ui/argument-suggestions/issue-112507.stderr
index 908ed35c669..e2ea9af7dc2 100644
--- a/tests/ui/argument-suggestions/issue-112507.stderr
+++ b/tests/ui/argument-suggestions/issue-112507.stderr
@@ -18,8 +18,9 @@ LL |     Float(Option<f64>),
    |     ^^^^^
 help: remove the extra arguments
    |
-LL ~         ,
-LL ~         None);
+LL -         0,
+LL -         None,
+LL +         None);
    |
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/async-await/field-in-sync.rs b/tests/ui/async-await/field-in-sync.rs
new file mode 100644
index 00000000000..586980c6e2b
--- /dev/null
+++ b/tests/ui/async-await/field-in-sync.rs
@@ -0,0 +1,13 @@
+//@ edition: 2021
+
+struct S {
+    field: (),
+}
+
+async fn foo() -> S { todo!() }
+
+fn main() -> Result<(), ()> {
+    foo().field;
+    //~^ ERROR no field `field` on type `impl Future<Output = S>`
+    Ok(())
+}
diff --git a/tests/ui/async-await/field-in-sync.stderr b/tests/ui/async-await/field-in-sync.stderr
new file mode 100644
index 00000000000..7be30339c27
--- /dev/null
+++ b/tests/ui/async-await/field-in-sync.stderr
@@ -0,0 +1,17 @@
+error[E0609]: no field `field` on type `impl Future<Output = S>`
+  --> $DIR/field-in-sync.rs:10:11
+   |
+LL |     foo().field;
+   |           ^^^^^ field not available in `impl Future`, but it is available in its `Output`
+   |
+note: this implements `Future` and its output type has the field, but the future cannot be awaited in a synchronous function
+  --> $DIR/field-in-sync.rs:10:5
+   |
+LL | fn main() -> Result<(), ()> {
+   | --------------------------- this is not `async`
+LL |     foo().field;
+   |     ^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/tests/ui/async-await/issue-61076.stderr b/tests/ui/async-await/issue-61076.stderr
index 44de282988b..b8478c8d138 100644
--- a/tests/ui/async-await/issue-61076.stderr
+++ b/tests/ui/async-await/issue-61076.stderr
@@ -28,7 +28,7 @@ error[E0609]: no field `0` on type `impl Future<Output = Tuple>`
 LL |     let _: i32 = tuple().0;
    |                          ^ field not available in `impl Future`, but it is available in its `Output`
    |
-help: consider `await`ing on the `Future` and access the field of its `Output`
+help: consider `await`ing on the `Future` to access the field
    |
 LL |     let _: i32 = tuple().await.0;
    |                         ++++++
@@ -39,7 +39,7 @@ error[E0609]: no field `a` on type `impl Future<Output = Struct>`
 LL |     let _: i32 = struct_().a;
    |                            ^ field not available in `impl Future`, but it is available in its `Output`
    |
-help: consider `await`ing on the `Future` and access the field of its `Output`
+help: consider `await`ing on the `Future` to access the field
    |
 LL |     let _: i32 = struct_().await.a;
    |                           ++++++
diff --git a/tests/ui/async-await/try-in-sync.rs b/tests/ui/async-await/try-in-sync.rs
new file mode 100644
index 00000000000..81d72c3fb9a
--- /dev/null
+++ b/tests/ui/async-await/try-in-sync.rs
@@ -0,0 +1,9 @@
+//@ edition: 2021
+
+async fn foo() -> Result<(), ()> { todo!() }
+
+fn main() -> Result<(), ()> {
+    foo()?;
+    //~^ ERROR the `?` operator can only be applied to values that implement `Try`
+    Ok(())
+}
diff --git a/tests/ui/async-await/try-in-sync.stderr b/tests/ui/async-await/try-in-sync.stderr
new file mode 100644
index 00000000000..bc7a6bd0151
--- /dev/null
+++ b/tests/ui/async-await/try-in-sync.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+  --> $DIR/try-in-sync.rs:6:5
+   |
+LL |     foo()?;
+   |     ^^^^^^ the `?` operator cannot be applied to type `impl Future<Output = Result<(), ()>>`
+   |
+   = help: the trait `Try` is not implemented for `impl Future<Output = Result<(), ()>>`
+note: this implements `Future` and its output type supports `?`, but the future cannot be awaited in a synchronous function
+  --> $DIR/try-in-sync.rs:6:10
+   |
+LL | fn main() -> Result<(), ()> {
+   | --------------------------- this is not `async`
+LL |     foo()?;
+   |          ^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/attributes/optimize.rs b/tests/ui/attributes/optimize.rs
index b01806165c1..7a1cc1be9ee 100644
--- a/tests/ui/attributes/optimize.rs
+++ b/tests/ui/attributes/optimize.rs
@@ -3,11 +3,13 @@
 #![deny(unused_attributes)]
 #![allow(dead_code)]
 
-#[optimize(speed)] //~ ERROR attribute should be applied to function or closure
+//@ edition: 2018
+
+#[optimize(speed)] //~ ERROR attribute applied to an invalid target
 struct F;
 
 fn invalid() {
-    #[optimize(speed)] //~ ERROR attribute should be applied to function or closure
+    #[optimize(speed)] //~ ERROR attribute applied to an invalid target
     {
         1
     };
@@ -16,13 +18,25 @@ fn invalid() {
 #[optimize(speed)]
 fn valid() {}
 
-#[optimize(speed)]
+#[optimize(speed)] //~ ERROR attribute applied to an invalid target
 mod valid_module {}
 
-#[optimize(speed)]
+#[optimize(speed)] //~ ERROR attribute applied to an invalid target
 impl F {}
 
 fn main() {
     let _ = #[optimize(speed)]
     (|| 1);
 }
+
+use std::future::Future;
+
+fn async_block() -> impl Future<Output = ()> {
+    #[optimize(speed)]
+    async { }
+}
+
+#[optimize(speed)]
+async fn async_fn() {
+    ()
+}
diff --git a/tests/ui/attributes/optimize.stderr b/tests/ui/attributes/optimize.stderr
index 3c445d73c2e..ad9309d27a5 100644
--- a/tests/ui/attributes/optimize.stderr
+++ b/tests/ui/attributes/optimize.stderr
@@ -1,20 +1,36 @@
-error: attribute should be applied to function or closure
-  --> $DIR/optimize.rs:6:1
+error: attribute applied to an invalid target
+  --> $DIR/optimize.rs:8:1
    |
 LL | #[optimize(speed)]
    | ^^^^^^^^^^^^^^^^^^
+LL | struct F;
+   | --------- invalid target
+
+error: attribute applied to an invalid target
+  --> $DIR/optimize.rs:12:5
    |
-note: the lint level is defined here
-  --> $DIR/optimize.rs:3:9
+LL |       #[optimize(speed)]
+   |       ^^^^^^^^^^^^^^^^^^
+LL | /     {
+LL | |         1
+LL | |     };
+   | |_____- invalid target
+
+error: attribute applied to an invalid target
+  --> $DIR/optimize.rs:21:1
    |
-LL | #![deny(unused_attributes)]
-   |         ^^^^^^^^^^^^^^^^^
+LL | #[optimize(speed)]
+   | ^^^^^^^^^^^^^^^^^^
+LL | mod valid_module {}
+   | ------------------- invalid target
 
-error: attribute should be applied to function or closure
-  --> $DIR/optimize.rs:10:5
+error: attribute applied to an invalid target
+  --> $DIR/optimize.rs:24:1
    |
-LL |     #[optimize(speed)]
-   |     ^^^^^^^^^^^^^^^^^^
+LL | #[optimize(speed)]
+   | ^^^^^^^^^^^^^^^^^^
+LL | impl F {}
+   | --------- invalid target
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/closures/issue-111932.stderr b/tests/ui/closures/issue-111932.stderr
index ff46b10d005..93488ad2011 100644
--- a/tests/ui/closures/issue-111932.stderr
+++ b/tests/ui/closures/issue-111932.stderr
@@ -17,7 +17,7 @@ LL |         println!("{:?}", foo);
    |                   required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `dyn Foo`
-note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'a>::new_debug`
+note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'_>::new_debug`
   --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
index 0c9df7ecd78..b2b4934aa5f 100644
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
@@ -2,8 +2,6 @@
 //@ compile-flags: -Copt-level=2
 //@ run-pass
 
-#![feature(exposed_provenance)]
-
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
index b188b794d1f..bf130c9f759 100644
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
@@ -4,8 +4,6 @@
 
 // Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908
 
-#![feature(exposed_provenance)]
-
 use std::ptr;
 
 fn f() -> usize {
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
index 7f64e23b9c1..cdf07eade87 100644
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
@@ -4,8 +4,6 @@
 
 // Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
 
-#![feature(exposed_provenance)]
-
 use std::ptr;
 
 #[inline(never)]
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
index 3417296ce12..f128e1bb084 100644
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
@@ -4,8 +4,6 @@
 
 // Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
 
-#![feature(exposed_provenance)]
-
 use std::ptr;
 
 #[inline(never)]
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
index e1e9e3f46b8..0baf8886395 100644
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
@@ -4,8 +4,6 @@
 
 // https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
 
-#![feature(exposed_provenance)]
-
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
index 8d581e8c9e9..c7f46318aae 100644
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
@@ -4,8 +4,6 @@
 
 // https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
 
-#![feature(exposed_provenance)]
-
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
index 506f114cd2a..b163c282d93 100644
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
@@ -4,8 +4,6 @@
 
 // https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
 
-#![feature(exposed_provenance)]
-
 use std::{
     cell::{Ref, RefCell},
     ptr,
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
index 603db5e08f4..7ccff8d0848 100644
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
@@ -4,8 +4,6 @@
 
 // Derived from https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
 
-#![feature(exposed_provenance)]
-
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
index 0243c2bfe95..4602ec654d1 100644
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
@@ -2,8 +2,6 @@
 //@ compile-flags: -Copt-level=2
 //@ run-pass
 
-#![feature(strict_provenance)]
-
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
index 29758036a21..789a78c15b4 100644
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
@@ -4,8 +4,6 @@
 
 // Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908
 
-#![feature(strict_provenance)]
-
 use std::ptr;
 
 fn f() -> usize {
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
index 11925261a65..5f4ee731f7d 100644
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
@@ -4,8 +4,6 @@
 
 // Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
 
-#![feature(strict_provenance)]
-
 use std::ptr;
 
 #[inline(never)]
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
index e628bb90faa..0414879804a 100644
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
@@ -4,8 +4,6 @@
 
 // Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
 
-#![feature(strict_provenance)]
-
 use std::ptr;
 
 #[inline(never)]
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
index 075e3475a32..b7165ce1e5c 100644
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
@@ -4,8 +4,6 @@
 
 // https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
 
-#![feature(strict_provenance)]
-
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
index 6d7b6fa33e0..a02ff30918d 100644
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
@@ -4,8 +4,6 @@
 
 // https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
 
-#![feature(strict_provenance)]
-
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
index 67660d285a4..fea41e03612 100644
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
@@ -4,8 +4,6 @@
 
 // https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
 
-#![feature(strict_provenance)]
-
 use std::{
     cell::{Ref, RefCell},
     ptr,
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs
index a89310f9930..d963e45e4cd 100644
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs
@@ -4,8 +4,6 @@
 
 // Derived from https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
 
-#![feature(strict_provenance)]
-
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr
index 9a6374a2adc..4ab80cec58d 100644
--- a/tests/ui/const-generics/infer/issue-77092.stderr
+++ b/tests/ui/const-generics/infer/issue-77092.stderr
@@ -25,7 +25,7 @@ LL |         println!("{:?}", take_array_from_mut(&mut arr, i));
    = note: required for `[i32; _]` to implement `Debug`
    = note: 1 redundant requirement hidden
    = note: required for `&mut [i32; _]` to implement `Debug`
-note: required by a bound in `core::fmt::rt::Argument::<'a>::new_debug`
+note: required by a bound in `core::fmt::rt::Argument::<'_>::new_debug`
   --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
 help: consider specifying the generic arguments
    |
diff --git a/tests/ui/coroutine/other-attribute-on-gen.rs b/tests/ui/coroutine/other-attribute-on-gen.rs
new file mode 100644
index 00000000000..0f26dc6860d
--- /dev/null
+++ b/tests/ui/coroutine/other-attribute-on-gen.rs
@@ -0,0 +1,40 @@
+//@ edition: 2024
+//@ compile-flags: -Zunstable-options
+//@ run-pass
+#![feature(gen_blocks)]
+#![feature(optimize_attribute)]
+#![feature(stmt_expr_attributes)]
+#![feature(async_iterator)]
+#![allow(dead_code)]
+
+// make sure that other attributes e.g. `optimize` can be applied to gen blocks and functions
+
+fn main() { }
+
+fn optimize_gen_block() -> impl Iterator<Item = ()> {
+    #[optimize(speed)]
+    gen { yield (); }
+}
+
+#[optimize(speed)]
+gen fn optimize_gen_fn() -> i32 {
+    yield 1;
+    yield 2;
+    yield 3;
+}
+
+#[optimize(speed)]
+async gen fn optimize_async_gen_fn() -> i32 {
+    yield 1;
+    yield 2;
+    yield 3;
+}
+
+use std::async_iter::AsyncIterator;
+
+pub fn deduce() -> impl AsyncIterator<Item = ()> {
+    #[optimize(size)]
+    async gen {
+        yield ();
+    }
+}
diff --git a/tests/ui/feature-gates/duplicate-features.rs b/tests/ui/feature-gates/duplicate-features.rs
index d8f7818054a..1fae71c3eb2 100644
--- a/tests/ui/feature-gates/duplicate-features.rs
+++ b/tests/ui/feature-gates/duplicate-features.rs
@@ -1,9 +1,9 @@
 #![allow(stable_features)]
 
 #![feature(rust1)]
-#![feature(rust1)] //~ ERROR the feature `rust1` has already been declared
+#![feature(rust1)] //~ ERROR the feature `rust1` has already been enabled
 
 #![feature(if_let)]
-#![feature(if_let)] //~ ERROR the feature `if_let` has already been declared
+#![feature(if_let)] //~ ERROR the feature `if_let` has already been enabled
 
 fn main() {}
diff --git a/tests/ui/feature-gates/duplicate-features.stderr b/tests/ui/feature-gates/duplicate-features.stderr
index dbde806f6cc..f667a5b9623 100644
--- a/tests/ui/feature-gates/duplicate-features.stderr
+++ b/tests/ui/feature-gates/duplicate-features.stderr
@@ -1,10 +1,10 @@
-error[E0636]: the feature `if_let` has already been declared
+error[E0636]: the feature `if_let` has already been enabled
   --> $DIR/duplicate-features.rs:7:12
    |
 LL | #![feature(if_let)]
    |            ^^^^^^
 
-error[E0636]: the feature `rust1` has already been declared
+error[E0636]: the feature `rust1` has already been enabled
   --> $DIR/duplicate-features.rs:4:12
    |
 LL | #![feature(rust1)]
diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
index 15aa3a6af4c..7f9cada6a47 100644
--- a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
+++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
@@ -1,8 +1,4 @@
 #![crate_type="rlib"]
-#![optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature
-
-#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature
-mod module {
 
 #[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 fn size() {}
@@ -14,5 +10,3 @@ fn speed() {}
 //~^ ERROR the `#[optimize]` attribute is an experimental feature
 //~| ERROR E0722
 fn not_known() {}
-
-}
diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
index 609526150ba..ca8f4a078f0 100644
--- a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
+++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
@@ -1,25 +1,5 @@
 error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:2:1
-   |
-LL | #![optimize(speed)]
-   | ^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
-   = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:4:1
-   |
-LL | #[optimize(size)]
-   | ^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
-   = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:7:1
+  --> $DIR/feature-gate-optimize_attribute.rs:3:1
    |
 LL | #[optimize(size)]
    | ^^^^^^^^^^^^^^^^^
@@ -29,7 +9,7 @@ LL | #[optimize(size)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:10:1
+  --> $DIR/feature-gate-optimize_attribute.rs:6:1
    |
 LL | #[optimize(speed)]
    | ^^^^^^^^^^^^^^^^^^
@@ -39,7 +19,7 @@ LL | #[optimize(speed)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:13:1
+  --> $DIR/feature-gate-optimize_attribute.rs:9:1
    |
 LL | #[optimize(banana)]
    | ^^^^^^^^^^^^^^^^^^^
@@ -49,12 +29,12 @@ LL | #[optimize(banana)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0722]: invalid argument
-  --> $DIR/feature-gate-optimize_attribute.rs:13:12
+  --> $DIR/feature-gate-optimize_attribute.rs:9:12
    |
 LL | #[optimize(banana)]
    |            ^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0658, E0722.
 For more information about an error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs b/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs
deleted file mode 100644
index dda317aecc3..00000000000
--- a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-#![allow(dead_code)]
-#![deny(improper_ctypes)]
-#![feature(ptr_internals)]
-
-use std::num;
-
-enum Z {}
-
-#[repr(transparent)]
-struct TransparentStruct<T>(T, std::marker::PhantomData<Z>);
-
-#[repr(transparent)]
-enum TransparentEnum<T> {
-    Variant(T, std::marker::PhantomData<Z>),
-}
-
-struct NoField;
-
-extern "C" {
-    fn result_ref_t(x: Result<&'static u8, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_fn_t(x: Result<extern "C" fn(), ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonnull_t(x: Result<std::ptr::NonNull<u8>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_unique_t(x: Result<std::ptr::Unique<u8>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_u8_t(x: Result<num::NonZero<u8>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_u16_t(x: Result<num::NonZero<u16>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_u32_t(x: Result<num::NonZero<u32>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_u64_t(x: Result<num::NonZero<u64>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_usize_t(x: Result<num::NonZero<usize>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_i8_t(x: Result<num::NonZero<i8>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_i16_t(x: Result<num::NonZero<i16>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_i32_t(x: Result<num::NonZero<i32>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_i64_t(x: Result<num::NonZero<i64>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_isize_t(x: Result<num::NonZero<isize>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_transparent_struct_t(x: Result<TransparentStruct<num::NonZero<u8>>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_transparent_enum_t(x: Result<TransparentEnum<num::NonZero<u8>>, ()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_phantom_t(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_1zst_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, Z>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_1zst_exhaustive_no_field_t(x: Result<num::NonZero<u8>, NoField>);
-    //~^ ERROR `extern` block uses type `Result
-
-    fn result_ref_e(x: Result<(), &'static u8>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_fn_e(x: Result<(), extern "C" fn()>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonnull_e(x: Result<(), std::ptr::NonNull<u8>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_unique_e(x: Result<(), std::ptr::Unique<u8>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_u8_e(x: Result<(), num::NonZero<u8>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_u16_e(x: Result<(), num::NonZero<u16>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_u32_e(x: Result<(), num::NonZero<u32>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_u64_e(x: Result<(), num::NonZero<u64>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_usize_e(x: Result<(), num::NonZero<usize>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_i8_e(x: Result<(), num::NonZero<i8>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_i16_e(x: Result<(), num::NonZero<i16>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_i32_e(x: Result<(), num::NonZero<i32>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_i64_e(x: Result<(), num::NonZero<i64>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_nonzero_isize_e(x: Result<(), num::NonZero<isize>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_transparent_struct_e(x: Result<(), TransparentStruct<num::NonZero<u8>>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_transparent_enum_e(x: Result<(), TransparentEnum<num::NonZero<u8>>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_phantom_e(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_1zst_exhaustive_no_variant_e(x: Result<Z, num::NonZero<u8>>);
-    //~^ ERROR `extern` block uses type `Result
-    fn result_1zst_exhaustive_no_field_e(x: Result<NoField, num::NonZero<u8>>);
-    //~^ ERROR `extern` block uses type `Result
-}
-
-pub fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr b/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr
deleted file mode 100644
index 94416eb99c8..00000000000
--- a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr
+++ /dev/null
@@ -1,349 +0,0 @@
-error: `extern` block uses type `Result<&u8, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:20:24
-   |
-LL |     fn result_ref_t(x: Result<&'static u8, ()>);
-   |                        ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-note: the lint level is defined here
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:2:9
-   |
-LL | #![deny(improper_ctypes)]
-   |         ^^^^^^^^^^^^^^^
-
-error: `extern` block uses type `Result<extern "C" fn(), ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:22:23
-   |
-LL |     fn result_fn_t(x: Result<extern "C" fn(), ()>);
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonNull<u8>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:24:28
-   |
-LL |     fn result_nonnull_t(x: Result<std::ptr::NonNull<u8>, ()>);
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<Unique<u8>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:26:27
-   |
-LL |     fn result_unique_t(x: Result<std::ptr::Unique<u8>, ()>);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<u8>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:28:31
-   |
-LL |     fn result_nonzero_u8_t(x: Result<num::NonZero<u8>, ()>);
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<u16>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:30:32
-   |
-LL |     fn result_nonzero_u16_t(x: Result<num::NonZero<u16>, ()>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<u32>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:32:32
-   |
-LL |     fn result_nonzero_u32_t(x: Result<num::NonZero<u32>, ()>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<u64>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:34:32
-   |
-LL |     fn result_nonzero_u64_t(x: Result<num::NonZero<u64>, ()>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<usize>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:36:34
-   |
-LL |     fn result_nonzero_usize_t(x: Result<num::NonZero<usize>, ()>);
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<i8>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:38:31
-   |
-LL |     fn result_nonzero_i8_t(x: Result<num::NonZero<i8>, ()>);
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<i16>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:40:32
-   |
-LL |     fn result_nonzero_i16_t(x: Result<num::NonZero<i16>, ()>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<i32>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:42:32
-   |
-LL |     fn result_nonzero_i32_t(x: Result<num::NonZero<i32>, ()>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<i64>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:44:32
-   |
-LL |     fn result_nonzero_i64_t(x: Result<num::NonZero<i64>, ()>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<isize>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:46:34
-   |
-LL |     fn result_nonzero_isize_t(x: Result<num::NonZero<isize>, ()>);
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<TransparentStruct<NonZero<u8>>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:48:39
-   |
-LL |     fn result_transparent_struct_t(x: Result<TransparentStruct<num::NonZero<u8>>, ()>);
-   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<TransparentEnum<NonZero<u8>>, ()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:50:37
-   |
-LL |     fn result_transparent_enum_t(x: Result<TransparentEnum<num::NonZero<u8>>, ()>);
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<u8>, PhantomData<()>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:52:28
-   |
-LL |     fn result_phantom_t(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<u8>, Z>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:54:47
-   |
-LL |     fn result_1zst_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, Z>);
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<u8>, NoField>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:56:45
-   |
-LL |     fn result_1zst_exhaustive_no_field_t(x: Result<num::NonZero<u8>, NoField>);
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), &u8>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:59:24
-   |
-LL |     fn result_ref_e(x: Result<(), &'static u8>);
-   |                        ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), extern "C" fn()>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:61:23
-   |
-LL |     fn result_fn_e(x: Result<(), extern "C" fn()>);
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonNull<u8>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:63:28
-   |
-LL |     fn result_nonnull_e(x: Result<(), std::ptr::NonNull<u8>>);
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), Unique<u8>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:65:27
-   |
-LL |     fn result_unique_e(x: Result<(), std::ptr::Unique<u8>>);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<u8>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:67:31
-   |
-LL |     fn result_nonzero_u8_e(x: Result<(), num::NonZero<u8>>);
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<u16>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:69:32
-   |
-LL |     fn result_nonzero_u16_e(x: Result<(), num::NonZero<u16>>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<u32>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:71:32
-   |
-LL |     fn result_nonzero_u32_e(x: Result<(), num::NonZero<u32>>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<u64>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:73:32
-   |
-LL |     fn result_nonzero_u64_e(x: Result<(), num::NonZero<u64>>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<usize>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:75:34
-   |
-LL |     fn result_nonzero_usize_e(x: Result<(), num::NonZero<usize>>);
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<i8>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:77:31
-   |
-LL |     fn result_nonzero_i8_e(x: Result<(), num::NonZero<i8>>);
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<i16>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:79:32
-   |
-LL |     fn result_nonzero_i16_e(x: Result<(), num::NonZero<i16>>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<i32>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:81:32
-   |
-LL |     fn result_nonzero_i32_e(x: Result<(), num::NonZero<i32>>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<i64>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:83:32
-   |
-LL |     fn result_nonzero_i64_e(x: Result<(), num::NonZero<i64>>);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), NonZero<isize>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:85:34
-   |
-LL |     fn result_nonzero_isize_e(x: Result<(), num::NonZero<isize>>);
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), TransparentStruct<NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:87:39
-   |
-LL |     fn result_transparent_struct_e(x: Result<(), TransparentStruct<num::NonZero<u8>>>);
-   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<(), TransparentEnum<NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:89:37
-   |
-LL |     fn result_transparent_enum_e(x: Result<(), TransparentEnum<num::NonZero<u8>>>);
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NonZero<u8>, PhantomData<()>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:91:28
-   |
-LL |     fn result_phantom_e(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<Z, NonZero<u8>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:93:47
-   |
-LL |     fn result_1zst_exhaustive_no_variant_e(x: Result<Z, num::NonZero<u8>>);
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: `extern` block uses type `Result<NoField, NonZero<u8>>`, which is not FFI-safe
-  --> $DIR/feature-gate-result_ffi_guarantees.rs:95:45
-   |
-LL |     fn result_1zst_exhaustive_no_field_e(x: Result<NoField, num::NonZero<u8>>);
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
-error: aborting due to 38 previous errors
-
diff --git a/tests/ui/feature-gates/feature-gate-strict_provenance.rs b/tests/ui/feature-gates/feature-gate-strict_provenance_lints.rs
index 738c8daa168..738c8daa168 100644
--- a/tests/ui/feature-gates/feature-gate-strict_provenance.rs
+++ b/tests/ui/feature-gates/feature-gate-strict_provenance_lints.rs
diff --git a/tests/ui/feature-gates/feature-gate-strict_provenance.stderr b/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr
index 82078d576ad..15428cbd4be 100644
--- a/tests/ui/feature-gates/feature-gate-strict_provenance.stderr
+++ b/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr
@@ -1,24 +1,24 @@
 warning: unknown lint: `fuzzy_provenance_casts`
-  --> $DIR/feature-gate-strict_provenance.rs:3:1
+  --> $DIR/feature-gate-strict_provenance_lints.rs:3:1
    |
 LL | #![deny(fuzzy_provenance_casts)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the `fuzzy_provenance_casts` lint is unstable
-   = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
-   = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+   = note: see issue #130351 <https://github.com/rust-lang/rust/issues/130351> for more information
+   = help: add `#![feature(strict_provenance_lints)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = note: `#[warn(unknown_lints)]` on by default
 
 warning: unknown lint: `lossy_provenance_casts`
-  --> $DIR/feature-gate-strict_provenance.rs:5:1
+  --> $DIR/feature-gate-strict_provenance_lints.rs:5:1
    |
 LL | #![deny(lossy_provenance_casts)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the `lossy_provenance_casts` lint is unstable
-   = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
-   = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+   = note: see issue #130351 <https://github.com/rust-lang/rust/issues/130351> for more information
+   = help: add `#![feature(strict_provenance_lints)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 warning: 2 warnings emitted
diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr
index a22bba07c02..f83e7c87728 100644
--- a/tests/ui/fmt/ifmt-unimpl.stderr
+++ b/tests/ui/fmt/ifmt-unimpl.stderr
@@ -17,7 +17,7 @@ LL |     format!("{:X}", "3");
              i32
            and 9 others
    = note: required for `&str` to implement `UpperHex`
-note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex`
+note: required by a bound in `core::fmt::rt::Argument::<'_>::new_upper_hex`
   --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
    = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr b/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr
new file mode 100644
index 00000000000..8fc04adf57f
--- /dev/null
+++ b/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr
@@ -0,0 +1,4 @@
+error: `-Zregparm=4` is unsupported (valid values 0-3)
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs b/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs
new file mode 100644
index 00000000000..b548d678520
--- /dev/null
+++ b/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs
@@ -0,0 +1,24 @@
+//@ revisions: regparm0 regparm1 regparm2 regparm3 regparm4
+
+//@ needs-llvm-components: x86
+//@ compile-flags: --target i686-unknown-linux-gnu
+
+//@[regparm0] check-pass
+//@[regparm0] compile-flags: -Zregparm=0
+
+//@[regparm1] check-pass
+//@[regparm1] compile-flags: -Zregparm=1
+
+//@[regparm2] check-pass
+//@[regparm2] compile-flags: -Zregparm=2
+
+//@[regparm3] check-pass
+//@[regparm3] compile-flags: -Zregparm=3
+
+//@[regparm4] check-fail
+//@[regparm4] compile-flags: -Zregparm=4
+//@[regparm4] error-pattern: `-Zregparm=4` is unsupported (valid values 0-3)
+
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr b/tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr
new file mode 100644
index 00000000000..2433519f803
--- /dev/null
+++ b/tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr
@@ -0,0 +1,4 @@
+error: `-Zregparm=N` is only supported on x86
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.rs b/tests/ui/invalid-compile-flags/regparm/requires-x86.rs
new file mode 100644
index 00000000000..ce6e437fb47
--- /dev/null
+++ b/tests/ui/invalid-compile-flags/regparm/requires-x86.rs
@@ -0,0 +1,21 @@
+//@ revisions: x86 x86_64 aarch64
+
+//@ compile-flags: -Zregparm=3
+
+//@[x86] check-pass
+//@[x86] needs-llvm-components: x86
+//@[x86] compile-flags: --target i686-unknown-linux-gnu
+
+//@[x86_64] check-fail
+//@[x86_64] needs-llvm-components: x86
+//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
+//@[x86_64] error-pattern: `-Zregparm=N` is only supported on x86
+
+//@[aarch64] check-fail
+//@[aarch64] needs-llvm-components: aarch64
+//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64] error-pattern: `-Zregparm=N` is only supported on x86
+
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr b/tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr
new file mode 100644
index 00000000000..2433519f803
--- /dev/null
+++ b/tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr
@@ -0,0 +1,4 @@
+error: `-Zregparm=N` is only supported on x86
+
+error: aborting due to 1 previous error
+
diff --git a/tests/crashes/126966.rs b/tests/ui/layout/thaw-transmute-invalid-enum.rs
index 2c9f1a70f4f..835dcc04996 100644
--- a/tests/crashes/126966.rs
+++ b/tests/ui/layout/thaw-transmute-invalid-enum.rs
@@ -1,10 +1,14 @@
-//@ known-bug: rust-lang/rust#126966
+#![crate_type = "lib"]
+
 mod assert {
     use std::mem::{Assume, TransmuteFrom};
+    //~^ ERROR: use of unstable library feature 'transmutability'
+    //~| ERROR: use of unstable library feature 'transmutability'
 
     pub fn is_transmutable<Src, Dst>()
     where
         Dst: TransmuteFrom<Src>,
+        //~^ ERROR: use of unstable library feature 'transmutability'
     {
     }
 }
@@ -15,6 +19,7 @@ enum Ox00 {
 }
 
 #[repr(C, packed(2))]
+//~^ ERROR: attribute should be applied to a struct
 enum OxFF {
     V = 0xFF,
 }
@@ -22,8 +27,10 @@ enum OxFF {
 fn test() {
     union Superset {
         a: Ox00,
+        //~^ ERROR: field must implement `Copy`
         b: OxFF,
     }
 
     assert::is_transmutable::<Superset, Subset>();
+    //~^ ERROR: cannot find type `Subset`
 }
diff --git a/tests/ui/layout/thaw-transmute-invalid-enum.stderr b/tests/ui/layout/thaw-transmute-invalid-enum.stderr
new file mode 100644
index 00000000000..e6a5399c66b
--- /dev/null
+++ b/tests/ui/layout/thaw-transmute-invalid-enum.stderr
@@ -0,0 +1,68 @@
+error[E0412]: cannot find type `Subset` in this scope
+  --> $DIR/thaw-transmute-invalid-enum.rs:34:41
+   |
+LL |     assert::is_transmutable::<Superset, Subset>();
+   |                                         ^^^^^^ not found in this scope
+   |
+help: you might be missing a type parameter
+   |
+LL | fn test<Subset>() {
+   |        ++++++++
+
+error[E0517]: attribute should be applied to a struct or union
+  --> $DIR/thaw-transmute-invalid-enum.rs:21:11
+   |
+LL |   #[repr(C, packed(2))]
+   |             ^^^^^^^^^
+LL |
+LL | / enum OxFF {
+LL | |     V = 0xFF,
+LL | | }
+   | |_- not a struct or union
+
+error[E0658]: use of unstable library feature 'transmutability'
+  --> $DIR/thaw-transmute-invalid-enum.rs:4:20
+   |
+LL |     use std::mem::{Assume, TransmuteFrom};
+   |                    ^^^^^^
+   |
+   = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
+   = help: add `#![feature(transmutability)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature 'transmutability'
+  --> $DIR/thaw-transmute-invalid-enum.rs:4:28
+   |
+LL |     use std::mem::{Assume, TransmuteFrom};
+   |                            ^^^^^^^^^^^^^
+   |
+   = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
+   = help: add `#![feature(transmutability)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature 'transmutability'
+  --> $DIR/thaw-transmute-invalid-enum.rs:10:14
+   |
+LL |         Dst: TransmuteFrom<Src>,
+   |              ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
+   = help: add `#![feature(transmutability)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+  --> $DIR/thaw-transmute-invalid-enum.rs:29:9
+   |
+LL |         a: Ox00,
+   |         ^^^^^^^
+   |
+   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL |         a: std::mem::ManuallyDrop<Ox00>,
+   |            +++++++++++++++++++++++    +
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0412, E0517, E0658, E0740.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/tests/crashes/128870.rs b/tests/ui/layout/thaw-validate-invalid-enum.rs
index 2b731962144..51aff7fb556 100644
--- a/tests/crashes/128870.rs
+++ b/tests/ui/layout/thaw-validate-invalid-enum.rs
@@ -1,7 +1,6 @@
-//@ known-bug: rust-lang/rust#128870
 //@ compile-flags: -Zvalidate-mir
 
-#[repr(packed)]
+#[repr(packed)] //~ ERROR: attribute should be applied to a struct
 #[repr(u32)]
 enum E {
     A,
@@ -12,7 +11,7 @@ enum E {
 fn main() {
     union InvalidTag {
         int: u32,
-        e: E,
+        e: E, //~ ERROR: field must implement `Copy`
     }
     let _invalid_tag = InvalidTag { int: 4 };
 }
diff --git a/tests/ui/layout/thaw-validate-invalid-enum.stderr b/tests/ui/layout/thaw-validate-invalid-enum.stderr
new file mode 100644
index 00000000000..9e522cba96a
--- /dev/null
+++ b/tests/ui/layout/thaw-validate-invalid-enum.stderr
@@ -0,0 +1,29 @@
+error[E0517]: attribute should be applied to a struct or union
+  --> $DIR/thaw-validate-invalid-enum.rs:3:8
+   |
+LL |   #[repr(packed)]
+   |          ^^^^^^
+LL |   #[repr(u32)]
+LL | / enum E {
+LL | |     A,
+LL | |     B,
+LL | |     C,
+LL | | }
+   | |_- not a struct or union
+
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+  --> $DIR/thaw-validate-invalid-enum.rs:14:9
+   |
+LL |         e: E,
+   |         ^^^^
+   |
+   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL |         e: std::mem::ManuallyDrop<E>,
+   |            +++++++++++++++++++++++ +
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0517, E0740.
+For more information about an error, try `rustc --explain E0517`.
diff --git a/tests/ui/lint/auxiliary/allow-macro.rs b/tests/ui/lint/auxiliary/allow-macro.rs
new file mode 100644
index 00000000000..35980e2e6ac
--- /dev/null
+++ b/tests/ui/lint/auxiliary/allow-macro.rs
@@ -0,0 +1,7 @@
+#[macro_export]
+macro_rules! emit_allow {
+    () => {
+        #[allow(unsafe_code)]
+        let _so_safe = 0;
+    };
+}
diff --git a/tests/ui/lint/auxiliary/deny-macro.rs b/tests/ui/lint/auxiliary/deny-macro.rs
new file mode 100644
index 00000000000..6106cd0ef17
--- /dev/null
+++ b/tests/ui/lint/auxiliary/deny-macro.rs
@@ -0,0 +1,7 @@
+#[macro_export]
+macro_rules! emit_deny {
+    () => {
+        #[deny(unsafe_code)]
+        let _so_safe = 0;
+    };
+}
diff --git a/tests/ui/lint/auxiliary/forbid-macro.rs b/tests/ui/lint/auxiliary/forbid-macro.rs
new file mode 100644
index 00000000000..aa74d0cf314
--- /dev/null
+++ b/tests/ui/lint/auxiliary/forbid-macro.rs
@@ -0,0 +1,7 @@
+#[macro_export]
+macro_rules! emit_forbid {
+    () => {
+        #[forbid(unsafe_code)]
+        let _so_safe = 0;
+    };
+}
diff --git a/tests/ui/lint/auxiliary/warn-macro.rs b/tests/ui/lint/auxiliary/warn-macro.rs
new file mode 100644
index 00000000000..8216b65c74b
--- /dev/null
+++ b/tests/ui/lint/auxiliary/warn-macro.rs
@@ -0,0 +1,7 @@
+#[macro_export]
+macro_rules! emit_warn {
+    () => {
+        #[warn(unsafe_code)]
+        let _so_safe = 0;
+    };
+}
diff --git a/tests/ui/lint/deny-inside-forbid-ignored.cli_forbid.stderr b/tests/ui/lint/deny-inside-forbid-ignored.cli_forbid.stderr
new file mode 100644
index 00000000000..06086cbef8a
--- /dev/null
+++ b/tests/ui/lint/deny-inside-forbid-ignored.cli_forbid.stderr
@@ -0,0 +1,35 @@
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+  --> $DIR/deny-inside-forbid-ignored.rs:12:17
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ----------- `forbid` level set here
+...
+LL |         #[allow(unsafe_code)] // let's have some unsafe code in here
+   |                 ^^^^^^^^^^^ overruled by previous forbid
+
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+  --> $DIR/deny-inside-forbid-ignored.rs:12:17
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ----------- `forbid` level set here
+...
+LL |         #[allow(unsafe_code)] // let's have some unsafe code in here
+   |                 ^^^^^^^^^^^ overruled by previous forbid
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: usage of an `unsafe` block
+  --> $DIR/deny-inside-forbid-ignored.rs:16:13
+   |
+LL |             unsafe { /* ≽^•⩊•^≼ */ }
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/deny-inside-forbid-ignored.rs:8:10
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/deny-inside-forbid-ignored.cli_forbid_warnings.stderr b/tests/ui/lint/deny-inside-forbid-ignored.cli_forbid_warnings.stderr
new file mode 100644
index 00000000000..06086cbef8a
--- /dev/null
+++ b/tests/ui/lint/deny-inside-forbid-ignored.cli_forbid_warnings.stderr
@@ -0,0 +1,35 @@
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+  --> $DIR/deny-inside-forbid-ignored.rs:12:17
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ----------- `forbid` level set here
+...
+LL |         #[allow(unsafe_code)] // let's have some unsafe code in here
+   |                 ^^^^^^^^^^^ overruled by previous forbid
+
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+  --> $DIR/deny-inside-forbid-ignored.rs:12:17
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ----------- `forbid` level set here
+...
+LL |         #[allow(unsafe_code)] // let's have some unsafe code in here
+   |                 ^^^^^^^^^^^ overruled by previous forbid
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: usage of an `unsafe` block
+  --> $DIR/deny-inside-forbid-ignored.rs:16:13
+   |
+LL |             unsafe { /* ≽^•⩊•^≼ */ }
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/deny-inside-forbid-ignored.rs:8:10
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/deny-inside-forbid-ignored.rs b/tests/ui/lint/deny-inside-forbid-ignored.rs
new file mode 100644
index 00000000000..b14a3e94bb5
--- /dev/null
+++ b/tests/ui/lint/deny-inside-forbid-ignored.rs
@@ -0,0 +1,20 @@
+//! Ensure that using deny inside forbid is treated as a no-op, and does not override the level to
+//! deny.
+
+//@ revisions: source_only cli_forbid cli_forbid_warnings
+//@[cli_forbid] compile-flags: -F unsafe_code
+//@[cli_forbid_warnings] compile-flags: -F warnings
+
+#[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+fn main() {
+    #[deny(unsafe_code)] // m-m-maybe we can have unsafe code in here?
+    {
+        #[allow(unsafe_code)] // let's have some unsafe code in here
+        //~^ ERROR allow(unsafe_code) incompatible with previous forbid
+        //~| ERROR allow(unsafe_code) incompatible with previous forbid
+        {
+            unsafe { /* ≽^•⩊•^≼ */ }
+            //~^ ERROR usage of an `unsafe` block
+        }
+    }
+}
diff --git a/tests/ui/lint/deny-inside-forbid-ignored.source_only.stderr b/tests/ui/lint/deny-inside-forbid-ignored.source_only.stderr
new file mode 100644
index 00000000000..06086cbef8a
--- /dev/null
+++ b/tests/ui/lint/deny-inside-forbid-ignored.source_only.stderr
@@ -0,0 +1,35 @@
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+  --> $DIR/deny-inside-forbid-ignored.rs:12:17
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ----------- `forbid` level set here
+...
+LL |         #[allow(unsafe_code)] // let's have some unsafe code in here
+   |                 ^^^^^^^^^^^ overruled by previous forbid
+
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+  --> $DIR/deny-inside-forbid-ignored.rs:12:17
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ----------- `forbid` level set here
+...
+LL |         #[allow(unsafe_code)] // let's have some unsafe code in here
+   |                 ^^^^^^^^^^^ overruled by previous forbid
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: usage of an `unsafe` block
+  --> $DIR/deny-inside-forbid-ignored.rs:16:13
+   |
+LL |             unsafe { /* ≽^•⩊•^≼ */ }
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/deny-inside-forbid-ignored.rs:8:10
+   |
+LL | #[forbid(unsafe_code)] // NO UNSAFE CODE IN HERE!!
+   |          ^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/forbid-macro-with-deny.allow.stderr b/tests/ui/lint/forbid-macro-with-deny.allow.stderr
new file mode 100644
index 00000000000..77735c1c5d3
--- /dev/null
+++ b/tests/ui/lint/forbid-macro-with-deny.allow.stderr
@@ -0,0 +1,26 @@
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+  --> $DIR/forbid-macro-with-deny.rs:39:5
+   |
+LL | #![forbid(unsafe_code)]
+   |           ----------- `forbid` level set here
+...
+LL |     allow_macro::emit_allow! {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ overruled by previous forbid
+   |
+   = note: this error originates in the macro `allow_macro::emit_allow` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+  --> $DIR/forbid-macro-with-deny.rs:39:5
+   |
+LL | #![forbid(unsafe_code)]
+   |           ----------- `forbid` level set here
+...
+LL |     allow_macro::emit_allow! {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ overruled by previous forbid
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   = note: this error originates in the macro `allow_macro::emit_allow` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/forbid-macro-with-deny.rs b/tests/ui/lint/forbid-macro-with-deny.rs
new file mode 100644
index 00000000000..85f67ea3631
--- /dev/null
+++ b/tests/ui/lint/forbid-macro-with-deny.rs
@@ -0,0 +1,45 @@
+//! Ensure that when a macro (or normal code) does `#[deny]` inside a `#[forbid]` context, no error
+//! is emitted, as both parties agree on the treatment of the lint.
+//!
+//! However, still emit an error if the macro does `#[allow]` or `#[warn]`.
+
+//@ revisions: forbid deny warn allow
+//@[forbid] aux-build:forbid-macro.rs
+//@[deny] aux-build:deny-macro.rs
+//@[warn] aux-build:warn-macro.rs
+//@[allow] aux-build:allow-macro.rs
+
+//@[forbid] check-pass
+//@[deny] check-pass
+
+#![forbid(unsafe_code)]
+
+#[cfg(allow)]
+extern crate allow_macro;
+#[cfg(deny)]
+extern crate deny_macro;
+#[cfg(forbid)]
+extern crate forbid_macro;
+#[cfg(warn)]
+extern crate warn_macro;
+
+fn main() {
+    #[cfg(forbid)]
+    forbid_macro::emit_forbid! {} // OK
+
+    #[cfg(deny)]
+    deny_macro::emit_deny! {} // OK
+
+    #[cfg(warn)]
+    warn_macro::emit_warn! {}
+    //[warn]~^ ERROR warn(unsafe_code) incompatible with previous forbid
+    //[warn]~| ERROR warn(unsafe_code) incompatible with previous forbid
+
+    #[cfg(allow)]
+    allow_macro::emit_allow! {}
+    //[allow]~^ ERROR allow(unsafe_code) incompatible with previous forbid
+    //[allow]~| ERROR allow(unsafe_code) incompatible with previous forbid
+
+    #[deny(unsafe_code)] // OK
+    let _ = 0;
+}
diff --git a/tests/ui/lint/forbid-macro-with-deny.warn.stderr b/tests/ui/lint/forbid-macro-with-deny.warn.stderr
new file mode 100644
index 00000000000..10452ebd1b6
--- /dev/null
+++ b/tests/ui/lint/forbid-macro-with-deny.warn.stderr
@@ -0,0 +1,26 @@
+error[E0453]: warn(unsafe_code) incompatible with previous forbid
+  --> $DIR/forbid-macro-with-deny.rs:34:5
+   |
+LL | #![forbid(unsafe_code)]
+   |           ----------- `forbid` level set here
+...
+LL |     warn_macro::emit_warn! {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ overruled by previous forbid
+   |
+   = note: this error originates in the macro `warn_macro::emit_warn` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0453]: warn(unsafe_code) incompatible with previous forbid
+  --> $DIR/forbid-macro-with-deny.rs:34:5
+   |
+LL | #![forbid(unsafe_code)]
+   |           ----------- `forbid` level set here
+...
+LL |     warn_macro::emit_warn! {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ overruled by previous forbid
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   = note: this error originates in the macro `warn_macro::emit_warn` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
index 37d96129317..45b78d75b27 100644
--- a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
+++ b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
@@ -19,9 +19,9 @@
 fn forbid_first(num: i32) -> i32 {
     #![forbid(unused)]
     #![deny(unused)]
-    //~^ ERROR: deny(unused) incompatible with previous forbid
-    //~| WARNING being phased out
     #![warn(unused)]
+    //~^ ERROR: warn(unused) incompatible with previous forbid
+    //~| WARNING being phased out
     #![allow(unused)]
 
     num * num
diff --git a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr
index f78bf899b84..407eaf1c60a 100644
--- a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr
+++ b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr
@@ -1,9 +1,10 @@
-error: deny(unused) incompatible with previous forbid
-  --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:21:13
+error: warn(unused) incompatible with previous forbid
+  --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13
    |
 LL |     #![forbid(unused)]
    |               ------ `forbid` level set here
 LL |     #![deny(unused)]
+LL |     #![warn(unused)]
    |             ^^^^^^ overruled by previous forbid
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
diff --git a/tests/ui/lint/issue-80988.rs b/tests/ui/lint/issue-80988.rs
deleted file mode 100644
index 80decd8e736..00000000000
--- a/tests/ui/lint/issue-80988.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Regression test for #80988
-//
-//@ check-pass
-
-#![forbid(warnings)]
-
-#[deny(warnings)]
-//~^ WARNING incompatible with previous forbid
-//~| WARNING being phased out
-fn main() {}
diff --git a/tests/ui/lint/issue-80988.stderr b/tests/ui/lint/issue-80988.stderr
deleted file mode 100644
index afc93fcfeef..00000000000
--- a/tests/ui/lint/issue-80988.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-warning: deny(warnings) incompatible with previous forbid
-  --> $DIR/issue-80988.rs:7:8
-   |
-LL | #![forbid(warnings)]
-   |           -------- `forbid` level set here
-LL |
-LL | #[deny(warnings)]
-   |        ^^^^^^^^ overruled by previous forbid
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-   = note: `#[warn(forbidden_lint_groups)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs
index cb8e9e80675..19af1de9576 100644
--- a/tests/ui/lint/lint-ctypes-enum.rs
+++ b/tests/ui/lint/lint-ctypes-enum.rs
@@ -2,7 +2,6 @@
 #![deny(improper_ctypes)]
 #![feature(ptr_internals)]
 #![feature(transparent_unions)]
-#![feature(result_ffi_guarantees)]
 
 use std::num;
 
diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr
index bba5b09b69c..8e92e7e6946 100644
--- a/tests/ui/lint/lint-ctypes-enum.stderr
+++ b/tests/ui/lint/lint-ctypes-enum.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `U`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:69:14
+  --> $DIR/lint-ctypes-enum.rs:68:14
    |
 LL |     fn uf(x: U);
    |              ^ not FFI-safe
@@ -7,7 +7,7 @@ LL |     fn uf(x: U);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 note: the type is defined here
-  --> $DIR/lint-ctypes-enum.rs:10:1
+  --> $DIR/lint-ctypes-enum.rs:9:1
    |
 LL | enum U {
    | ^^^^^^
@@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `B`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:70:14
+  --> $DIR/lint-ctypes-enum.rs:69:14
    |
 LL |     fn bf(x: B);
    |              ^ not FFI-safe
@@ -26,13 +26,13 @@ LL |     fn bf(x: B);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 note: the type is defined here
-  --> $DIR/lint-ctypes-enum.rs:13:1
+  --> $DIR/lint-ctypes-enum.rs:12:1
    |
 LL | enum B {
    | ^^^^^^
 
 error: `extern` block uses type `T`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:71:14
+  --> $DIR/lint-ctypes-enum.rs:70:14
    |
 LL |     fn tf(x: T);
    |              ^ not FFI-safe
@@ -40,13 +40,13 @@ LL |     fn tf(x: T);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 note: the type is defined here
-  --> $DIR/lint-ctypes-enum.rs:17:1
+  --> $DIR/lint-ctypes-enum.rs:16:1
    |
 LL | enum T {
    | ^^^^^^
 
 error: `extern` block uses type `u128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:83:31
+  --> $DIR/lint-ctypes-enum.rs:82:31
    |
 LL |     fn option_nonzero_u128(x: Option<num::NonZero<u128>>);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -54,7 +54,7 @@ LL |     fn option_nonzero_u128(x: Option<num::NonZero<u128>>);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `i128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:90:31
+  --> $DIR/lint-ctypes-enum.rs:89:31
    |
 LL |     fn option_nonzero_i128(x: Option<num::NonZero<i128>>);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -62,7 +62,7 @@ LL |     fn option_nonzero_i128(x: Option<num::NonZero<i128>>);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:95:36
+  --> $DIR/lint-ctypes-enum.rs:94:36
    |
 LL |     fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>>>);
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -71,7 +71,7 @@ LL |     fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>
    = note: enum has no representation hint
 
 error: `extern` block uses type `Option<Rust<NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:97:28
+  --> $DIR/lint-ctypes-enum.rs:96:28
    |
 LL |     fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>);
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -80,7 +80,7 @@ LL |     fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>);
    = note: enum has no representation hint
 
 error: `extern` block uses type `u128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:107:33
+  --> $DIR/lint-ctypes-enum.rs:106:33
    |
 LL |     fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -88,7 +88,7 @@ LL |     fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `i128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:114:33
+  --> $DIR/lint-ctypes-enum.rs:113:33
    |
 LL |     fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -96,7 +96,7 @@ LL |     fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `Result<TransparentUnion<NonZero<u8>>, ()>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:119:38
+  --> $DIR/lint-ctypes-enum.rs:118:38
    |
 LL |     fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u8>>, ()>);
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -105,7 +105,7 @@ LL |     fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<Rust<NonZero<u8>>, ()>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:121:30
+  --> $DIR/lint-ctypes-enum.rs:120:30
    |
 LL |     fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -114,7 +114,7 @@ LL |     fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<NonZero<u8>, U>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:125:51
+  --> $DIR/lint-ctypes-enum.rs:124:51
    |
 LL |     fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
    |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -123,7 +123,7 @@ LL |     fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>,
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<NonZero<u8>, B>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:127:53
+  --> $DIR/lint-ctypes-enum.rs:126:53
    |
 LL |     fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
    |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -132,7 +132,7 @@ LL |     fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<NonZero<u8>, NonExhaustive>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:129:51
+  --> $DIR/lint-ctypes-enum.rs:128:51
    |
 LL |     fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
    |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -141,7 +141,7 @@ LL |     fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>,
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<NonZero<u8>, Field>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:132:49
+  --> $DIR/lint-ctypes-enum.rs:131:49
    |
 LL |     fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Field>);
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -150,7 +150,7 @@ LL |     fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Fi
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:134:30
+  --> $DIR/lint-ctypes-enum.rs:133:30
    |
 LL |     fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -159,7 +159,7 @@ LL |     fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
    = note: enum has no representation hint
 
 error: `extern` block uses type `u128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:145:33
+  --> $DIR/lint-ctypes-enum.rs:144:33
    |
 LL |     fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -167,7 +167,7 @@ LL |     fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `i128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:152:33
+  --> $DIR/lint-ctypes-enum.rs:151:33
    |
 LL |     fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -175,7 +175,7 @@ LL |     fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `Result<(), TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:157:38
+  --> $DIR/lint-ctypes-enum.rs:156:38
    |
 LL |     fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZero<u8>>>);
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -184,7 +184,7 @@ LL |     fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZe
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:159:30
+  --> $DIR/lint-ctypes-enum.rs:158:30
    |
 LL |     fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -193,7 +193,7 @@ LL |     fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<U, NonZero<u8>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:163:51
+  --> $DIR/lint-ctypes-enum.rs:162:51
    |
 LL |     fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8>>);
    |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -202,7 +202,7 @@ LL |     fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<B, NonZero<u8>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:165:53
+  --> $DIR/lint-ctypes-enum.rs:164:53
    |
 LL |     fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
    |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -211,7 +211,7 @@ LL |     fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:167:51
+  --> $DIR/lint-ctypes-enum.rs:166:51
    |
 LL |     fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
    |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -220,7 +220,7 @@ LL |     fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<Field, NonZero<u8>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:170:49
+  --> $DIR/lint-ctypes-enum.rs:169:49
    |
 LL |     fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<u8>>);
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -229,7 +229,7 @@ LL |     fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:172:30
+  --> $DIR/lint-ctypes-enum.rs:171:30
    |
 LL |     fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -238,7 +238,7 @@ LL |     fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:174:27
+  --> $DIR/lint-ctypes-enum.rs:173:27
    |
 LL |     fn result_unit_t_e(x: Result<(), ()>);
    |                           ^^^^^^^^^^^^^^ not FFI-safe
diff --git a/tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs b/tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs
index d2d72a68f13..187209d4e20 100644
--- a/tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs
+++ b/tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs
@@ -1,4 +1,4 @@
-#![feature(strict_provenance)]
+#![feature(strict_provenance_lints)]
 #![deny(fuzzy_provenance_casts)]
 
 fn main() {
diff --git a/tests/ui/lint/lint-strict-provenance-lossy-casts.rs b/tests/ui/lint/lint-strict-provenance-lossy-casts.rs
index 9799a053756..395dc75f825 100644
--- a/tests/ui/lint/lint-strict-provenance-lossy-casts.rs
+++ b/tests/ui/lint/lint-strict-provenance-lossy-casts.rs
@@ -1,4 +1,4 @@
-#![feature(strict_provenance)]
+#![feature(strict_provenance_lints)]
 #![deny(lossy_provenance_casts)]
 
 fn main() {
diff --git a/tests/ui/lint/unit_bindings.deny_level.stderr b/tests/ui/lint/unit_bindings.deny_level.stderr
new file mode 100644
index 00000000000..9062f2e5c1f
--- /dev/null
+++ b/tests/ui/lint/unit_bindings.deny_level.stderr
@@ -0,0 +1,40 @@
+error: binding has unit type `()`
+  --> $DIR/unit_bindings.rs:50:5
+   |
+LL |     let _ = expr;
+   |     ^^^^-^^^^^^^^
+   |         |
+   |         this pattern is inferred to be the unit type `()`
+   |
+note: the lint level is defined here
+  --> $DIR/unit_bindings.rs:22:30
+   |
+LL | #![cfg_attr(deny_level, deny(unit_bindings))]
+   |                              ^^^^^^^^^^^^^
+
+error: binding has unit type `()`
+  --> $DIR/unit_bindings.rs:51:5
+   |
+LL |     let pat = expr;
+   |     ^^^^---^^^^^^^^
+   |         |
+   |         this pattern is inferred to be the unit type `()`
+
+error: binding has unit type `()`
+  --> $DIR/unit_bindings.rs:52:5
+   |
+LL |     let _pat = expr;
+   |     ^^^^----^^^^^^^^
+   |         |
+   |         this pattern is inferred to be the unit type `()`
+
+error: binding has unit type `()`
+  --> $DIR/unit_bindings.rs:55:5
+   |
+LL |     let list = v.sort();
+   |     ^^^^----^^^^^^^^^^^^
+   |         |
+   |         this pattern is inferred to be the unit type `()`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/unit_bindings.rs b/tests/ui/lint/unit_bindings.rs
new file mode 100644
index 00000000000..9a682a2244c
--- /dev/null
+++ b/tests/ui/lint/unit_bindings.rs
@@ -0,0 +1,60 @@
+//! Basic checks for `unit_bindings` lint.
+//!
+//! The `unit_bindings` lint tries to detect cases like `let list = list.sort()`. The lint will
+//! trigger on bindings that have the unit `()` type **except** if:
+//!
+//! - The user wrote `()` on either side, i.e.
+//!     - `let () = <expr>;` or `let <expr> = ();`
+//!     - `let _ = ();`
+//! - The binding occurs within macro expansions, e.g. `foo!();`.
+//! - The user explicitly provided type annotations, e.g. `let x: () = <expr>`.
+//!
+//! Examples where the lint *should* fire on include:
+//!
+//! - `let _ = <expr>;`
+//! - `let pat = <expr>;`
+//! - `let _pat = <expr>;`
+
+//@ revisions: default_level deny_level
+//@[default_level] check-pass (`unit_bindings` is currently allow-by-default)
+
+#![allow(unused)]
+#![cfg_attr(deny_level, deny(unit_bindings))]
+
+// The `list` binding below should trigger the lint if it's not contained in a macro expansion.
+macro_rules! expands_to_sus {
+    () => {
+        let mut v = [1, 2, 3];
+        let list = v.sort();
+    }
+}
+
+// No warning for `y` and `z` because it is provided as type parameter.
+fn ty_param_check<T: Copy>(x: T) {
+    let y = x;
+    let z: T = x;
+}
+
+fn main() {
+    // No warning if user explicitly wrote `()` on either side.
+    let expr = ();
+    let () = expr;
+    let _ = ();
+    // No warning if user explicitly annotates the unit type on the binding.
+    let pat: () = expr;
+    // No warning for let bindings with unit type in macro expansions.
+    expands_to_sus!();
+    // No warning for unit bindings in generic fns.
+    ty_param_check(());
+
+    let _ = expr; //[deny_level]~ ERROR binding has unit type
+    let pat = expr; //[deny_level]~ ERROR binding has unit type
+    let _pat = expr; //[deny_level]~ ERROR binding has unit type
+
+    let mut v = [1, 2, 3];
+    let list = v.sort(); //[deny_level]~ ERROR binding has unit type
+
+    // Limitation: the lint currently does not fire on nested unit LHS bindings, i.e.
+    // this will not currently trigger the lint.
+    let (nested, _) = (expr, 0i32);
+}
diff --git a/tests/ui/lint/unused/unused-macro-rules-compile-error.stderr b/tests/ui/lint/unused/unused-macro-rules-compile-error.stderr
index 936428f6a1c..d91af762e68 100644
--- a/tests/ui/lint/unused/unused-macro-rules-compile-error.stderr
+++ b/tests/ui/lint/unused/unused-macro-rules-compile-error.stderr
@@ -10,17 +10,17 @@ note: the lint level is defined here
 LL | #![deny(unused_macro_rules)]
    |         ^^^^^^^^^^^^^^^^^^
 
-error: rule #3 of macro `num2` is never used
-  --> $DIR/unused-macro-rules-compile-error.rs:22:5
-   |
-LL |     (two_) => { compile_error! };
-   |     ^^^^^^
-
 error: rule #2 of macro `num2` is never used
   --> $DIR/unused-macro-rules-compile-error.rs:20:5
    |
 LL |     (two) => { fn compile_error() {} };
    |     ^^^^^
 
+error: rule #3 of macro `num2` is never used
+  --> $DIR/unused-macro-rules-compile-error.rs:22:5
+   |
+LL |     (two_) => { compile_error! };
+   |     ^^^^^^
+
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/lint/unused/unused-macro-rules-decl.stderr b/tests/ui/lint/unused/unused-macro-rules-decl.stderr
index 10ceb3921f3..98f146c5b5b 100644
--- a/tests/ui/lint/unused/unused-macro-rules-decl.stderr
+++ b/tests/ui/lint/unused/unused-macro-rules-decl.stderr
@@ -1,8 +1,8 @@
-error: rule #4 of macro `num` is never used
-  --> $DIR/unused-macro-rules-decl.rs:11:5
+error: rule #2 of macro `num` is never used
+  --> $DIR/unused-macro-rules-decl.rs:9:5
    |
-LL |     (four) => { 4 },
-   |     ^^^^^^
+LL |     (two) => { 2 },
+   |     ^^^^^
    |
 note: the lint level is defined here
   --> $DIR/unused-macro-rules-decl.rs:2:9
@@ -10,11 +10,11 @@ note: the lint level is defined here
 LL | #![deny(unused_macro_rules)]
    |         ^^^^^^^^^^^^^^^^^^
 
-error: rule #2 of macro `num` is never used
-  --> $DIR/unused-macro-rules-decl.rs:9:5
+error: rule #4 of macro `num` is never used
+  --> $DIR/unused-macro-rules-decl.rs:11:5
    |
-LL |     (two) => { 2 },
-   |     ^^^^^
+LL |     (four) => { 4 },
+   |     ^^^^^^
 
 error: rule #3 of macro `num_rec` is never used
   --> $DIR/unused-macro-rules-decl.rs:31:5
diff --git a/tests/ui/lint/unused/unused-macro-rules.stderr b/tests/ui/lint/unused/unused-macro-rules.stderr
index b9258e77805..e50a8a63cea 100644
--- a/tests/ui/lint/unused/unused-macro-rules.stderr
+++ b/tests/ui/lint/unused/unused-macro-rules.stderr
@@ -1,8 +1,8 @@
-error: rule #4 of macro `num` is never used
-  --> $DIR/unused-macro-rules.rs:10:5
+error: rule #2 of macro `num` is never used
+  --> $DIR/unused-macro-rules.rs:8:5
    |
-LL |     (four) => { 4 };
-   |     ^^^^^^
+LL |     (two) => { 2 };
+   |     ^^^^^
    |
 note: the lint level is defined here
   --> $DIR/unused-macro-rules.rs:1:9
@@ -10,11 +10,11 @@ note: the lint level is defined here
 LL | #![deny(unused_macro_rules)]
    |         ^^^^^^^^^^^^^^^^^^
 
-error: rule #2 of macro `num` is never used
-  --> $DIR/unused-macro-rules.rs:8:5
+error: rule #4 of macro `num` is never used
+  --> $DIR/unused-macro-rules.rs:10:5
    |
-LL |     (two) => { 2 };
-   |     ^^^^^
+LL |     (four) => { 4 };
+   |     ^^^^^^
 
 error: rule #3 of macro `num_rec` is never used
   --> $DIR/unused-macro-rules.rs:30:5
diff --git a/tests/ui/mir/alignment/i686-pc-windows-msvc.rs b/tests/ui/mir/alignment/i686-pc-windows-msvc.rs
index 379f61ae818..c6b47a6d679 100644
--- a/tests/ui/mir/alignment/i686-pc-windows-msvc.rs
+++ b/tests/ui/mir/alignment/i686-pc-windows-msvc.rs
@@ -7,8 +7,6 @@
 // that will fail on dereferencing of a pointer to u64 which is not 8-byte-aligned but is
 // 4-byte-aligned.
 
-#![feature(strict_provenance)]
-
 fn main() {
     let mut x = [0u64; 2];
     let ptr = x.as_mut_ptr();
diff --git a/tests/ui/mir/alignment/packed.rs b/tests/ui/mir/alignment/packed.rs
index 1a12425f11a..cf908365e1a 100644
--- a/tests/ui/mir/alignment/packed.rs
+++ b/tests/ui/mir/alignment/packed.rs
@@ -1,8 +1,6 @@
 //@ run-pass
 //@ compile-flags: -C debug-assertions
 
-#![feature(strict_provenance)]
-
 #[repr(packed)]
 struct Misaligner {
     _head: u8,
diff --git a/tests/ui/rfcs/rfc-3391-result-ffi-guarantees.rs b/tests/ui/rfcs/rfc-3391-result-ffi-guarantees.rs
new file mode 100644
index 00000000000..9b8092526b9
--- /dev/null
+++ b/tests/ui/rfcs/rfc-3391-result-ffi-guarantees.rs
@@ -0,0 +1,133 @@
+//@ build-pass
+/*!
+
+The guarantees in RFC 3391 were strengthened as a result of the 2024 Oct 09 T-lang meeting[^1]
+following the precedent of T-lang's guaranteeing[^2] ABI compatibility for "Option-like" enums[^2].
+We now guarantee ABI compatibility for enums that conform to these rules described by scottmcm:
+
+* The enum `E` has exactly two variants.
+* One variant has exactly one field, of type `T`.
+* `T` is a `rustc_nonnull_optimization_guaranteed` type.
+* All fields of the other variant are 1-ZSTs.
+
+Where "all" fields includes "there aren't any fields, so they're vacuously all 1-ZSTs".
+
+Note: "1-ZST" means a type of size 0 and alignment 1.
+
+The reason alignment of the zero-sized type matters is it can affect the alignment of the enum,
+which also will affect its size if the enum has a non-zero size.
+
+[^1]: <https://github.com/rust-lang/rust/pull/130628#issuecomment-2402761599>
+[^2]: <https://github.com/rust-lang/rust/pull/60300#issuecomment-487000474>
+
+*/
+
+#![allow(dead_code)]
+#![deny(improper_ctypes)]
+#![feature(ptr_internals)]
+
+use std::num;
+
+enum Z {}
+
+#[repr(transparent)]
+struct TransparentStruct<T>(T, std::marker::PhantomData<Z>);
+
+#[repr(transparent)]
+enum TransparentEnum<T> {
+    Variant(T, std::marker::PhantomData<Z>),
+}
+
+struct NoField;
+
+extern "C" {
+    fn result_ref_t(x: Result<&'static u8, ()>);
+    fn result_fn_t(x: Result<extern "C" fn(), ()>);
+    fn result_nonnull_t(x: Result<std::ptr::NonNull<u8>, ()>);
+    fn result_unique_t(x: Result<std::ptr::Unique<u8>, ()>);
+    fn result_nonzero_u8_t(x: Result<num::NonZero<u8>, ()>);
+    fn result_nonzero_u16_t(x: Result<num::NonZero<u16>, ()>);
+    fn result_nonzero_u32_t(x: Result<num::NonZero<u32>, ()>);
+    fn result_nonzero_u64_t(x: Result<num::NonZero<u64>, ()>);
+    fn result_nonzero_usize_t(x: Result<num::NonZero<usize>, ()>);
+    fn result_nonzero_i8_t(x: Result<num::NonZero<i8>, ()>);
+    fn result_nonzero_i16_t(x: Result<num::NonZero<i16>, ()>);
+    fn result_nonzero_i32_t(x: Result<num::NonZero<i32>, ()>);
+    fn result_nonzero_i64_t(x: Result<num::NonZero<i64>, ()>);
+    fn result_nonzero_isize_t(x: Result<num::NonZero<isize>, ()>);
+    fn result_transparent_struct_t(x: Result<TransparentStruct<num::NonZero<u8>>, ()>);
+    fn result_transparent_enum_t(x: Result<TransparentEnum<num::NonZero<u8>>, ()>);
+    fn result_phantom_t(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
+    fn result_1zst_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, Z>);
+    fn result_1zst_exhaustive_no_field_t(x: Result<num::NonZero<u8>, NoField>);
+
+    fn result_ref_e(x: Result<(), &'static u8>);
+    fn result_fn_e(x: Result<(), extern "C" fn()>);
+    fn result_nonnull_e(x: Result<(), std::ptr::NonNull<u8>>);
+    fn result_unique_e(x: Result<(), std::ptr::Unique<u8>>);
+    fn result_nonzero_u8_e(x: Result<(), num::NonZero<u8>>);
+    fn result_nonzero_u16_e(x: Result<(), num::NonZero<u16>>);
+    fn result_nonzero_u32_e(x: Result<(), num::NonZero<u32>>);
+    fn result_nonzero_u64_e(x: Result<(), num::NonZero<u64>>);
+    fn result_nonzero_usize_e(x: Result<(), num::NonZero<usize>>);
+    fn result_nonzero_i8_e(x: Result<(), num::NonZero<i8>>);
+    fn result_nonzero_i16_e(x: Result<(), num::NonZero<i16>>);
+    fn result_nonzero_i32_e(x: Result<(), num::NonZero<i32>>);
+    fn result_nonzero_i64_e(x: Result<(), num::NonZero<i64>>);
+    fn result_nonzero_isize_e(x: Result<(), num::NonZero<isize>>);
+    fn result_transparent_struct_e(x: Result<(), TransparentStruct<num::NonZero<u8>>>);
+    fn result_transparent_enum_e(x: Result<(), TransparentEnum<num::NonZero<u8>>>);
+    fn result_phantom_e(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
+    fn result_1zst_exhaustive_no_variant_e(x: Result<Z, num::NonZero<u8>>);
+    fn result_1zst_exhaustive_no_field_e(x: Result<NoField, num::NonZero<u8>>);
+}
+
+// Custom "Result-like" enum for testing custom "Option-like" types are also accepted
+enum Either<L, R> {
+    Left(L),
+    Right(R),
+}
+
+extern "C" {
+    fn either_ref_t(x: Either<&'static u8, ()>);
+    fn either_fn_t(x: Either<extern "C" fn(), ()>);
+    fn either_nonnull_t(x: Either<std::ptr::NonNull<u8>, ()>);
+    fn either_unique_t(x: Either<std::ptr::Unique<u8>, ()>);
+    fn either_nonzero_u8_t(x: Either<num::NonZero<u8>, ()>);
+    fn either_nonzero_u16_t(x: Either<num::NonZero<u16>, ()>);
+    fn either_nonzero_u32_t(x: Either<num::NonZero<u32>, ()>);
+    fn either_nonzero_u64_t(x: Either<num::NonZero<u64>, ()>);
+    fn either_nonzero_usize_t(x: Either<num::NonZero<usize>, ()>);
+    fn either_nonzero_i8_t(x: Either<num::NonZero<i8>, ()>);
+    fn either_nonzero_i16_t(x: Either<num::NonZero<i16>, ()>);
+    fn either_nonzero_i32_t(x: Either<num::NonZero<i32>, ()>);
+    fn either_nonzero_i64_t(x: Either<num::NonZero<i64>, ()>);
+    fn either_nonzero_isize_t(x: Either<num::NonZero<isize>, ()>);
+    fn either_transparent_struct_t(x: Either<TransparentStruct<num::NonZero<u8>>, ()>);
+    fn either_transparent_enum_t(x: Either<TransparentEnum<num::NonZero<u8>>, ()>);
+    fn either_phantom_t(x: Either<num::NonZero<u8>, std::marker::PhantomData<()>>);
+    fn either_1zst_exhaustive_no_variant_t(x: Either<num::NonZero<u8>, Z>);
+    fn either_1zst_exhaustive_no_field_t(x: Either<num::NonZero<u8>, NoField>);
+
+    fn either_ref_e(x: Either<(), &'static u8>);
+    fn either_fn_e(x: Either<(), extern "C" fn()>);
+    fn either_nonnull_e(x: Either<(), std::ptr::NonNull<u8>>);
+    fn either_unique_e(x: Either<(), std::ptr::Unique<u8>>);
+    fn either_nonzero_u8_e(x: Either<(), num::NonZero<u8>>);
+    fn either_nonzero_u16_e(x: Either<(), num::NonZero<u16>>);
+    fn either_nonzero_u32_e(x: Either<(), num::NonZero<u32>>);
+    fn either_nonzero_u64_e(x: Either<(), num::NonZero<u64>>);
+    fn either_nonzero_usize_e(x: Either<(), num::NonZero<usize>>);
+    fn either_nonzero_i8_e(x: Either<(), num::NonZero<i8>>);
+    fn either_nonzero_i16_e(x: Either<(), num::NonZero<i16>>);
+    fn either_nonzero_i32_e(x: Either<(), num::NonZero<i32>>);
+    fn either_nonzero_i64_e(x: Either<(), num::NonZero<i64>>);
+    fn either_nonzero_isize_e(x: Either<(), num::NonZero<isize>>);
+    fn either_transparent_struct_e(x: Either<(), TransparentStruct<num::NonZero<u8>>>);
+    fn either_transparent_enum_e(x: Either<(), TransparentEnum<num::NonZero<u8>>>);
+    fn either_phantom_e(x: Either<num::NonZero<u8>, std::marker::PhantomData<()>>);
+    fn either_1zst_exhaustive_no_variant_e(x: Either<Z, num::NonZero<u8>>);
+    fn either_1zst_exhaustive_no_field_e(x: Either<NoField, num::NonZero<u8>>);
+}
+
+pub fn main() {}
diff --git a/tests/ui/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr
index b27f769ba34..3a2d4df3bee 100644
--- a/tests/ui/stats/hir-stats.stderr
+++ b/tests/ui/stats/hir-stats.stderr
@@ -1,33 +1,33 @@
 ast-stats-1 PRE EXPANSION AST STATS
 ast-stats-1 Name                Accumulated Size         Count     Item Size
 ast-stats-1 ----------------------------------------------------------------
+ast-stats-1 Crate                     40 ( 0.6%)             1            40
 ast-stats-1 GenericArgs               40 ( 0.6%)             1            40
 ast-stats-1 - AngleBracketed            40 ( 0.6%)             1
-ast-stats-1 Crate                     40 ( 0.6%)             1            40
 ast-stats-1 ExprField                 48 ( 0.7%)             1            48
 ast-stats-1 WherePredicate            56 ( 0.8%)             1            56
 ast-stats-1 - BoundPredicate            56 ( 0.8%)             1
 ast-stats-1 Attribute                 64 ( 1.0%)             2            32
-ast-stats-1 - Normal                    32 ( 0.5%)             1
 ast-stats-1 - DocComment                32 ( 0.5%)             1
+ast-stats-1 - Normal                    32 ( 0.5%)             1
 ast-stats-1 Local                     80 ( 1.2%)             1            80
 ast-stats-1 ForeignItem               88 ( 1.3%)             1            88
 ast-stats-1 - Fn                        88 ( 1.3%)             1
 ast-stats-1 Arm                       96 ( 1.4%)             2            48
 ast-stats-1 FnDecl                   120 ( 1.8%)             5            24
 ast-stats-1 FieldDef                 160 ( 2.4%)             2            80
+ast-stats-1 Param                    160 ( 2.4%)             4            40
 ast-stats-1 Stmt                     160 ( 2.4%)             5            32
 ast-stats-1 - Let                       32 ( 0.5%)             1
 ast-stats-1 - MacCall                   32 ( 0.5%)             1
 ast-stats-1 - Expr                      96 ( 1.4%)             3
-ast-stats-1 Param                    160 ( 2.4%)             4            40
 ast-stats-1 Block                    192 ( 2.9%)             6            32
 ast-stats-1 Variant                  208 ( 3.1%)             2           104
-ast-stats-1 GenericBound             352 ( 5.3%)             4            88
-ast-stats-1 - Trait                    352 ( 5.3%)             4
 ast-stats-1 AssocItem                352 ( 5.3%)             4            88
 ast-stats-1 - Type                     176 ( 2.7%)             2
 ast-stats-1 - Fn                       176 ( 2.7%)             2
+ast-stats-1 GenericBound             352 ( 5.3%)             4            88
+ast-stats-1 - Trait                    352 ( 5.3%)             4
 ast-stats-1 GenericParam             480 ( 7.2%)             5            96
 ast-stats-1 Pat                      504 ( 7.6%)             7            72
 ast-stats-1 - Struct                    72 ( 1.1%)             1
@@ -41,15 +41,15 @@ ast-stats-1 - Lit                      144 ( 2.2%)             2
 ast-stats-1 - Block                    216 ( 3.3%)             3
 ast-stats-1 PathSegment              744 (11.2%)            31            24
 ast-stats-1 Ty                       896 (13.5%)            14            64
-ast-stats-1 - Ptr                       64 ( 1.0%)             1
 ast-stats-1 - Ref                       64 ( 1.0%)             1
+ast-stats-1 - Ptr                       64 ( 1.0%)             1
 ast-stats-1 - ImplicitSelf             128 ( 1.9%)             2
 ast-stats-1 - Path                     640 ( 9.6%)            10
 ast-stats-1 Item                   1_224 (18.4%)             9           136
-ast-stats-1 - Trait                    136 ( 2.0%)             1
-ast-stats-1 - Enum                     136 ( 2.0%)             1
 ast-stats-1 - ForeignMod               136 ( 2.0%)             1
+ast-stats-1 - Trait                    136 ( 2.0%)             1
 ast-stats-1 - Impl                     136 ( 2.0%)             1
+ast-stats-1 - Enum                     136 ( 2.0%)             1
 ast-stats-1 - Fn                       272 ( 4.1%)             2
 ast-stats-1 - Use                      408 ( 6.1%)             3
 ast-stats-1 ----------------------------------------------------------------
@@ -58,9 +58,9 @@ ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
 ast-stats-2 ----------------------------------------------------------------
+ast-stats-2 Crate                     40 ( 0.5%)             1            40
 ast-stats-2 GenericArgs               40 ( 0.5%)             1            40
 ast-stats-2 - AngleBracketed            40 ( 0.5%)             1
-ast-stats-2 Crate                     40 ( 0.5%)             1            40
 ast-stats-2 ExprField                 48 ( 0.7%)             1            48
 ast-stats-2 WherePredicate            56 ( 0.8%)             1            56
 ast-stats-2 - BoundPredicate            56 ( 0.8%)             1
@@ -68,24 +68,24 @@ ast-stats-2 Local                     80 ( 1.1%)             1            80
 ast-stats-2 ForeignItem               88 ( 1.2%)             1            88
 ast-stats-2 - Fn                        88 ( 1.2%)             1
 ast-stats-2 Arm                       96 ( 1.3%)             2            48
-ast-stats-2 InlineAsm                120 ( 1.6%)             1           120
 ast-stats-2 FnDecl                   120 ( 1.6%)             5            24
+ast-stats-2 InlineAsm                120 ( 1.6%)             1           120
 ast-stats-2 Attribute                128 ( 1.8%)             4            32
 ast-stats-2 - DocComment                32 ( 0.4%)             1
 ast-stats-2 - Normal                    96 ( 1.3%)             3
 ast-stats-2 FieldDef                 160 ( 2.2%)             2            80
+ast-stats-2 Param                    160 ( 2.2%)             4            40
 ast-stats-2 Stmt                     160 ( 2.2%)             5            32
 ast-stats-2 - Let                       32 ( 0.4%)             1
 ast-stats-2 - Semi                      32 ( 0.4%)             1
 ast-stats-2 - Expr                      96 ( 1.3%)             3
-ast-stats-2 Param                    160 ( 2.2%)             4            40
 ast-stats-2 Block                    192 ( 2.6%)             6            32
 ast-stats-2 Variant                  208 ( 2.9%)             2           104
-ast-stats-2 GenericBound             352 ( 4.8%)             4            88
-ast-stats-2 - Trait                    352 ( 4.8%)             4
 ast-stats-2 AssocItem                352 ( 4.8%)             4            88
 ast-stats-2 - Type                     176 ( 2.4%)             2
 ast-stats-2 - Fn                       176 ( 2.4%)             2
+ast-stats-2 GenericBound             352 ( 4.8%)             4            88
+ast-stats-2 - Trait                    352 ( 4.8%)             4
 ast-stats-2 GenericParam             480 ( 6.6%)             5            96
 ast-stats-2 Pat                      504 ( 6.9%)             7            72
 ast-stats-2 - Struct                    72 ( 1.0%)             1
@@ -100,16 +100,16 @@ ast-stats-2 - Lit                      144 ( 2.0%)             2
 ast-stats-2 - Block                    216 ( 3.0%)             3
 ast-stats-2 PathSegment              864 (11.9%)            36            24
 ast-stats-2 Ty                       896 (12.3%)            14            64
-ast-stats-2 - Ptr                       64 ( 0.9%)             1
 ast-stats-2 - Ref                       64 ( 0.9%)             1
+ast-stats-2 - Ptr                       64 ( 0.9%)             1
 ast-stats-2 - ImplicitSelf             128 ( 1.8%)             2
 ast-stats-2 - Path                     640 ( 8.8%)            10
 ast-stats-2 Item                   1_496 (20.5%)            11           136
-ast-stats-2 - Trait                    136 ( 1.9%)             1
 ast-stats-2 - Enum                     136 ( 1.9%)             1
+ast-stats-2 - Trait                    136 ( 1.9%)             1
+ast-stats-2 - Impl                     136 ( 1.9%)             1
 ast-stats-2 - ExternCrate              136 ( 1.9%)             1
 ast-stats-2 - ForeignMod               136 ( 1.9%)             1
-ast-stats-2 - Impl                     136 ( 1.9%)             1
 ast-stats-2 - Fn                       272 ( 3.7%)             2
 ast-stats-2 - Use                      544 ( 7.5%)             4
 ast-stats-2 ----------------------------------------------------------------
@@ -129,8 +129,8 @@ hir-stats - Lifetime                  48 ( 0.5%)             3
 hir-stats Local                     64 ( 0.7%)             1            64
 hir-stats Param                     64 ( 0.7%)             2            32
 hir-stats Body                      72 ( 0.8%)             3            24
-hir-stats InlineAsm                 72 ( 0.8%)             1            72
 hir-stats ImplItemRef               72 ( 0.8%)             2            36
+hir-stats InlineAsm                 72 ( 0.8%)             1            72
 hir-stats Arm                       80 ( 0.9%)             2            40
 hir-stats FieldDef                  96 ( 1.1%)             2            48
 hir-stats Stmt                      96 ( 1.1%)             3            32
@@ -139,8 +139,8 @@ hir-stats - Semi                      32 ( 0.4%)             1
 hir-stats - Expr                      32 ( 0.4%)             1
 hir-stats FnDecl                   120 ( 1.3%)             3            40
 hir-stats Attribute                128 ( 1.4%)             4            32
-hir-stats Variant                  144 ( 1.6%)             2            72
 hir-stats GenericArgs              144 ( 1.6%)             3            48
+hir-stats Variant                  144 ( 1.6%)             2            72
 hir-stats GenericBound             192 ( 2.1%)             4            48
 hir-stats - Trait                    192 ( 2.1%)             4
 hir-stats WherePredicate           192 ( 2.1%)             3            64
@@ -148,27 +148,27 @@ hir-stats - BoundPredicate           192 ( 2.1%)             3
 hir-stats Block                    288 ( 3.2%)             6            48
 hir-stats GenericParam             360 ( 4.0%)             5            72
 hir-stats Pat                      360 ( 4.0%)             5            72
-hir-stats - Wild                      72 ( 0.8%)             1
 hir-stats - Struct                    72 ( 0.8%)             1
+hir-stats - Wild                      72 ( 0.8%)             1
 hir-stats - Binding                  216 ( 2.4%)             3
 hir-stats Generics                 560 ( 6.2%)            10            56
 hir-stats Ty                       720 ( 8.0%)            15            48
-hir-stats - Ptr                       48 ( 0.5%)             1
 hir-stats - Ref                       48 ( 0.5%)             1
+hir-stats - Ptr                       48 ( 0.5%)             1
 hir-stats - Path                     624 ( 7.0%)            13
 hir-stats Expr                     768 ( 8.6%)            12            64
 hir-stats - Path                      64 ( 0.7%)             1
-hir-stats - Struct                    64 ( 0.7%)             1
 hir-stats - Match                     64 ( 0.7%)             1
+hir-stats - Struct                    64 ( 0.7%)             1
 hir-stats - InlineAsm                 64 ( 0.7%)             1
 hir-stats - Lit                      128 ( 1.4%)             2
 hir-stats - Block                    384 ( 4.3%)             6
 hir-stats Item                     968 (10.8%)            11            88
-hir-stats - Trait                     88 ( 1.0%)             1
 hir-stats - Enum                      88 ( 1.0%)             1
+hir-stats - Trait                     88 ( 1.0%)             1
+hir-stats - Impl                      88 ( 1.0%)             1
 hir-stats - ExternCrate               88 ( 1.0%)             1
 hir-stats - ForeignMod                88 ( 1.0%)             1
-hir-stats - Impl                      88 ( 1.0%)             1
 hir-stats - Fn                       176 ( 2.0%)             2
 hir-stats - Use                      352 ( 3.9%)             4
 hir-stats Path                   1_240 (13.8%)            31            40
diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs
index f49ce33841a..1961f10bd0a 100644
--- a/tests/ui/structs-enums/type-sizes.rs
+++ b/tests/ui/structs-enums/type-sizes.rs
@@ -5,7 +5,6 @@
 #![allow(dead_code)]
 #![feature(never_type)]
 #![feature(pointer_is_aligned_to)]
-#![feature(strict_provenance)]
 
 use std::mem::size_of;
 use std::num::NonZero;
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
index 4399ae2d1be..4399ae2d1be 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr
index 8288c660ce7..8288c660ce7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs
index 8a1bf75f87e..8a1bf75f87e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
index 0792d090321..0792d090321 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/traits/const-traits/assoc-type.rs
index ea3cbabf302..ea3cbabf302 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs
+++ b/tests/ui/traits/const-traits/assoc-type.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/traits/const-traits/assoc-type.stderr
index c20b53c210f..c20b53c210f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr
+++ b/tests/ui/traits/const-traits/assoc-type.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/attr-misuse.rs b/tests/ui/traits/const-traits/attr-misuse.rs
index 01ac74feff7..01ac74feff7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/attr-misuse.rs
+++ b/tests/ui/traits/const-traits/attr-misuse.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/attr-misuse.stderr b/tests/ui/traits/const-traits/attr-misuse.stderr
index 998958cedf7..998958cedf7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/attr-misuse.stderr
+++ b/tests/ui/traits/const-traits/attr-misuse.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/traits/const-traits/auxiliary/cross-crate.rs
index 8f63cd1d521..8f63cd1d521 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
+++ b/tests/ui/traits/const-traits/auxiliary/cross-crate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/tests/ui/traits/const-traits/auxiliary/staged-api.rs
index 986165ef91e..986165ef91e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
+++ b/tests/ui/traits/const-traits/auxiliary/staged-api.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/tests/ui/traits/const-traits/call-const-trait-method-fail.rs
index 878f9a713a0..878f9a713a0 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
+++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr
index 5d2333d94fe..5d2333d94fe 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
+++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs
index b854b422b3a..b854b422b3a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs
+++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
index bf455a714a3..bf455a714a3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
+++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/tests/ui/traits/const-traits/call-generic-in-impl.rs
index 6b3a4ae1b95..6b3a4ae1b95 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.rs
+++ b/tests/ui/traits/const-traits/call-generic-in-impl.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr b/tests/ui/traits/const-traits/call-generic-in-impl.stderr
index 5cd274c6c5a..5cd274c6c5a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr
+++ b/tests/ui/traits/const-traits/call-generic-in-impl.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.rs b/tests/ui/traits/const-traits/call-generic-method-chain.rs
index 9df694a02f5..9df694a02f5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-chain.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/traits/const-traits/call-generic-method-chain.stderr
index 57d57dfd5b9..57d57dfd5b9 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-chain.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs
index f46a34911f1..f46a34911f1 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr
index 0088ed2eb13..0088ed2eb13 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs b/tests/ui/traits/const-traits/call-generic-method-fail.rs
index 86e0eae61c9..86e0eae61c9 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-fail.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst-bound.rs b/tests/ui/traits/const-traits/call-generic-method-nonconst-bound.rs
index 9dbc2b95626..9dbc2b95626 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst-bound.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst-bound.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/tests/ui/traits/const-traits/call-generic-method-nonconst.rs
index f9e79d41752..f9e79d41752 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
index 68c9fc40010..68c9fc40010 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.rs b/tests/ui/traits/const-traits/call-generic-method-pass.rs
index 413685d8b34..413685d8b34 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-pass.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/traits/const-traits/call-generic-method-pass.stderr
index 4a6100c3c1a..4a6100c3c1a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-pass.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs b/tests/ui/traits/const-traits/call.rs
index af2f7caf88c..af2f7caf88c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs
+++ b/tests/ui/traits/const-traits/call.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.rs b/tests/ui/traits/const-traits/const-and-non-const-impl.rs
index 6b96fcf0ae3..6b96fcf0ae3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.rs
+++ b/tests/ui/traits/const-traits/const-and-non-const-impl.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
index cf7af41cd4e..cf7af41cd4e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
+++ b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs
index 099cf0b00d3..099cf0b00d3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs
+++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr
index b5d9b1fff8a..b5d9b1fff8a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr
+++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs
index db446f8bc2e..db446f8bc2e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs
+++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr
index e1a85fc5414..e1a85fc5414 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr
+++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs
index a1710e65252..a1710e65252 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
+++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr
index 49cd1725c8c..49cd1725c8c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr
+++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.rs b/tests/ui/traits/const-traits/const-closure-parse-not-item.rs
index b1b0e68b90d..b1b0e68b90d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.rs
+++ b/tests/ui/traits/const-traits/const-closure-parse-not-item.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.stderr b/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr
index 12cc79f5961..12cc79f5961 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.stderr
+++ b/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs b/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs
index 8c6286426d3..8c6286426d3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs
+++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
index 507ceaae2ea..507ceaae2ea 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr
+++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.rs b/tests/ui/traits/const-traits/const-closure-trait-method.rs
index ebee4daefbe..ebee4daefbe 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.rs
+++ b/tests/ui/traits/const-traits/const-closure-trait-method.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr b/tests/ui/traits/const-traits/const-closure-trait-method.stderr
index 2a54cd5d7f6..2a54cd5d7f6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr
+++ b/tests/ui/traits/const-traits/const-closure-trait-method.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.rs b/tests/ui/traits/const-traits/const-closures.rs
index 98f8d039cd6..98f8d039cd6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.rs
+++ b/tests/ui/traits/const-traits/const-closures.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr b/tests/ui/traits/const-traits/const-closures.stderr
index a0f05325389..a0f05325389 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr
+++ b/tests/ui/traits/const-traits/const-closures.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/tests/ui/traits/const-traits/const-default-method-bodies.rs
index a0333153f85..a0333153f85 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
+++ b/tests/ui/traits/const-traits/const-default-method-bodies.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/traits/const-traits/const-default-method-bodies.stderr
index 0809d9c1e1d..0809d9c1e1d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
+++ b/tests/ui/traits/const-traits/const-default-method-bodies.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.rs b/tests/ui/traits/const-traits/const-drop-bound.rs
index b0790f86ef5..b0790f86ef5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.rs
+++ b/tests/ui/traits/const-traits/const-drop-bound.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr
index be197006f02..be197006f02 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.stderr
+++ b/tests/ui/traits/const-traits/const-drop-bound.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
index 7529af9293d..7529af9293d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/traits/const-traits/const-drop-fail-2.rs
index 7b57e0405af..7b57e0405af 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
index faf24c6d911..faf24c6d911 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
index 7529af9293d..7529af9293d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
index 3d400bf0158..3d400bf0158 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.rs b/tests/ui/traits/const-traits/const-drop-fail.rs
index 5a98c32e838..5a98c32e838 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.rs
+++ b/tests/ui/traits/const-traits/const-drop-fail.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
index fd0f6d02684..fd0f6d02684 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr
index dd3ea5d241d..dd3ea5d241d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop.precise.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs b/tests/ui/traits/const-traits/const-drop.rs
index 5bd81fb3ab6..5bd81fb3ab6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs
+++ b/tests/ui/traits/const-traits/const-drop.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr
index aa59e1c8dc4..aa59e1c8dc4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop.stock.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs
index b3087349e4d..b3087349e4d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs
+++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr b/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr
index 9eda9d98ec5..9eda9d98ec5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr
+++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-norecover.rs b/tests/ui/traits/const-traits/const-impl-norecover.rs
index bed4e9fd1e6..bed4e9fd1e6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-norecover.rs
+++ b/tests/ui/traits/const-traits/const-impl-norecover.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-norecover.stderr b/tests/ui/traits/const-traits/const-impl-norecover.stderr
index efa72463c5e..efa72463c5e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-norecover.stderr
+++ b/tests/ui/traits/const-traits/const-impl-norecover.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-recovery.rs b/tests/ui/traits/const-traits/const-impl-recovery.rs
index 837124db04e..837124db04e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-recovery.rs
+++ b/tests/ui/traits/const-traits/const-impl-recovery.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-recovery.stderr b/tests/ui/traits/const-traits/const-impl-recovery.stderr
index 7217fc85543..7217fc85543 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-recovery.stderr
+++ b/tests/ui/traits/const-traits/const-impl-recovery.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs
index bd6f476f879..bd6f476f879 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
+++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr
index 2a030369093..2a030369093 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
+++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs
index 51dfe29b829..51dfe29b829 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs
+++ b/tests/ui/traits/const-traits/const-impl-trait.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr
index 1040af7541c..1040af7541c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr
+++ b/tests/ui/traits/const-traits/const-impl-trait.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.rs b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs
index 691bce19dc2..691bce19dc2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.rs
+++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.stderr b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr
index bd29b4b860b..bd29b4b860b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds-trait-objects.stderr
+++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs b/tests/ui/traits/const-traits/const-trait-bounds.rs
index 3b4ba6a998f..3b4ba6a998f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs
+++ b/tests/ui/traits/const-traits/const-trait-bounds.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr b/tests/ui/traits/const-traits/const-trait-bounds.stderr
index 698b1b5b578..698b1b5b578 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr
+++ b/tests/ui/traits/const-traits/const-trait-bounds.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs
index a772d69c9e2..a772d69c9e2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr
index 3ccae5a83e6..3ccae5a83e6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs
index 5896091f8c4..5896091f8c4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr
index 777b3313da6..777b3313da6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
index cb649b1ec79..cb649b1ec79 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
index ad727fc36cd..ad727fc36cd 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs
index c032c76d38f..c032c76d38f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr
index addce8dcd6c..addce8dcd6c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs b/tests/ui/traits/const-traits/cross-crate-default-method-body-is-const.rs
index 9ee5254dbf8..9ee5254dbf8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs
+++ b/tests/ui/traits/const-traits/cross-crate-default-method-body-is-const.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr
index a34bae843c8..a34bae843c8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs b/tests/ui/traits/const-traits/cross-crate.rs
index cfcada9c828..cfcada9c828 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
+++ b/tests/ui/traits/const-traits/cross-crate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr
index b481bdc470c..b481bdc470c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
index 5c3e3b6ff40..5c3e3b6ff40 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs
index b534d23b107..b534d23b107 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs
index 0c2d93775a4..0c2d93775a4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr
index d0f22c0b9b6..d0f22c0b9b6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-with-staged-api.rs b/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs
index 8b264ebd0e4..8b264ebd0e4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-with-staged-api.rs
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/traits/const-traits/do-not-const-check-override.rs
index 71e6375283f..71e6375283f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
+++ b/tests/ui/traits/const-traits/do-not-const-check-override.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check.rs b/tests/ui/traits/const-traits/do-not-const-check.rs
index 443b6385735..443b6385735 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check.rs
+++ b/tests/ui/traits/const-traits/do-not-const-check.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs b/tests/ui/traits/const-traits/effects/auxiliary/cross-crate.rs
index 779527e22d4..779527e22d4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs
+++ b/tests/ui/traits/const-traits/effects/auxiliary/cross-crate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/traits/const-traits/effects/const_closure-const_trait_impl-ice-113381.rs
index 3debc22098a..3debc22098a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs
+++ b/tests/ui/traits/const-traits/effects/const_closure-const_trait_impl-ice-113381.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs b/tests/ui/traits/const-traits/effects/effect-param-infer.rs
index 958b9ac6d57..958b9ac6d57 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs
+++ b/tests/ui/traits/const-traits/effects/effect-param-infer.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs b/tests/ui/traits/const-traits/effects/fallback.rs
index 4cfba00526b..4cfba00526b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs
+++ b/tests/ui/traits/const-traits/effects/fallback.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs b/tests/ui/traits/const-traits/effects/group-traits.rs
index 2c5b6cc40e6..2c5b6cc40e6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs
+++ b/tests/ui/traits/const-traits/effects/group-traits.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/traits/const-traits/effects/helloworld.rs
index 54f362b4413..54f362b4413 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
+++ b/tests/ui/traits/const-traits/effects/helloworld.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.rs b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs
index 9a9016de3a0..9a9016de3a0 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.rs
+++ b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr
index 526746eec73..526746eec73 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr
+++ b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs b/tests/ui/traits/const-traits/effects/ice-113375-index-out-of-bounds-generics.rs
index 06e3377c5ee..06e3377c5ee 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs
+++ b/tests/ui/traits/const-traits/effects/ice-113375-index-out-of-bounds-generics.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs b/tests/ui/traits/const-traits/effects/infer-fallback.rs
index 581c3949d38..581c3949d38 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs
+++ b/tests/ui/traits/const-traits/effects/infer-fallback.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/traits/const-traits/effects/minicore.rs
index 1c3c66bc3ce..1c3c66bc3ce 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs
+++ b/tests/ui/traits/const-traits/effects/minicore.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/traits/const-traits/effects/minicore.stderr
index 823ab69df9c..823ab69df9c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr
+++ b/tests/ui/traits/const-traits/effects/minicore.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/mismatched_generic_args.rs b/tests/ui/traits/const-traits/effects/mismatched_generic_args.rs
index 21e91c731b3..21e91c731b3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/mismatched_generic_args.rs
+++ b/tests/ui/traits/const-traits/effects/mismatched_generic_args.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/mismatched_generic_args.stderr b/tests/ui/traits/const-traits/effects/mismatched_generic_args.stderr
index 8e12b40381f..8e12b40381f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/mismatched_generic_args.stderr
+++ b/tests/ui/traits/const-traits/effects/mismatched_generic_args.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.rs b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.rs
index 97052a1d09a..97052a1d09a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.rs
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr
index 8c591edac54..8c591edac54 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs b/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs
index 84f5f2803e1..84f5f2803e1 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr b/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr
index cc08114ddb5..cc08114ddb5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs b/tests/ui/traits/const-traits/effects/project.rs
index 9f6ca1f294f..9f6ca1f294f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs
+++ b/tests/ui/traits/const-traits/effects/project.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs b/tests/ui/traits/const-traits/effects/span-bug-issue-121418.rs
index e6e41c472bd..e6e41c472bd 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs
+++ b/tests/ui/traits/const-traits/effects/span-bug-issue-121418.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr b/tests/ui/traits/const-traits/effects/span-bug-issue-121418.stderr
index 5ff1c6c5b9f..5ff1c6c5b9f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr
+++ b/tests/ui/traits/const-traits/effects/span-bug-issue-121418.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs
index 0508b1c5e26..0508b1c5e26 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs
+++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr
index e97a9615ae1..e97a9615ae1 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr
+++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.rs b/tests/ui/traits/const-traits/effects/trait-fn-const.rs
index d63dbfbf57d..d63dbfbf57d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.rs
+++ b/tests/ui/traits/const-traits/effects/trait-fn-const.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr b/tests/ui/traits/const-traits/effects/trait-fn-const.stderr
index 15cb84026e4..15cb84026e4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr
+++ b/tests/ui/traits/const-traits/effects/trait-fn-const.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr b/tests/ui/traits/const-traits/effects/with-without-next-solver.coherence.stderr
index 20448f51de2..20448f51de2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr
+++ b/tests/ui/traits/const-traits/effects/with-without-next-solver.coherence.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs b/tests/ui/traits/const-traits/effects/with-without-next-solver.rs
index f022af05c50..f022af05c50 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs
+++ b/tests/ui/traits/const-traits/effects/with-without-next-solver.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr b/tests/ui/traits/const-traits/effects/with-without-next-solver.stock.stderr
index 20448f51de2..20448f51de2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr
+++ b/tests/ui/traits/const-traits/effects/with-without-next-solver.stock.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.gated.stderr b/tests/ui/traits/const-traits/feature-gate.gated.stderr
index 12f9355e41d..12f9355e41d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.gated.stderr
+++ b/tests/ui/traits/const-traits/feature-gate.gated.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.rs b/tests/ui/traits/const-traits/feature-gate.rs
index c36ec3538c3..c36ec3538c3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.rs
+++ b/tests/ui/traits/const-traits/feature-gate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.stock.stderr b/tests/ui/traits/const-traits/feature-gate.stock.stderr
index 78157d57056..78157d57056 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/feature-gate.stock.stderr
+++ b/tests/ui/traits/const-traits/feature-gate.stock.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/function-pointer-does-not-require-const.rs b/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs
index 61826e9977e..61826e9977e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/function-pointer-does-not-require-const.rs
+++ b/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/gate.rs b/tests/ui/traits/const-traits/gate.rs
index d1c93ab9f95..d1c93ab9f95 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/gate.rs
+++ b/tests/ui/traits/const-traits/gate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/gate.stderr b/tests/ui/traits/const-traits/gate.stderr
index 19fd54ff369..19fd54ff369 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/gate.stderr
+++ b/tests/ui/traits/const-traits/gate.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.rs b/tests/ui/traits/const-traits/generic-bound.rs
index 620e3259917..620e3259917 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.rs
+++ b/tests/ui/traits/const-traits/generic-bound.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/traits/const-traits/generic-bound.stderr
index 2baac1d2a16..2baac1d2a16 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
+++ b/tests/ui/traits/const-traits/generic-bound.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs b/tests/ui/traits/const-traits/hir-const-check.rs
index f5fb0fd516a..f5fb0fd516a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
+++ b/tests/ui/traits/const-traits/hir-const-check.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr b/tests/ui/traits/const-traits/hir-const-check.stderr
index 598129d8694..598129d8694 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr
+++ b/tests/ui/traits/const-traits/hir-const-check.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs
index c2f452a9925..c2f452a9925 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs
+++ b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr
index 50cdded8d51..50cdded8d51 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr
+++ b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.rs b/tests/ui/traits/const-traits/ice-120503-async-const-method.rs
index 9cd18d4566d..9cd18d4566d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.rs
+++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr
index 90771c344b5..90771c344b5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr
+++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.rs b/tests/ui/traits/const-traits/ice-121536-const-method.rs
index a01329278d7..a01329278d7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.rs
+++ b/tests/ui/traits/const-traits/ice-121536-const-method.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr b/tests/ui/traits/const-traits/ice-121536-const-method.stderr
index 29187654c3c..29187654c3c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr
+++ b/tests/ui/traits/const-traits/ice-121536-const-method.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs
index 64634e7b7ac..64634e7b7ac 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs
+++ b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr
index c937430a1ca..c937430a1ca 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr
+++ b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs
index d4fcbfb1b83..d4fcbfb1b83 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs
+++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr
index 284757c1a89..284757c1a89 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr
+++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs
index 717c0e7c088..717c0e7c088 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs
+++ b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr
index e49436c8f0f..e49436c8f0f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr
+++ b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-tilde-const-trait.rs b/tests/ui/traits/const-traits/impl-tilde-const-trait.rs
index 05b26465c5b..05b26465c5b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-tilde-const-trait.rs
+++ b/tests/ui/traits/const-traits/impl-tilde-const-trait.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-tilde-const-trait.stderr b/tests/ui/traits/const-traits/impl-tilde-const-trait.stderr
index 4695728f8ca..4695728f8ca 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-tilde-const-trait.stderr
+++ b/tests/ui/traits/const-traits/impl-tilde-const-trait.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs b/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs
index 49741ca24c7..49741ca24c7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs
+++ b/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr b/tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr
index 2ea203627f4..2ea203627f4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr
+++ b/tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs b/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs
index 2c375036941..2c375036941 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs
+++ b/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs b/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs
index 5ead1353bcd..5ead1353bcd 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs
+++ b/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl.rs b/tests/ui/traits/const-traits/inherent-impl.rs
index afd0d137bb4..afd0d137bb4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl.rs
+++ b/tests/ui/traits/const-traits/inherent-impl.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl.stderr b/tests/ui/traits/const-traits/inherent-impl.stderr
index 8c55627031d..8c55627031d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/inherent-impl.stderr
+++ b/tests/ui/traits/const-traits/inherent-impl.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.rs b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.rs
index e3adcce17b4..e3adcce17b4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.rs
+++ b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.stderr b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr
index 2e7801c0b8a..2e7801c0b8a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.stderr
+++ b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs b/tests/ui/traits/const-traits/issue-100222.rs
index 13c469d656c..13c469d656c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs
+++ b/tests/ui/traits/const-traits/issue-100222.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.rs b/tests/ui/traits/const-traits/issue-102156.rs
index fe4e9108130..fe4e9108130 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.rs
+++ b/tests/ui/traits/const-traits/issue-102156.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr b/tests/ui/traits/const-traits/issue-102156.stderr
index 0c836a614f8..0c836a614f8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr
+++ b/tests/ui/traits/const-traits/issue-102156.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.rs b/tests/ui/traits/const-traits/issue-102985.rs
index e5394ddd688..e5394ddd688 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.rs
+++ b/tests/ui/traits/const-traits/issue-102985.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr b/tests/ui/traits/const-traits/issue-102985.stderr
index 8401d1bd4f6..8401d1bd4f6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr
+++ b/tests/ui/traits/const-traits/issue-102985.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-103677.rs b/tests/ui/traits/const-traits/issue-103677.rs
index c032cc7a688..c032cc7a688 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-103677.rs
+++ b/tests/ui/traits/const-traits/issue-103677.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs b/tests/ui/traits/const-traits/issue-79450.rs
index b8b9e07b3bd..b8b9e07b3bd 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs
+++ b/tests/ui/traits/const-traits/issue-79450.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr b/tests/ui/traits/const-traits/issue-79450.stderr
index 9e6348d37ed..9e6348d37ed 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr
+++ b/tests/ui/traits/const-traits/issue-79450.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.rs b/tests/ui/traits/const-traits/issue-88155.rs
index 08739de8313..08739de8313 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.rs
+++ b/tests/ui/traits/const-traits/issue-88155.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.stderr b/tests/ui/traits/const-traits/issue-88155.stderr
index afe1ea3b1b7..afe1ea3b1b7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.stderr
+++ b/tests/ui/traits/const-traits/issue-88155.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.rs b/tests/ui/traits/const-traits/issue-92111.rs
index 64fa32156c3..64fa32156c3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.rs
+++ b/tests/ui/traits/const-traits/issue-92111.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr b/tests/ui/traits/const-traits/issue-92111.stderr
index ecc994a3fe6..ecc994a3fe6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr
+++ b/tests/ui/traits/const-traits/issue-92111.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs b/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs
index e666355db6f..e666355db6f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs
+++ b/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr b/tests/ui/traits/const-traits/match-non-const-eq.gated.stderr
index c7d21151661..c7d21151661 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr
+++ b/tests/ui/traits/const-traits/match-non-const-eq.gated.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs b/tests/ui/traits/const-traits/match-non-const-eq.rs
index 73f8af86bd0..73f8af86bd0 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs
+++ b/tests/ui/traits/const-traits/match-non-const-eq.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr b/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr
index 0f5ecac3891..0f5ecac3891 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr
+++ b/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-bare-trait-objects-const-trait-bounds.rs b/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs
index 820d3d63b62..820d3d63b62 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-bare-trait-objects-const-trait-bounds.rs
+++ b/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs
index 3dcdb0cad94..3dcdb0cad94 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs
+++ b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr
index f4b401b7386..f4b401b7386 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr
+++ b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs b/tests/ui/traits/const-traits/mbe-dyn-const-2015.rs
index 9d65a2ac302..9d65a2ac302 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs
+++ b/tests/ui/traits/const-traits/mbe-dyn-const-2015.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.rs b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs
index aaab8e819a3..aaab8e819a3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.rs
+++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.stderr b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr
index 18e4d160f5f..18e4d160f5f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/mutually-exclusive-trait-bound-modifiers.stderr
+++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs b/tests/ui/traits/const-traits/nested-closure.rs
index 7bd372c1695..7bd372c1695 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs
+++ b/tests/ui/traits/const-traits/nested-closure.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.rs b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs
index cd8bb5963ad..cd8bb5963ad 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.rs
+++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr
index c362a1077e3..c362a1077e3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.stderr
+++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs
index 8f11c8a6e55..8f11c8a6e55 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs
+++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr
index de4783bdb3f..de4783bdb3f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr
+++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs
index 69dcb403aa9..69dcb403aa9 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
+++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr
index 7643697874f..7643697874f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
+++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs
index a48a50b9e5c..a48a50b9e5c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
+++ b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr
index 9b2ae8d739c..9b2ae8d739c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr
+++ b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs
index 40fc3b17ae4..40fc3b17ae4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
+++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr
index c51d169dd33..c51d169dd33 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr
+++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/tests/ui/traits/const-traits/specialization/default-keyword.rs
index d9ffd237dce..d9ffd237dce 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs
+++ b/tests/ui/traits/const-traits/specialization/default-keyword.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr b/tests/ui/traits/const-traits/specialization/default-keyword.stderr
index 18a25045f4b..18a25045f4b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr
+++ b/tests/ui/traits/const-traits/specialization/default-keyword.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs
index 219e5f3a600..219e5f3a600 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
+++ b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr
index ecdc7b930e6..ecdc7b930e6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr
+++ b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs
index 7514baa2fd5..7514baa2fd5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
+++ b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr
index 6679bb46537..6679bb46537 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr
+++ b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs
index 912b35095f9..912b35095f9 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
+++ b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr
index 7f363922947..7f363922947 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
+++ b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs b/tests/ui/traits/const-traits/specializing-constness-2.rs
index c1fe42b9751..c1fe42b9751 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs
+++ b/tests/ui/traits/const-traits/specializing-constness-2.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr
index bf273f349b4..bf273f349b4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr
+++ b/tests/ui/traits/const-traits/specializing-constness-2.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/traits/const-traits/specializing-constness.rs
index 4501a218ad7..4501a218ad7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
+++ b/tests/ui/traits/const-traits/specializing-constness.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/traits/const-traits/specializing-constness.stderr
index 90721af8e5a..90721af8e5a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr
+++ b/tests/ui/traits/const-traits/specializing-constness.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api-user-crate.rs b/tests/ui/traits/const-traits/staged-api-user-crate.rs
index c4ecb8f67a1..c4ecb8f67a1 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api-user-crate.rs
+++ b/tests/ui/traits/const-traits/staged-api-user-crate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api-user-crate.stderr b/tests/ui/traits/const-traits/staged-api-user-crate.stderr
index 781191ec97c..781191ec97c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api-user-crate.stderr
+++ b/tests/ui/traits/const-traits/staged-api-user-crate.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/traits/const-traits/staged-api.rs
index f87e723472a..f87e723472a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
+++ b/tests/ui/traits/const-traits/staged-api.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr b/tests/ui/traits/const-traits/staged-api.stable.stderr
index 6c07a253f5b..6c07a253f5b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr
+++ b/tests/ui/traits/const-traits/staged-api.stable.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr b/tests/ui/traits/const-traits/staged-api.unstable.stderr
index 1c772f13dd5..1c772f13dd5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr
+++ b/tests/ui/traits/const-traits/staged-api.unstable.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/static-const-trait-bound.rs b/tests/ui/traits/const-traits/static-const-trait-bound.rs
index 062067f8e85..062067f8e85 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/static-const-trait-bound.rs
+++ b/tests/ui/traits/const-traits/static-const-trait-bound.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr b/tests/ui/traits/const-traits/std-impl-gate.gated.stderr
index d761fdce4bf..d761fdce4bf 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr
+++ b/tests/ui/traits/const-traits/std-impl-gate.gated.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.rs b/tests/ui/traits/const-traits/std-impl-gate.rs
index a9e2ff06290..a9e2ff06290 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.rs
+++ b/tests/ui/traits/const-traits/std-impl-gate.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.stock.stderr b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr
index b63ea695fc2..b63ea695fc2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.stock.stderr
+++ b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr
index 48bb1907be2..48bb1907be2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr
index 029c3b4bde3..029c3b4bde3 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/traits/const-traits/super-traits-fail-2.rs
index 93a6f385e47..93a6f385e47 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr
index 873c57ec71f..873c57ec71f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr
index bea3aea2f3a..bea3aea2f3a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr
index f40583f0ca5..f40583f0ca5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr
index 3f6dfa7b008..3f6dfa7b008 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/traits/const-traits/super-traits-fail-3.rs
index b5643b11700..b5643b11700 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr
index bbc95948a59..bbc95948a59 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/traits/const-traits/super-traits-fail.rs
index da41d7fcc72..da41d7fcc72 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs
+++ b/tests/ui/traits/const-traits/super-traits-fail.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr b/tests/ui/traits/const-traits/super-traits-fail.stderr
index 3870f0f722f..3870f0f722f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs b/tests/ui/traits/const-traits/super-traits.rs
index ff7349bba3c..ff7349bba3c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs
+++ b/tests/ui/traits/const-traits/super-traits.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/syntax.rs b/tests/ui/traits/const-traits/syntax.rs
index 1064713ac59..1064713ac59 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/syntax.rs
+++ b/tests/ui/traits/const-traits/syntax.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs b/tests/ui/traits/const-traits/tilde-const-and-const-params.rs
index 4b720b534a4..4b720b534a4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs
+++ b/tests/ui/traits/const-traits/tilde-const-and-const-params.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr
index 73526a26e08..73526a26e08 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
+++ b/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs b/tests/ui/traits/const-traits/tilde-const-assoc-fn-in-trait-impl.rs
index 8e7202ecaa1..8e7202ecaa1 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs
+++ b/tests/ui/traits/const-traits/tilde-const-assoc-fn-in-trait-impl.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs b/tests/ui/traits/const-traits/tilde-const-inherent-assoc-const-fn.rs
index 71c5d8366b2..71c5d8366b2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs
+++ b/tests/ui/traits/const-traits/tilde-const-inherent-assoc-const-fn.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/tests/ui/traits/const-traits/tilde-const-invalid-places.rs
index 9d220686771..9d220686771 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs
+++ b/tests/ui/traits/const-traits/tilde-const-invalid-places.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr
index 8151b9aaa23..8151b9aaa23 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
+++ b/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-syntax.rs b/tests/ui/traits/const-traits/tilde-const-syntax.rs
index d65ecae3d06..d65ecae3d06 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-syntax.rs
+++ b/tests/ui/traits/const-traits/tilde-const-syntax.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs b/tests/ui/traits/const-traits/tilde-const-trait-assoc-tys.rs
index 254cf2200d8..254cf2200d8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs
+++ b/tests/ui/traits/const-traits/tilde-const-trait-assoc-tys.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-twice.rs b/tests/ui/traits/const-traits/tilde-twice.rs
index c3f9f8e6764..c3f9f8e6764 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-twice.rs
+++ b/tests/ui/traits/const-traits/tilde-twice.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-twice.stderr b/tests/ui/traits/const-traits/tilde-twice.stderr
index a809736a4f8..a809736a4f8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-twice.stderr
+++ b/tests/ui/traits/const-traits/tilde-twice.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs b/tests/ui/traits/const-traits/trait-default-body-stability.rs
index b36e9535ca1..b36e9535ca1 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs
+++ b/tests/ui/traits/const-traits/trait-default-body-stability.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/traits/const-traits/trait-default-body-stability.stderr
index 49fbef9aaa2..49fbef9aaa2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
+++ b/tests/ui/traits/const-traits/trait-default-body-stability.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs b/tests/ui/traits/const-traits/trait-method-ptr-in-consts-ice.rs
index 8a901cc60fd..8a901cc60fd 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs
+++ b/tests/ui/traits/const-traits/trait-method-ptr-in-consts-ice.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/traits/const-traits/trait-where-clause-const.rs
index 8ca9b7cc7aa..8ca9b7cc7aa 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs
+++ b/tests/ui/traits/const-traits/trait-where-clause-const.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
index eaa981ec744..eaa981ec744 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
+++ b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/traits/const-traits/trait-where-clause-run.rs
index 2837c835429..2837c835429 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
+++ b/tests/ui/traits/const-traits/trait-where-clause-run.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs b/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs
index cb5cc924bfd..cb5cc924bfd 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
+++ b/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs b/tests/ui/traits/const-traits/trait-where-clause.rs
index 11f353f3f8a..11f353f3f8a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs
+++ b/tests/ui/traits/const-traits/trait-where-clause.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr b/tests/ui/traits/const-traits/trait-where-clause.stderr
index abe24b662a2..abe24b662a2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/tests/ui/traits/const-traits/trait-where-clause.stderr
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs
index d336719f52e..d336719f52e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs
+++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
index 848aa68689b..848aa68689b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr
+++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
diff --git a/tests/ui/traits/fully-qualified-syntax-cast.rs b/tests/ui/traits/fully-qualified-syntax-cast.rs
new file mode 100644
index 00000000000..740220a074b
--- /dev/null
+++ b/tests/ui/traits/fully-qualified-syntax-cast.rs
@@ -0,0 +1,15 @@
+// Regression test for #98565: Provide diagnostics when the user uses
+// the built-in type `str` in a cast where a trait is expected.
+
+trait Foo {
+    fn foo(&self);
+}
+
+impl Foo for String {
+    fn foo(&self) {
+        <Self as str>::trim(self);
+        //~^ ERROR expected trait, found builtin type `str`
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/fully-qualified-syntax-cast.stderr b/tests/ui/traits/fully-qualified-syntax-cast.stderr
new file mode 100644
index 00000000000..1848c9184c6
--- /dev/null
+++ b/tests/ui/traits/fully-qualified-syntax-cast.stderr
@@ -0,0 +1,9 @@
+error[E0404]: expected trait, found builtin type `str`
+  --> $DIR/fully-qualified-syntax-cast.rs:10:18
+   |
+LL |         <Self as str>::trim(self);
+   |                  ^^^ not a trait
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0404`.
diff --git a/tests/ui/traits/next-solver/canonical/do-not-bail-due-to-placeholders.rs b/tests/ui/traits/next-solver/canonical/do-not-bail-due-to-placeholders.rs
new file mode 100644
index 00000000000..3fc11f27d1f
--- /dev/null
+++ b/tests/ui/traits/next-solver/canonical/do-not-bail-due-to-placeholders.rs
@@ -0,0 +1,16 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// When canonicalizing responses, we bail if there are too many inference variables.
+// We previously also counted placeholders, which is incorrect.
+#![recursion_limit = "8"]
+
+fn foo<T>() {}
+
+fn bar<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>() {
+    // The query response will contain 10 placeholders, which previously
+    // caused us to bail here.
+    foo::<(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/normalize/normalize-allow-too-many-vars.rs b/tests/ui/traits/next-solver/normalize/normalize-allow-too-many-vars.rs
new file mode 100644
index 00000000000..5284220ac38
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize/normalize-allow-too-many-vars.rs
@@ -0,0 +1,52 @@
+//@ check-pass
+
+// When canonicalizing a response in the trait solver, we bail with overflow
+// if there are too many non-region inference variables. Doing so in normalizes-to
+// goals ends up hiding inference constraints in cases which we want to support,
+// see #131969. To prevent this issue we do not check for too many inference
+// variables in normalizes-to goals.
+#![recursion_limit = "8"]
+
+trait Bound {}
+trait Trait {
+    type Assoc;
+}
+
+
+impl<T0, T1, T2, T3, T4, T5, T6, T7> Trait for (T0, T1, T2, T3, T4, T5, T6, T7)
+where
+    T0: Trait,
+    T1: Trait,
+    T2: Trait,
+    T3: Trait,
+    T4: Trait,
+    T5: Trait,
+    T6: Trait,
+    T7: Trait,
+    (
+        T0::Assoc,
+        T1::Assoc,
+        T2::Assoc,
+        T3::Assoc,
+        T4::Assoc,
+        T5::Assoc,
+        T6::Assoc,
+        T7::Assoc,
+    ): Clone,
+{
+    type Assoc = (
+        T0::Assoc,
+        T1::Assoc,
+        T2::Assoc,
+        T3::Assoc,
+        T4::Assoc,
+        T5::Assoc,
+        T6::Assoc,
+        T7::Assoc,
+    );
+}
+
+trait Overlap {}
+impl<T: Trait<Assoc = ()>> Overlap for T {}
+impl<T0, T1, T2, T3, T4, T5, T6, T7> Overlap for (T0, T1, T2, T3, T4, T5, T6, T7) {}
+fn main() {}
diff --git a/tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs b/tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs
index 0d5f42231e4..f88f74680b9 100644
--- a/tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs
+++ b/tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs
@@ -1,8 +1,5 @@
 //@ check-pass
-//@ revisions: ai_current ai_next ia_current ia_next ii_current ii_next
-//@[ai_next] compile-flags: -Znext-solver
-//@[ia_next] compile-flags: -Znext-solver
-//@[ii_next] compile-flags: -Znext-solver
+//@ revisions: ai ia ii
 
 // Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
 
@@ -17,11 +14,11 @@ trait Trait {
     type Assoc: ?Sized;
 }
 impl<T: ?Sized + Trait> Trait for W<T, T> {
-    #[cfg(any(ai_current, ai_next))]
+    #[cfg(ai)]
     type Assoc = W<T::Assoc, Id<T::Assoc>>;
-    #[cfg(any(ia_current, ia_next))]
+    #[cfg(ia)]
     type Assoc = W<Id<T::Assoc>, T::Assoc>;
-    #[cfg(any(ii_current, ii_next))]
+    #[cfg(ii)]
     type Assoc = W<Id<T::Assoc>, Id<T::Assoc>>;
 }
 
diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
index 86d428cc0f0..dd8ad3c2dfe 100644
--- a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
+++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
@@ -1,8 +1,8 @@
-//~ ERROR overflow evaluating the requirement `Self: Trait`
-//~^ ERROR overflow evaluating the requirement `Self well-formed`
-// This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
+//@ check-pass
 //@ compile-flags: -Znext-solver --crate-type=lib
 
+// This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
+
 #![recursion_limit = "0"]
 trait Trait {}
 impl Trait for u32 {}
diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
deleted file mode 100644
index 2eed7e8f723..00000000000
--- a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0275]: overflow evaluating the requirement `Self: Trait`
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
-
-error[E0275]: overflow evaluating the requirement `Self well-formed`
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs
new file mode 100644
index 00000000000..eeb0777c856
--- /dev/null
+++ b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs
@@ -0,0 +1,19 @@
+#![feature(transmutability)]
+#![feature(generic_const_exprs)]
+//~^ WARN the feature `generic_const_exprs` is incomplete
+
+use std::mem::{Assume, TransmuteFrom};
+
+pub fn is_transmutable<const ASSUME_ALIGNMENT: bool>()
+where
+    (): TransmuteFrom<(), { Assume::SAFETY }>,
+{
+}
+
+fn foo<const N: usize>() {
+    is_transmutable::<{}>();
+    //~^ ERROR  the trait bound `(): TransmuteFrom<(), { Assume::SAFETY }>` is not satisfied
+    //~| ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr
new file mode 100644
index 00000000000..6cb6a85c78a
--- /dev/null
+++ b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr
@@ -0,0 +1,34 @@
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/dont-assume-err-is-yes-issue-126377.rs:2:12
+   |
+LL | #![feature(generic_const_exprs)]
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+  --> $DIR/dont-assume-err-is-yes-issue-126377.rs:14:23
+   |
+LL |     is_transmutable::<{}>();
+   |                       ^^ expected `bool`, found `()`
+
+error[E0277]: the trait bound `(): TransmuteFrom<(), { Assume::SAFETY }>` is not satisfied
+  --> $DIR/dont-assume-err-is-yes-issue-126377.rs:14:23
+   |
+LL |     is_transmutable::<{}>();
+   |                       ^^ the trait `TransmuteFrom<(), { Assume::SAFETY }>` is not implemented for `()`
+   |
+note: required by a bound in `is_transmutable`
+  --> $DIR/dont-assume-err-is-yes-issue-126377.rs:9:9
+   |
+LL | pub fn is_transmutable<const ASSUME_ALIGNMENT: bool>()
+   |        --------------- required by a bound in this function
+LL | where
+LL |     (): TransmuteFrom<(), { Assume::SAFETY }>,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/triagebot.toml b/triagebot.toml
index 33dcbfa55a4..17ce4cf32a2 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -679,6 +679,15 @@ instead.
 """
 cc = ["@calebzulawski", "@programmerjake"]
 
+[mentions."library/core/src/unicode/unicode_data.rs"]
+message = """
+`library/core/src/unicode/unicode_data.rs` is generated by
+`src/tools/unicode-table-generator` via `./x run
+src/tools/unicode-table-generator`. If you want to modify `unicode_data.rs`,
+please modify the tool then regenerate the library source file with the tool
+instead of editing the library source file manually.
+"""
+
 [mentions."src/librustdoc/clean/types.rs"]
 cc = ["@camelid"]
 
@@ -1072,7 +1081,7 @@ project-const-traits = [
 project-stable-mir = [
     "@celinval",
     "@oli-obk",
-    "@ouz-a",
+    "@scottmcm",
 ]
 
 project-exploit-mitigations = [